"""Arcade Starter Tools for Mailchimp_Marketing

DO NOT EDIT THIS MODULE DIRECTLY.

THIS MODULE WAS AUTO-GENERATED BY TRANSPILING THE API STARTER TOOL JSON DEFINITIONS
IN THE ../wrapper_tools DIRECTORY INTO PYTHON CODE. ANY CHANGES TO THIS MODULE WILL
BE OVERWRITTEN BY THE TRANSPILER.
"""
import asyncio
import json
import jsonschema
from enum import Enum
from typing import Annotated, Any

import httpx

from arcade_tdk import tool, ToolContext
from arcade_tdk.errors import RetryableToolError
from arcade_tdk.auth import OAuth2

from .request_body_schemas import REQUEST_BODY_SCHEMAS
from . import utils

# Retry configuration
INITIAL_RETRY_DELAY = 0.5  # seconds

HTTP_CLIENT = httpx.AsyncClient(
    timeout=httpx.Timeout(60.0, connect=10.0),
    limits=httpx.Limits(max_keepalive_connections=20, max_connections=100),
    transport=httpx.AsyncHTTPTransport(retries=3),
    http2=True,
    follow_redirects=True,
)

class ToolMode(str, Enum):
    """Mode for tools with complex request bodies."""
    GET_REQUEST_SCHEMA = "get_request_schema"
    EXECUTE = "execute"



def remove_none_values(data: dict[str, Any]) -> dict[str, Any]:
    return {k: v for k, v in data.items() if v is not None}


async def make_request(
    url: str,
    method: str,
    params: dict[str, Any] | None = None,
    headers: dict[str, Any] | None = None,
    content: str | None = None,
    data: dict[str, Any] | None = None,
    auth: tuple[str, str] | None = None,
    max_retries: int = 3,
) -> httpx.Response:
    """Make an HTTP request with retry logic for 5xx server errors."""
    for attempt in range(max_retries):
        try:
            response = await HTTP_CLIENT.request(
                url=url,
                auth=auth,
                method=method,
                params=params,
                headers=headers,
                content=content,
            )
            response.raise_for_status()
        except httpx.HTTPStatusError as e:
            # Only retry on 5xx server errors
            if e.response.status_code >= 500 and attempt < max_retries - 1:
                # Exponential backoff: 0.5s, 1s, 2s
                await asyncio.sleep(INITIAL_RETRY_DELAY * (2 ** attempt))
                continue
            # Re-raise for 4xx errors or if max retries reached
            raise
        except httpx.RequestError as e:
            # Don't retry request errors (network issues are handled by transport)
            raise
        else:
            return response

    # This should never be reached, but satisfies type checker
    raise httpx.RequestError("Max retries exceeded")  # noqa: TRY003


async def make_request_with_schema_validation(
    url: str,
    method: str,
    request_data: dict[str, Any],
    schema: dict[str, Any] | str,
    auth: tuple[str, str] | None = None,
    params: dict[str, Any] | None = None,
    headers: dict[str, Any] | None = None,
    max_retries: int = 3,
) -> httpx.Response:
    """Make an HTTP request with schema validation on format errors."""
    # Parse schema if it's a string, skip validation if parsing fails
    parsed_schema = None
    if isinstance(schema, str):
        try:
            parsed_schema = json.loads(schema)
        except Exception:
            # If schema parsing fails, just skip validation
            parsed_schema = None
    else:
        parsed_schema = schema

    try:
        response = await make_request(
            url=url,
            auth=auth,
            method=method,
            params=params,
            headers=headers,
            content=json.dumps(request_data),
            max_retries=max_retries,
        )
    except httpx.HTTPStatusError as e:
        # Only provide schema validation for format-related errors
        if e.response.status_code in (400, 422):
            api_error_details = (
                f"API returned {e.response.status_code}: {e.response.text}"
            )

            # Only run validation if we have a valid parsed schema
            if parsed_schema is not None:
                # Run validation to provide additional context
                is_valid, validation_error = validate_json_against_schema(
                    request_data, parsed_schema
                )

                if not is_valid:
                    # Schema validation found issues - additional context
                    additional_context = (
                        f"{api_error_details}\n\n"
                        f"Schema validation found the following issues:\n"
                        f"{validation_error}"
                    )
                else:
                    # Schema validation passed - just show API error
                    additional_context = api_error_details
            else:
                # No valid schema - just show API error
                additional_context = api_error_details

            raise RetryableToolError(
                message=(
                    f"API request failed with validation error: "
                    f"{e.response.status_code}"
                ),
                developer_message=api_error_details,
                additional_prompt_content=additional_context,
            ) from e
        else:
            # For non-validation errors, re-raise as-is
            raise
    else:
        return response


def validate_json_against_schema(
    json_data: dict[str, Any], schema: dict[str, Any]
) -> tuple[bool, str | None]:
    """Validate JSON data against an OpenAPI/JSON Schema.

    This provides full JSON Schema Draft 7 validation including:
    - Required fields, types, enums
    - Pattern validation (regex)
    - Format validation (email, uuid, date-time, etc.)
    - Min/max length and values
    - oneOf, anyOf, allOf
    - And all other JSON Schema features

    Args:
        json_data: The JSON data to validate
        schema: The JSON Schema to validate against

    Returns:
        Tuple of (is_valid, error_messages). If valid, error_messages is None.
        If invalid, error_messages contains all validation errors.
    """
    try:
        validator = jsonschema.Draft7Validator(
            schema, format_checker=jsonschema.Draft7Validator.FORMAT_CHECKER
        )
        # Collect ALL validation errors
        errors = list(validator.iter_errors(json_data))
        if errors:
            # Format all errors with their paths
            error_messages = []
            for error in errors:
                error_path = (
                    ".".join(str(p) for p in error.path)
                    if error.path
                    else "root"
                )
                error_messages.append(f"{error.message} at {error_path}")
            # Join all errors with newlines
            return False, "\n".join(error_messages)
        else:
            return True, None
    except jsonschema.SchemaError as e:
        return False, f"Invalid schema: {e.message}"
    except Exception as e:
        return False, f"Validation error: {e!s}"

@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_mailchimp_api_resources(
    context: ToolContext,
    exclude_fields: Annotated[str | None, "A comma-separated list of fields to exclude using dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to return, using dot notation for sub-object parameters."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getRoot'."]:
    """Retrieve all available Mailchimp API resource links.

    This tool fetches links to all the resources available in the Mailchimp Marketing API, providing easy access to various API endpoints."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_chimp_chatter_activity(
    context: ToolContext,
    number_of_records_to_return: Annotated[str | None, "Specify the number of Chimp Chatter records to return. Default is 10, maximum is 1000."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "Number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getActivityFeedChimpChatter'."]:
    """Retrieve the latest Chimp Chatter activity for your account.

    Use this tool to fetch the most recent Chimp Chatter activity feed from your Mailchimp account. This provides updates ordered by the latest first."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/activity-feed/chimp-chatter".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"count": number_of_records_to_return, "offset": pagination_offset}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_mailchimp_account_exports(
    context: ToolContext,
    fields_to_exclude: Annotated[str | None, "A comma-separated list of fields to exclude. Use dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to return in the response. Use dot notation for nested fields."] = None,  # noqa: E501
    number_of_records: Annotated[str | None, "Specify the number of records to return. Defaults to 10, maximum is 1000."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "Number of records to skip for pagination. Default is 0, used to manage data retrieval position."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getAccountExports'."]:
    """Retrieve a list of account exports in Mailchimp.

    Call this tool to get a list of account exports for a Mailchimp account, useful for tracking or managing account data exports."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/account-exports".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": fields_to_exclude, "count": number_of_records, "offset": pagination_offset}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def create_mailchimp_account_export(
    context: ToolContext,
    include_export_stages: Annotated[list[str], "Array of export stages to include in the account export."],  # noqa: E501
    export_starting_date: Annotated[str | None, "An ISO 8601 date to limit export to records created after this time. Excludes audiences."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postAccountExport'."]:
    """Create a new account export in your Mailchimp account.

    This tool initiates a new export of account data in your Mailchimp account. Use this when you need to generate and download account information from Mailchimp."""  # noqa: E501
    request_data: Any = {"include_stages": include_export_stages, "since_timestamp": export_starting_date}  # noqa: E501
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/account-exports".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_account_export_info(
    context: ToolContext,
    account_export_id: Annotated[str, "The unique ID for the account export. Required to retrieve specific export details."],  # noqa: E501
    fields_to_exclude: Annotated[str | None, "A comma-separated list of fields to exclude. Use dot notation for sub-objects."] = None,  # noqa: E501
    include_fields: Annotated[str | None, "Comma-separated list of fields to include in the response, using dot notation for sub-objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getAccountExportId'."]:
    """Get information about a specific account export.

    Use this tool to retrieve details about a particular account export using the export ID. Ideal for checking the status or details of exports in Mailchimp."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/account-exports/{export_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), export_id=account_export_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": include_fields, "exclude_fields": fields_to_exclude}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_audience_contacts(
    context: ToolContext,
    exclude_fields_list: Annotated[str | None, "A comma-separated list of fields to exclude from the response. Use dot notation for sub-object parameters."] = None,  # noqa: E501
    include_fields: Annotated[str | None, "A comma-separated list of fields to return. Use dot notation for sub-object parameters."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "The number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
    records_to_return: Annotated[str | None, "The number of audience records to return, ranging from 1 to 1000. Default is 10."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getAudienceContacts'."]:
    """Retrieve all audience information from the account.

    Use this tool to get detailed information about every audience in the Mailchimp account, assisting in data management and marketing analysis."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/audiences".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": include_fields, "exclude_fields": exclude_fields_list, "count": records_to_return, "offset": pagination_offset}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_audience_info(
    context: ToolContext,
    audience_id: Annotated[str, "The unique ID of the audience to retrieve information for."],
    exclude_fields_list: Annotated[str | None, "A list of fields to exclude from the response, using dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to return. Use dot notation for sub-object parameters."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getAudienceId'."]:
    """Retrieve information about a specific audience.

    Use this tool to get details about a specific audience in Mailchimp Marketing using the audience ID."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/audiences/{audience_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), audience_id=audience_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields_list}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def retrieve_audience_contact_list(
    context: ToolContext,
    audience_id: Annotated[str, "The unique identifier for the specific audience to retrieve contacts. Ensure this ID corresponds to an existing audience."],  # noqa: E501
    created_before_datetime: Annotated[str | None, "Restricts the response to contacts created at or before the specified time. Use ISO 8601 format: YYYY-MM-DDTHH:MM:SS+00:00."] = None,  # noqa: E501
    created_since: Annotated[str | None, "Restrict contacts to those created after this timestamp (exclusive). Use ISO 8601 format: YYYY-MM-DDTHH:MM:SS+00:00."] = None,  # noqa: E501
    exclude_fields_list: Annotated[str | None, "Comma-separated fields to exclude from the response, using dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to include in the response, using dot notation for sub-objects."] = None,  # noqa: E501
    number_of_records_to_return: Annotated[str | None, "Specifies how many records to return, from 10 to 1000."] = None,  # noqa: E501
    pagination_cursor: Annotated[str | None, "Paginate through records using a `next_cursor` from a previous request. By default, fetches the first page."] = None,  # noqa: E501
    restrict_by_update_date_before: Annotated[str | None, "Restricts the response to contacts updated at or before the specified date and time, using ISO 8601 format: YYYY-MM-DDTHH:MM:SS+00:00."] = None,  # noqa: E501
    updated_since: Annotated[str | None, "Restrict response to contacts updated after this time using ISO 8601 format (exclusive)."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getAudienceContactList'."]:
    """Retrieve contacts for a specific marketing audience.

    Use this tool to obtain a list of omni-channel contacts associated with a particular audience in your marketing campaigns."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/audiences/{audience_id}/contacts".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), audience_id=audience_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields_list, "count": number_of_records_to_return, "cursor": pagination_cursor, "created_before": created_before_datetime, "created_since": created_since, "updated_before": restrict_by_update_date_before, "updated_since": updated_since}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def create_audience_contact(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    audience_unique_id: Annotated[str | None, "The unique identifier for the audience in Mailchimp where the contact will be added. This ID is necessary to specify the target audience for the new contact.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    merge_field_validation_mode: Annotated[str | None, "Choose 'ignore_required_checks' to skip validation on required merge fields, or 'strict' to enforce validation. Defaults to 'strict' if not set.  Only used when mode is 'execute'."] = None,  # noqa: E501

    data_processing_mode: Annotated[str | None, "Selects the data processing mode: 'historical' mode skips automations and webhooks, 'live' mode triggers them.  Only used when mode is 'execute'."] = None,  # noqa: E501

    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'createAudienceContact'."]:
    """Create a new omni-channel contact for an audience.

    Use this tool to add a new contact to a Mailchimp audience for omni-channel marketing.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires path, query parameters.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.\n      Note: You must also provide the required path, query parameters when executing.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["CREATEAUDIENCECONTACT"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter along with the required path, query parameters. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters
    # Validate required parameters
    missing_params = []
    if not audience_unique_id:
        missing_params.append(("audience_unique_id", "path"))

    if missing_params:
        param_names = [p[0] for p in missing_params]
        param_details = ", ".join(
            [f"{p[0]} ({p[1]})" for p in missing_params]
        )
        raise RetryableToolError(
            message=f"Missing required parameters: {param_names}",
            developer_message=(
                f"Required parameters validation failed: {param_details}"
            ),
            additional_prompt_content=(
                f"The following required parameters are missing: "
                f"{param_details}. Please call this tool again with all "
                "required parameters."
            ),
        )


    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["CREATEAUDIENCECONTACT"] + "\n```"
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["CREATEAUDIENCECONTACT"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/audiences/{audience_id}/contacts".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), audience_id=audience_unique_id),  # noqa: E501  # noqa: UP032
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATEAUDIENCECONTACT"],
        params=remove_none_values({"merge_field_validation_mode": merge_field_validation_mode, "data_mode": data_processing_mode}),  # noqa: E501
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def retrieve_audience_contact(
    context: ToolContext,
    audience_unique_id: Annotated[str, "The unique ID for the audience to retrieve the contact from."],  # noqa: E501
    unique_contact_identifier: Annotated[str, "A unique identifier for the contact, either a Mailchimp contact ID or a channel hash. Format: email:[md5_hash] for emails or sms:[sha256_hash] for phone numbers."],  # noqa: E501
    exclude_fields_list: Annotated[str | None, "A comma-separated list of fields to exclude, using dot notation for sub-objects, when retrieving contact details."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to return, using dot notation for sub-objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getAudienceContact'."]:
    """Retrieve a specific omni-channel contact in an audience.

"""
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/audiences/{audience_id}/contacts/{contact_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), audience_id=audience_unique_id, contact_id=unique_contact_identifier),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields_list}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def update_contact_information(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    audience_id: Annotated[str | None, "The unique ID for the audience to be updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    contact_id: Annotated[str | None, "The unique ID for the contact to be updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    merge_field_validation_mode: Annotated[str | None, "Specifies how merge field validation is handled. Options: `ignore_required_checks` (no error if fields missing), `strict` (errors if required fields not provided). Default is `strict`.  Only used when mode is 'execute'."] = None,  # noqa: E501

    data_processing_mode: Annotated[str | None, "Specify `historical` to prevent triggering automations/webhooks, or `live` to trigger them for contact data changes.  Only used when mode is 'execute'."] = None,  # noqa: E501

    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'patchAudienceContact'."]:
    """Update information for an existing contact.

    Use this tool to update the details of an existing omni-channel contact in a specified audience in Mailchimp. Ideal for modifying contact information such as email, name, or other personal details.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires path, query parameters.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.\n      Note: You must also provide the required path, query parameters when executing.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["UPDATECONTACTINFORMATION"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter along with the required path, query parameters. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters
    # Validate required parameters
    missing_params = []
    if not audience_id:
        missing_params.append(("audience_id", "path"))
    if not contact_id:
        missing_params.append(("contact_id", "path"))

    if missing_params:
        param_names = [p[0] for p in missing_params]
        param_details = ", ".join(
            [f"{p[0]} ({p[1]})" for p in missing_params]
        )
        raise RetryableToolError(
            message=f"Missing required parameters: {param_names}",
            developer_message=(
                f"Required parameters validation failed: {param_details}"
            ),
            additional_prompt_content=(
                f"The following required parameters are missing: "
                f"{param_details}. Please call this tool again with all "
                "required parameters."
            ),
        )


    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["UPDATECONTACTINFORMATION"] + "\n```"
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["UPDATECONTACTINFORMATION"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/audiences/{audience_id}/contacts/{contact_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), audience_id=audience_id, contact_id=contact_id),  # noqa: E501  # noqa: UP032
        method="PATCH",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATECONTACTINFORMATION"],
        params=remove_none_values({"merge_field_validation_mode": merge_field_validation_mode, "data_mode": data_processing_mode}),  # noqa: E501
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def archive_contact_mailchimp(
    context: ToolContext,
    audience_unique_id: Annotated[str, "The unique ID for the Mailchimp audience where the contact will be archived."],  # noqa: E501
    contact_id: Annotated[str, "The unique identifier for the contact to archive within the audience in Mailchimp."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postAudiencesContactsActionsArchive'."]:  # noqa: E501
    """Archives a contact in a Mailchimp audience.

    This tool archives a specific contact within a given audience in Mailchimp. Use this when you need to remove a contact from active participation without deleting them permanently."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/audiences/{audience_id}/contacts/{contact_id}/actions/archive".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), audience_id=audience_unique_id, contact_id=contact_id),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def forget_contact(
    context: ToolContext,
    audience_id: Annotated[str, "The unique ID for the audience where the contact should be forgotten."],  # noqa: E501
    contact_id: Annotated[str, "The unique ID of the contact to be forgotten from the audience."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postAudiencesContactsActionsForget'."]:  # noqa: E501
    """Forget a contact in the audience list.

    Use this tool to erase a contact's data from a specified audience in Mailchimp, ensuring the contact is forgotten."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/audiences/{audience_id}/contacts/{contact_id}/actions/forget".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), audience_id=audience_id, contact_id=contact_id),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_connected_apps(
    context: ToolContext,
    exclude_fields_from_response: Annotated[str | None, "A comma-separated list of fields to exclude from the response, referencing sub-objects with dot notation."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to return in the response. Use dot notation for sub-object fields."] = None,  # noqa: E501
    number_of_records_to_return: Annotated[str | None, "Specify the number of records to return. Default is 10, maximum is 1000."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "Number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getAuthorizedApps'."]:
    """Retrieve registered connected applications for an account.

    Use this tool to get a list of applications that are registered and connected to a Mailchimp account."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/authorized-apps".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields_from_response, "count": number_of_records_to_return, "offset": pagination_offset}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_authorized_app_info(
    context: ToolContext,
    authorized_application_id: Annotated[str, "The unique ID for the connected authorized application to retrieve its information."],  # noqa: E501
    fields_to_exclude: Annotated[str | None, "Comma-separated list of fields to exclude. Use dot notation for sub-object references."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to return. Use dot notation for sub-object parameters."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getAuthorizedAppsId'."]:
    """Retrieve details of a specific authorized application.

    This tool retrieves information about a specific authorized application using the app ID. It is useful for checking the details or status of an application authorized within Mailchimp."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/authorized-apps/{app_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), app_id=authorized_application_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": fields_to_exclude}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_classic_automations_summary(
    context: ToolContext,
    automation_status_filter: Annotated[str | None, "Specify the status of automations to filter results (e.g., 'active', 'paused')."] = None,  # noqa: E501
    created_after_time: Annotated[str | None, "Specify the time to filter automations created after this date-time. Use ISO 8601 format, e.g., 2015-10-21T15:41:36+00:00."] = None,  # noqa: E501
    exclude_fields_list: Annotated[str | None, "A comma-separated list of fields to exclude. Use dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "Comma-separated list of fields to include in the response, using dot notation for sub-objects."] = None,  # noqa: E501
    number_of_records_to_return: Annotated[str | None, "The number of automation records to return. Default is 10, maximum is 1000."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "Number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
    restrict_before_create_time: Annotated[str | None, "Restrict the response to automations created before the specified time in ISO 8601 format. Example: 2015-10-21T15:41:36+00:00."] = None,  # noqa: E501
    restrict_to_automations_started_before: Annotated[str | None, "Restrict the response to automations started before this time using ISO 8601 format (e.g., 2015-10-21T15:41:36+00:00)."] = None,  # noqa: E501
    start_time_after: Annotated[str | None, "Restrict the response to automations started after this date and time in ISO 8601 format (e.g., 2015-10-21T15:41:36+00:00)."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getAutomations'."]:
    """Fetch a summary of an account's classic automations.

    Call this tool to obtain a summary of classic automations set up in a Mailchimp account, useful for understanding automation configurations and statuses."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/automations".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"count": number_of_records_to_return, "offset": pagination_offset, "fields": fields_to_return, "exclude_fields": exclude_fields_list, "before_create_time": restrict_before_create_time, "since_create_time": created_after_time, "before_start_time": restrict_to_automations_started_before, "since_start_time": start_time_after, "status": automation_status_filter}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def create_mailchimp_automation(
    context: ToolContext,
    automation_workflow_type: Annotated[str, "Specify the type of Automation workflow. Currently, only 'abandonedCart' is supported."],  # noqa: E501
    automation_from_name: Annotated[str | None, "The 'from' name to display in the new automation emails. It should be an easily recognizable name for recipients."] = None,  # noqa: E501
    list_id: Annotated[str | None, "The unique identifier for the Mailchimp List to target with the automation."] = None,  # noqa: E501
    reply_to_email_address: Annotated[str | None, "The reply-to email address for the automation in Mailchimp."] = None,  # noqa: E501
    store_id: Annotated[str | None, "The unique identifier for the store in Mailchimp. Required to target specific automation to a store."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postAutomations'."]:
    """Create a new classic automation in Mailchimp.

    This tool initiates the creation of a new classic automation within your Mailchimp account, facilitating automated email campaigns."""  # noqa: E501
    request_data: Any = {"recipients": {"list_id": list_id, "store_id": store_id}, "settings": {"from_name": automation_from_name, "reply_to": reply_to_email_address}, "trigger_settings": {"workflow_type": automation_workflow_type}}  # noqa: E501
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/automations".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_automation_summary(
    context: ToolContext,
    workflow_id: Annotated[str, "The unique ID for the automation workflow to retrieve its summary."],  # noqa: E501
    fields_to_exclude: Annotated[str | None, "A comma-separated list of fields to exclude from the automation workflow details. Use dot notation for sub-objects."] = None,  # noqa: E501
    include_fields: Annotated[str | None, "A comma-separated list of fields to include in the response. Use dot notation for sub-object parameters."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getAutomationsId'."]:
    """Retrieve details of a specific classic automation workflow.

    This tool fetches a summary of an individual classic automation workflow's settings and content, including trigger settings for the first email."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/automations/{workflow_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), workflow_id=workflow_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": include_fields, "exclude_fields": fields_to_exclude}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def pause_automation_emails(
    context: ToolContext,
    automation_workflow_id: Annotated[str, "The unique identifier for the specific automation workflow to be paused."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postAutomationsIdActionsPauseAllEmails'."]:  # noqa: E501
    """Pause emails in a specific automation workflow.

    Use this tool to pause all emails in a specified classic automation workflow in Mailchimp. Ideal for temporarily halting scheduled email deliveries."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/automations/{workflow_id}/actions/pause-all-emails".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), workflow_id=automation_workflow_id),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def start_mailchimp_automation_emails(
    context: ToolContext,
    automation_workflow_id: Annotated[str, "The unique identifier for the Mailchimp automation workflow to be started."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postAutomationsIdActionsStartAllEmails'."]:  # noqa: E501
    """Start all emails in a Mailchimp automation workflow.

    Use this tool to initiate all emails within a specified classic automation workflow in Mailchimp. It should be called when you want to activate a pre-configured sequence of emails in a marketing campaign."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/automations/{workflow_id}/actions/start-all-emails".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), workflow_id=automation_workflow_id),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def archive_mailchimp_automation(
    context: ToolContext,
    automation_workflow_id: Annotated[str, "The unique identifier for the Mailchimp automation workflow to archive. This ID is necessary to specify which automation you want to permanently end."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'archiveAutomations'."]:
    """Permanently archive a Mailchimp automation.

    Use this tool to permanently archive a Mailchimp automation workflow. Once archived, the automation cannot be restarted, but the report data will be kept. You can replicate the archived automation if needed."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/automations/{workflow_id}/actions/archive".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), workflow_id=automation_workflow_id),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_automation_emails_summary(
    context: ToolContext,
    automation_workflow_id: Annotated[str, "The unique ID of the automation workflow to retrieve the email summary for."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getAutomationsIdEmails'."]:
    """Get a summary of emails in an automation workflow.

    Use this tool to retrieve a summary of all emails within a specified classic automation workflow. Call this tool when you need detailed insights into the automation process."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/automations/{workflow_id}/emails".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), workflow_id=automation_workflow_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_automation_email_info(
    context: ToolContext,
    automation_email_unique_id: Annotated[str, "The unique identifier for the Automation workflow email in Mailchimp."],  # noqa: E501
    automation_workflow_id: Annotated[str, "The unique ID for the automation workflow."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getAutomationsIdEmailsId'."]:
    """Retrieve details of a specific classic automation email.

    Use this tool to get detailed information about a specific email within a classic automation workflow in Mailchimp Marketing."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/automations/{workflow_id}/emails/{workflow_email_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), workflow_id=automation_workflow_id, workflow_email_id=automation_email_unique_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def remove_classic_automation_email(
    context: ToolContext,
    automation_workflow_email_id: Annotated[str, "The unique identifier for the specific automation workflow email to be removed."],  # noqa: E501
    automation_workflow_id: Annotated[str, "The unique identifier for the Automation workflow to target for email removal."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteAutomationsIdEmailsId'."]:
    """Removes a specified classic automation workflow email.

    Use this tool to remove a specific classic automation email from a workflow. Note that emails from certain workflow types, such as Abandoned Cart and Product Retargeting, cannot be deleted."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/automations/{workflow_id}/emails/{workflow_email_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), workflow_id=automation_workflow_id, workflow_email_id=automation_workflow_email_id),  # noqa: E501  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def update_automation_email_settings(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    automation_workflow_id: Annotated[str | None, "The unique identifier for the Automation workflow to be updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    automation_workflow_email_id: Annotated[str | None, "The unique ID for the Automation workflow email to update.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'patchAutomationEmailWorkflowId'."]:
    """Update settings for a classic automation workflow email.

    Use this tool to update the settings of a specific email in a classic automation workflow in Mailchimp. Applicable for workflows of type: abandonedBrowse, abandonedCart, emailFollowup, or singleWelcome.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires path parameters.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.\n      Note: You must also provide the required path parameters when executing.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["UPDATEAUTOMATIONEMAILSETTINGS"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter along with the required path parameters. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters
    # Validate required parameters
    missing_params = []
    if not automation_workflow_id:
        missing_params.append(("automation_workflow_id", "path"))
    if not automation_workflow_email_id:
        missing_params.append(("automation_workflow_email_id", "path"))

    if missing_params:
        param_names = [p[0] for p in missing_params]
        param_details = ", ".join(
            [f"{p[0]} ({p[1]})" for p in missing_params]
        )
        raise RetryableToolError(
            message=f"Missing required parameters: {param_names}",
            developer_message=(
                f"Required parameters validation failed: {param_details}"
            ),
            additional_prompt_content=(
                f"The following required parameters are missing: "
                f"{param_details}. Please call this tool again with all "
                "required parameters."
            ),
        )


    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["UPDATEAUTOMATIONEMAILSETTINGS"] + "\n```"  # noqa: E501
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["UPDATEAUTOMATIONEMAILSETTINGS"] + "\n```"  # noqa: E501
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/automations/{workflow_id}/emails/{workflow_email_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), workflow_id=automation_workflow_id, workflow_email_id=automation_workflow_email_id),  # noqa: E501  # noqa: UP032
        method="PATCH",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEAUTOMATIONEMAILSETTINGS"],
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_automation_email_queue_info(
    context: ToolContext,
    automation_workflow_email_id: Annotated[str, "The unique ID for the automation workflow email."],  # noqa: E501
    automation_workflow_id: Annotated[str, "The unique ID for the Automation workflow to obtain the email queue details."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getAutomationsIdEmailsIdQueue'."]:
    """Retrieve details of a classic automation email queue in Mailchimp.

    This tool retrieves information about a classic automation email queue in Mailchimp. It should be called when you need details about queued emails for a specific automation workflow and email."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/automations/{workflow_id}/emails/{workflow_email_id}/queue".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), workflow_id=automation_workflow_id, workflow_email_id=automation_workflow_email_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def add_subscriber_to_workflow(
    context: ToolContext,
    automation_workflow_id: Annotated[str, "The unique identifier for the Automation workflow to which the subscriber will be added."],  # noqa: E501
    subscriber_email_address: Annotated[str, "The email address of the subscriber to add to the automation workflow."],  # noqa: E501
    workflow_email_id: Annotated[str, "The unique ID for the Automation workflow email. Required to identify the specific email in the workflow."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postAutomationsIdEmailsIdQueue'."]:
    """Add a subscriber to an automation workflow.

    Use this tool to manually add a subscriber to a Mailchimp workflow, bypassing default triggers, or to initiate a series of automated emails."""  # noqa: E501
    request_data: Any = {"email_address": subscriber_email_address}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/automations/{workflow_id}/emails/{workflow_email_id}/queue".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), workflow_id=automation_workflow_id, workflow_email_id=workflow_email_id),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_automation_subscriber_info(
    context: ToolContext,
    automation_workflow_email_id: Annotated[str, "The unique ID for the Automation workflow email in Mailchimp."],  # noqa: E501
    automation_workflow_id: Annotated[str, "The unique ID for the Automation workflow in Mailchimp."],  # noqa: E501
    subscriber_email_md5_hash: Annotated[str, "The MD5 hash of the lowercase version of the subscriber's email address in the list."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getAutomationsIdEmailsIdQueueId'."]:
    """Get details of a subscriber in an automation email queue.

    This tool retrieves information about a specific subscriber within the queue of a classic automation email in Mailchimp. Use this when you need to access details about how a subscriber is queued in a specific workflow email."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/automations/{workflow_id}/emails/{workflow_email_id}/queue/{subscriber_hash}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), workflow_id=automation_workflow_id, workflow_email_id=automation_workflow_email_id, subscriber_hash=subscriber_email_md5_hash),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def pause_automated_email(
    context: ToolContext,
    automation_workflow_email_id: Annotated[str, "The unique ID for the automation workflow email to be paused."],  # noqa: E501
    automation_workflow_id: Annotated[str, "The unique ID for the Mailchimp automation workflow to pause."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postAutomationsIdEmailsIdActionsPause'."]:  # noqa: E501
    """Pause an automated email in a Mailchimp workflow.

    Use this tool to pause a specific automated email within a Mailchimp automation workflow. This can be useful when you need to temporarily stop sending an ongoing sequence."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/automations/{workflow_id}/emails/{workflow_email_id}/actions/pause".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), workflow_id=automation_workflow_id, workflow_email_id=automation_workflow_email_id),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def start_automated_email(
    context: ToolContext,
    automation_email_id: Annotated[str, "The unique ID for the specific email in the automation workflow to be started."],  # noqa: E501
    automation_workflow_id: Annotated[str, "The unique identifier for the Automation workflow in Mailchimp."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postAutomationsIdEmailsIdActionsStart'."]:  # noqa: E501
    """Initiate an automated email in Mailchimp.

    Use this tool to begin sending an automated email within a specific Mailchimp workflow. Useful for starting email campaigns based on predefined automation workflows."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/automations/{workflow_id}/emails/{workflow_email_id}/actions/start".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), workflow_id=automation_workflow_id, workflow_email_id=automation_email_id),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_removed_automation_subscribers(
    context: ToolContext,
    automation_workflow_id: Annotated[str, "The unique ID for identifying the specific automation workflow in Mailchimp."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getAutomationsIdRemovedSubscribers'."]:  # noqa: E501
    """Get details on subscribers removed from automation workflows.

    Use this tool to obtain information about subscribers who have been removed from a specific classic automation workflow in Mailchimp."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/automations/{workflow_id}/removed-subscribers".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), workflow_id=automation_workflow_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def remove_subscriber_from_workflow(
    context: ToolContext,
    automation_workflow_id: Annotated[str, "The unique identifier for the Mailchimp automation workflow."],  # noqa: E501
    subscriber_email_address: Annotated[str, "Email address of the list member to be removed from the workflow."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postAutomationsIdRemovedSubscribers'."]:  # noqa: E501
    """Remove a subscriber from a Mailchimp automation workflow.

    This tool removes a subscriber from a specified Mailchimp classic automation workflow at any point, ensuring they cannot be re-added to the same workflow."""  # noqa: E501
    request_data: Any = {"email_address": subscriber_email_address}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/automations/{workflow_id}/removed-subscribers".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), workflow_id=automation_workflow_id),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_removed_subscriber_info(
    context: ToolContext,
    automation_workflow_id: Annotated[str, "The unique ID for the Mailchimp automation workflow. It is required to identify from which workflow the subscriber was removed."],  # noqa: E501
    subscriber_hash: Annotated[str, "MD5 hash of the lowercase version of the subscriber's email address to identify the removed member."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getAutomationsIdRemovedSubscribersId'."]:  # noqa: E501
    """Retrieve details about a removed subscriber from automation.

    Use this tool to get specific information about a subscriber who was removed from a classic Mailchimp automation workflow by providing the workflow ID and subscriber hash."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/automations/{workflow_id}/removed-subscribers/{subscriber_hash}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), workflow_id=automation_workflow_id, subscriber_hash=subscriber_hash),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_batch_summaries(
    context: ToolContext,
    exclude_fields_to_return: Annotated[str | None, "A comma-separated list of fields to exclude from the response. Use dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of specific fields to include in the response, using dot notation for sub-objects."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "Number of records to skip for pagination. Default is 0, used for navigating through large sets of data."] = None,  # noqa: E501
    record_count_to_return: Annotated[str | None, "Specify the number of records to return, from 1 to 1000. Default is 10."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getBatches'."]:
    """Retrieve a summary of batch requests from Mailchimp.

    Call this tool to obtain a summary of batch requests that have been executed in Mailchimp. Useful for monitoring and tracking the status and details of past batch operations."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/batches".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields_to_return, "count": record_count_to_return, "offset": pagination_offset}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def start_batch_processing(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postBatches'."]:
    """Initiate a batch operations request in Mailchimp.

    Use this tool to initiate processing of batch operations requests in Mailchimp Marketing. This is useful for handling multiple actions at once, such as managing email campaigns or subscriber updates.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["STARTBATCHPROCESSING"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters

    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["STARTBATCHPROCESSING"] + "\n```"
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["STARTBATCHPROCESSING"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/batches".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: UP032
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["STARTBATCHPROCESSING"],
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_batch_status(
    context: ToolContext,
    batch_operation_id: Annotated[str, "The unique ID for the Mailchimp batch operation to check its status."],  # noqa: E501
    excluded_fields_list: Annotated[str | None, "Comma-separated list of fields to exclude from the response. Use dot notation for sub-object parameters."] = None,  # noqa: E501
    return_fields: Annotated[str | None, "A comma-separated list of fields to include in the response, using dot notation for sub-objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getBatchesId'."]:
    """Retrieve the status of a Mailchimp batch request.

    Use this tool to check the current status of a specific batch request in Mailchimp, identified by its batch ID."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/batches/{batch_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), batch_id=batch_operation_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": return_fields, "exclude_fields": excluded_fields_list}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def cancel_batch_request(
    context: ToolContext,
    batch_request_id: Annotated[str, "The unique identifier for the batch request you want to cancel."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteBatchesId'."]:
    """Cancels a running batch request to stop its execution.

    This tool stops a batch request from running in Mailchimp Marketing. It should be called to cancel a long-running batch request. After calling this, results of any completed operations in the batch will not be available."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/batches/{batch_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), batch_id=batch_request_id),  # noqa: E501  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_all_batch_webhooks(
    context: ToolContext,
    fields_to_exclude: Annotated[str | None, "Comma-separated list of fields to exclude. Use dot notation for sub-object parameters."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to return. Use dot notation for sub-object references."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "Number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
    records_to_return: Annotated[str | None, "Specify the number of webhook records to return. Default is 10, maximum is 1000."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getBatchWebhooks'."]:
    """Retrieve all configured webhooks for batches.

    Call this tool to get a list of webhooks that have been set up for handling batch processing events in Mailchimp."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/batch-webhooks".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": fields_to_exclude, "count": records_to_return, "offset": pagination_offset}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def configure_webhook_on_batch_complete(
    context: ToolContext,
    webhook_url: Annotated[str, "The URL where the webhook payload will be sent upon batch completion. It must be a valid and accessible URL."],  # noqa: E501
    webhook_enabled: Annotated[bool | None, "Set to True to enable the webhook to receive requests when batch processing completes."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postBatchWebhooks'."]:
    """Configure a webhook for batch processing completion alerts.

    This tool allows you to configure a webhook that triggers when any batch request completes processing in Mailchimp. Useful for automating follow-up actions based on batch completion events."""  # noqa: E501
    request_data: Any = {"url": webhook_url, "enabled": webhook_enabled}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/batch-webhooks".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_batch_webhook_info(
    context: ToolContext,
    batch_webhook_id: Annotated[str, "The unique ID for the batch webhook to retrieve information from Mailchimp."],  # noqa: E501
    fields_to_exclude: Annotated[str | None, "A comma-separated list of fields to exclude from the batch webhook details. Use dot notation for sub-objects."] = None,  # noqa: E501
    include_fields: Annotated[str | None, "Specify fields to include in response. Use dot notation for sub-object fields."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getBatchWebhook'."]:
    """Retrieve details of a specific batch webhook on Mailchimp.

    Use this tool to get information about a specific batch webhook in a Mailchimp account. It retrieves details such as status and metadata of the specified webhook."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/batch-webhooks/{batch_webhook_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), batch_webhook_id=batch_webhook_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": include_fields, "exclude_fields": fields_to_exclude}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def update_batch_webhook(
    context: ToolContext,
    batch_webhook_unique_id: Annotated[str, "The unique identifier for the batch webhook to update."],  # noqa: E501
    enable_webhook: Annotated[bool | None, "Enable or disable webhook requests (true for enable, false for disable)."] = None,  # noqa: E501
    webhook_url: Annotated[str | None, "A valid URL to send webhook notifications when a batch request completes in Mailchimp."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'patchBatchWebhooks'."]:
    """Update a batch webhook on Mailchimp.

    Use this tool to update a webhook that triggers when a batch request in Mailchimp completes. This is useful for managing notifications and automated responses to batch operations."""  # noqa: E501
    request_data: Any = {"url": webhook_url, "enabled": enable_webhook}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/batch-webhooks/{batch_webhook_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), batch_webhook_id=batch_webhook_unique_id),  # noqa: E501  # noqa: UP032
        method="PATCH",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def remove_batch_webhook(
    context: ToolContext,
    batch_webhook_id: Annotated[str, "The unique identifier for the batch webhook to remove. Use this ID to specify which webhook should be deleted, stopping any further webhook notifications to the associated URL."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteBatchWebhookId'."]:
    """Remove a batch webhook to stop sending webhooks to a URL.

    This tool deletes a batch webhook identified by its ID, ensuring that webhooks are no longer sent to the specified URL. Use this tool when you need to stop receiving batch webhooks from Mailchimp to a particular endpoint."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/batch-webhooks/{batch_webhook_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), batch_webhook_id=batch_webhook_id),  # noqa: E501  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_mailchimp_template_folders(
    context: ToolContext,
    exclude_fields_list: Annotated[str | None, "A comma-separated list of fields to exclude. Use dot notation for sub-objects."] = None,  # noqa: E501
    include_fields: Annotated[str | None, "A comma-separated list of fields to return. Use dot notation for sub-object parameters."] = None,  # noqa: E501
    number_of_records_to_return: Annotated[str | None, "Specify the number of template folder records to return, up to a maximum of 1000. The default is 10."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "Number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getTemplateFolders'."]:
    """Retrieve all template folders from Mailchimp.

    Use this tool to retrieve all folders used in Mailchimp to organize templates. It is helpful for managing and categorizing your email templates."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/template-folders".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": include_fields, "exclude_fields": exclude_fields_list, "count": number_of_records_to_return, "offset": pagination_offset}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def create_template_folder(
    context: ToolContext,
    folder_name: Annotated[str, "The desired name for the new template folder in Mailchimp."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postTemplateFolders'."]:
    """Create a new template folder in Mailchimp.

    Use this tool to add a new template folder in Mailchimp. This can help organize your templates into specific categories for better management."""  # noqa: E501
    request_data: Any = {"name": folder_name}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/template-folders".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_template_folder_info(
    context: ToolContext,
    template_folder_id: Annotated[str, "The unique ID for the template folder to retrieve information about."],  # noqa: E501
    exclude_fields_list: Annotated[str | None, "A comma-separated list of fields to exclude from the response. Use dot notation for sub-object fields."] = None,  # noqa: E501
    included_fields: Annotated[str | None, "A comma-separated list of fields to return for the folder. Use dot notation for sub-objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getTemplateFoldersId'."]:
    """Retrieve details of a specific template folder.

    Use this tool to get information about a particular folder used for organizing templates in Mailchimp. This is helpful when you need to know more about how your templates are categorized."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/template-folders/{folder_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), folder_id=template_folder_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": included_fields, "exclude_fields": exclude_fields_list}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def update_template_folder(
    context: ToolContext,
    folder_name: Annotated[str, "The new name for the template folder. Provide a string value."],
    template_folder_id: Annotated[str, "The unique identifier for the template folder to be updated."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'patchTemplateFoldersId'."]:
    """Update a specific folder for organizing templates.

    This tool updates a specific folder used to organize templates in Mailchimp. It should be called when you need to change the details of a template folder, identified by its ID."""  # noqa: E501
    request_data: Any = {"name": folder_name}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/template-folders/{folder_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), folder_id=template_folder_id),  # noqa: E501  # noqa: UP032
        method="PATCH",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def delete_template_folder(
    context: ToolContext,
    template_folder_id: Annotated[str, "The unique ID for the template folder to be deleted. Use this to specify which folder should be removed and have its templates marked as 'unfiled'."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteTemplateFoldersId'."]:
    """Delete a specific template folder in Mailchimp.

    Use this tool to delete a specific template folder in Mailchimp and mark all its templates as 'unfiled'. Call this tool when you need to reorganize or clean up template folders."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/template-folders/{folder_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), folder_id=template_folder_id),  # noqa: E501  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_campaign_folders(
    context: ToolContext,
    exclude_fields: Annotated[str | None, "A comma-separated list of fields to exclude. Use dot notation for sub-objects."] = None,  # noqa: E501
    include_fields: Annotated[str | None, "A comma-separated list of fields to include in the response. Use dot notation for sub-object fields."] = None,  # noqa: E501
    number_of_records_to_return: Annotated[str | None, "The number of campaign folders to return, between 1 and 1000. Defaults to 10."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "Number of records to skip for pagination. Defaults to 0. Use for fetching subsequent pages."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getCampaignFolders'."]:
    """Retrieve all folders used to organize campaigns.

    Use this tool to get a list of all folders created for organizing your campaigns in Mailchimp."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/campaign-folders".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": include_fields, "exclude_fields": exclude_fields, "count": number_of_records_to_return, "offset": pagination_offset}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def create_campaign_folder(
    context: ToolContext,
    folder_name: Annotated[str, "The name to assign to the new campaign folder. It should be a descriptive string that helps identify the folder's contents."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postCampaignFolders'."]:
    """Create a new campaign folder in Mailchimp.

    This tool is used to create a new campaign folder within Mailchimp marketing. Call this tool when you need to organize campaigns into folders for better management."""  # noqa: E501
    request_data: Any = {"name": folder_name}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/campaign-folders".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_campaign_folder_info(
    context: ToolContext,
    campaign_folder_id: Annotated[str, "The unique identifier for the campaign folder. Used to specify which folder's information to retrieve."],  # noqa: E501
    exclude_fields: Annotated[str | None, "Specify a comma-separated list of fields to exclude from the response. Use dot notation for sub-object parameters."] = None,  # noqa: E501
    included_fields: Annotated[str | None, "Comma-separated list of fields to return. Use dot notation for sub-object parameters."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getCampaignFoldersId'."]:
    """Get details about a specific campaign folder.

    Call this tool to retrieve information about a specific campaign folder used for organizing campaigns in Mailchimp."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/campaign-folders/{folder_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), folder_id=campaign_folder_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": included_fields, "exclude_fields": exclude_fields}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def update_campaign_folder(
    context: ToolContext,
    campaign_folder_id: Annotated[str, "The unique identifier for the campaign folder to be updated."],  # noqa: E501
    folder_name: Annotated[str, "The new name to assign to the campaign folder."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'patchCampaignFoldersId'."]:
    """Update a specific folder used to organize campaigns.

    Use this tool to modify the details of an existing campaign folder in Mailchimp. It updates the specified folder to help organize marketing campaigns more efficiently."""  # noqa: E501
    request_data: Any = {"name": folder_name}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/campaign-folders/{folder_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), folder_id=campaign_folder_id),  # noqa: E501  # noqa: UP032
        method="PATCH",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def delete_campaign_folder(
    context: ToolContext,
    campaign_folder_id: Annotated[str, "The unique ID for the Mailchimp campaign folder to be deleted."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteCampaignFoldersId'."]:
    """Delete a specific campaign folder in Mailchimp.

    Deletes a specified campaign folder in Mailchimp and marks all campaigns in it as 'unfiled'. This tool should be called when you need to remove a campaign folder and manage its contents accordingly."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/campaign-folders/{folder_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), folder_id=campaign_folder_id),  # noqa: E501  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_all_marketing_campaigns(
    context: ToolContext,
    campaign_status: Annotated[str | None, "Filter campaigns by their status (e.g., sent, draft)."] = None,  # noqa: E501
    campaign_type: Annotated[str | None, "Specify the type of campaign to retrieve (e.g., regular, plaintext, absplit)."] = None,  # noqa: E501
    campaigns_created_after: Annotated[str | None, "Specify the date and time to restrict results to campaigns created after this point. Must be in ISO 8601 format."] = None,  # noqa: E501
    created_before_date_time: Annotated[str | None, "Restrict response to campaigns created before this time using ISO 8601 format."] = None,  # noqa: E501
    exclude_fields: Annotated[str | None, "A comma-separated list of fields to exclude from the response. Use dot notation for sub-object parameters."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "Comma-separated list of fields to return. Use dot notation for sub-object parameters."] = None,  # noqa: E501
    include_resend_shortcut_eligibility: Annotated[str | None, "Include this field in the response to determine if campaigns are eligible for Resend Shortcuts."] = None,  # noqa: E501
    list_member_identifier: Annotated[str | None, "The MD5 hash of the lowercase version of the list member’s email. Used to retrieve campaigns sent to this member."] = None,  # noqa: E501
    list_unique_id: Annotated[str | None, "The unique identifier for the list associated with the campaigns to be retrieved."] = None,  # noqa: E501
    number_of_records_to_return: Annotated[str | None, "Number of records to return, between 10 and 1000. Default is 10."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "The number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
    restrict_to_campaigns_sent_after: Annotated[str | None, "Restrict the response to campaigns sent after the specified ISO 8601 time."] = None,  # noqa: E501
    sent_before_time: Annotated[str | None, "Restricts the response to campaigns sent before the specified time. It should be in ISO 8601 format."] = None,  # noqa: E501
    sort_by_field: Annotated[str | None, "Specify the field to sort the campaigns by. Use dot notation for sub-object fields."] = None,  # noqa: E501
    sort_order_direction: Annotated[str | None, "Specify the sorting order for the results. Use 'ASC' for ascending or 'DESC' for descending."] = None,  # noqa: E501
    unique_folder_id: Annotated[str | None, "Unique identifier for the folder containing the campaigns."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getCampaigns'."]:
    """Fetches all marketing campaigns from an account.

    Use this tool to retrieve a list of all marketing campaigns associated with a Mailchimp account."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/campaigns".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields, "count": number_of_records_to_return, "offset": pagination_offset, "type": campaign_type, "status": campaign_status, "before_send_time": sent_before_time, "since_send_time": restrict_to_campaigns_sent_after, "before_create_time": created_before_date_time, "since_create_time": campaigns_created_after, "list_id": list_unique_id, "folder_id": unique_folder_id, "member_id": list_member_identifier, "sort_field": sort_by_field, "sort_dir": sort_order_direction, "include_resend_shortcut_eligibility": include_resend_shortcut_eligibility}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def create_mailchimp_campaign(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postCampaigns'."]:
    """Create a new Mailchimp campaign quickly.

    This tool is used to initiate a new email campaign via Mailchimp. It should be called when a user wants to create and configure a marketing email or advertisement using Mailchimp's services.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["CREATEMAILCHIMPCAMPAIGN"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters

    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["CREATEMAILCHIMPCAMPAIGN"] + "\n```"
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["CREATEMAILCHIMPCAMPAIGN"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/campaigns".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: UP032
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATEMAILCHIMPCAMPAIGN"],
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_campaign_details(
    context: ToolContext,
    campaign_id: Annotated[str, "The unique identifier for the campaign to retrieve details about."],  # noqa: E501
    fields_to_exclude: Annotated[str | None, "A comma-separated list of fields to exclude, using dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "Specify a comma-separated list of fields to return, using dot notation for sub-object parameters."] = None,  # noqa: E501
    include_resend_shortcut_eligibility: Annotated[str | None, "Include the `resend_shortcut_eligibility` field in the response to check if the campaign is eligible for Campaign Resend Shortcuts."] = None,  # noqa: E501
    include_resend_shortcut_usage: Annotated[str | None, "Include this to receive the `resend_shortcut_usage` field, providing details about campaigns related by a shortcut."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getCampaignsId'."]:
    """Retrieve details of a specific marketing campaign.

    Use this tool to get detailed information about a specific campaign using its ID. It provides insights and data related to that campaign."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/campaigns/{campaign_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": fields_to_exclude, "include_resend_shortcut_eligibility": include_resend_shortcut_eligibility, "include_resend_shortcut_usage": include_resend_shortcut_usage}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def update_campaign_settings(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    campaign_unique_id: Annotated[str | None, "The unique identifier for the campaign to be updated in Mailchimp.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'patchCampaignsId'."]:
    """Update campaign settings in Mailchimp.

    Use this tool to modify specific settings for a given campaign in Mailchimp. Suitable for updating parts or all of a campaign's configuration.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires path parameters.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.\n      Note: You must also provide the required path parameters when executing.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["UPDATECAMPAIGNSETTINGS"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter along with the required path parameters. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters
    # Validate required parameters
    missing_params = []
    if not campaign_unique_id:
        missing_params.append(("campaign_unique_id", "path"))

    if missing_params:
        param_names = [p[0] for p in missing_params]
        param_details = ", ".join(
            [f"{p[0]} ({p[1]})" for p in missing_params]
        )
        raise RetryableToolError(
            message=f"Missing required parameters: {param_names}",
            developer_message=(
                f"Required parameters validation failed: {param_details}"
            ),
            additional_prompt_content=(
                f"The following required parameters are missing: "
                f"{param_details}. Please call this tool again with all "
                "required parameters."
            ),
        )


    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["UPDATECAMPAIGNSETTINGS"] + "\n```"
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["UPDATECAMPAIGNSETTINGS"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/campaigns/{campaign_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_unique_id),  # noqa: E501  # noqa: UP032
        method="PATCH",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATECAMPAIGNSETTINGS"],
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def delete_mailchimp_campaign(
    context: ToolContext,
    campaign_id: Annotated[str, "The unique ID for the Mailchimp campaign to delete."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteCampaignsId'."]:
    """Delete a specific Mailchimp campaign.

    Use this tool to remove a campaign from your Mailchimp account by specifying the campaign ID. Ideal for managing or cleaning up your Mailchimp campaigns when they are no longer needed."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/campaigns/{campaign_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_id),  # noqa: E501  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def cancel_campaign_send(
    context: ToolContext,
    campaign_identifier: Annotated[str, "The unique identifier for the Mailchimp campaign to be canceled. Used to specify which campaign's delivery is to be stopped."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postCampaignsIdActionsCancelSend'."]:  # noqa: E501
    """Cancel a sent campaign before all recipients receive it.

    Use to cancel a Regular or Plain-Text Campaign that has been sent, but not yet delivered to all recipients. Requires Mailchimp Pro."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/campaigns/{campaign_id}/actions/cancel-send".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_identifier),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def replicate_campaign_mailchimp(
    context: ToolContext,
    campaign_unique_id: Annotated[str, "The unique identifier for the Mailchimp campaign to be replicated."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postCampaignsIdActionsReplicate'."]:
    """Replicate a saved or sent Mailchimp campaign.

    This tool replicates a Mailchimp campaign that is in a saved or sent status. Use it to duplicate existing campaigns for reuse or modification."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/campaigns/{campaign_id}/actions/replicate".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_unique_id),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def send_mailchimp_campaign(
    context: ToolContext,
    campaign_unique_id: Annotated[str, "The unique identifier for the Mailchimp campaign to be sent. This is a string value required to trigger the campaign."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postCampaignsIdActionsSend'."]:
    """Send a Mailchimp campaign immediately or as scheduled.

    Use this tool to send a Mailchimp campaign. For RSS campaigns, it will follow the predefined schedule, while all other types of campaigns will be sent immediately."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/campaigns/{campaign_id}/actions/send".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_unique_id),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def schedule_campaign_delivery(
    context: ToolContext,
    campaign_unique_id: Annotated[str, "The unique identifier for the Mailchimp campaign to be scheduled."],  # noqa: E501
    schedule_delivery_time: Annotated[str, "The UTC date and time to schedule the campaign for delivery in ISO 8601 format. Must be on the quarter-hour (:00, :15, :30, :45)."],  # noqa: E501
    batch_delivery_delay: Annotated[int | None, "The delay in minutes between batches for campaign delivery."] = None,  # noqa: E501
    number_of_batches_for_campaign: Annotated[int | None, "The number of batches for the campaign send. Determines how the campaign delivery is split into batches."] = None,  # noqa: E501
    use_timewarp: Annotated[bool | None, "Set to true to use Timewarp for localizing campaign delivery to recipients' time zones. Cannot be true when using Batch Delivery."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postCampaignsIdActionsSchedule'."]:
    """Schedule a Mailchimp campaign for delivery.

    Use this tool to schedule a Mailchimp campaign for delivery. Ideal for standard campaigns; for Multivariate or RSS campaigns, consider using the send action instead."""  # noqa: E501
    request_data: Any = {"schedule_time": schedule_delivery_time, "timewarp": use_timewarp, "batch_delivery": {"batch_delay": batch_delivery_delay, "batch_count": number_of_batches_for_campaign}}  # noqa: E501
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/campaigns/{campaign_id}/actions/schedule".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_unique_id),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def unschedule_campaign(
    context: ToolContext,
    campaign_id: Annotated[str, "The unique identifier for the scheduled campaign to be unscheduled."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postCampaignsIdActionsUnschedule'."]:  # noqa: E501
    """Unschedule a scheduled Mailchimp campaign.

    Use this tool to unschedule a Mailchimp campaign that is scheduled but hasn't started sending yet."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/campaigns/{campaign_id}/actions/unschedule".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_id),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def send_test_email_campaign(
    context: ToolContext,
    campaign_unique_id: Annotated[str, "The unique ID for the specific Mailchimp campaign to send the test email for."],  # noqa: E501
    test_email_addresses: Annotated[list[str], "An array of email addresses to receive the test email."],  # noqa: E501
    test_email_send_type: Annotated[str, "Specify the type of test email to send: 'html' or 'plaintext'."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postCampaignsIdActionsTest'."]:
    """Send a test email for a specific campaign.

    Use this tool to send a test email for a specified Mailchimp marketing campaign. Useful for previewing the campaign before final send."""  # noqa: E501
    request_data: Any = {"test_emails": test_email_addresses, "send_type": test_email_send_type}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/campaigns/{campaign_id}/actions/test".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_unique_id),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def pause_rss_campaign(
    context: ToolContext,
    campaign_unique_id: Annotated[str, "The unique identifier for the RSS-Driven campaign you want to pause. It should be a string."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postCampaignsIdActionsPause'."]:
    """Pause an RSS-Driven campaign.

    Use this tool to pause an ongoing RSS-Driven campaign in Mailchimp Marketing. It should be called when you need to temporarily stop a campaign without deleting it."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/campaigns/{campaign_id}/actions/pause".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_unique_id),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def resume_rss_driven_campaign(
    context: ToolContext,
    campaign_id: Annotated[str, "The unique identifier for the RSS-driven campaign to be resumed."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postCampaignsIdActionsResume'."]:
    """Resume an RSS-Driven campaign in Mailchimp.

    This tool resumes an RSS-Driven campaign in Mailchimp, allowing previously paused campaigns to continue sending as planned."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/campaigns/{campaign_id}/actions/resume".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_id),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def resend_campaign_to_segments(
    context: ToolContext,
    campaign_unique_id: Annotated[str, "The unique ID for identifying the campaign to replicate and resend."],  # noqa: E501
    resend_shortcut_type: Annotated[str | None, "Specify the type of segment to resend the campaign to. Options: 'to_non_openers', 'to_new_subscribers', 'to_non_clickers', 'to_non_purchasers'. Default is 'to_non_openers'."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postCampaignsIdActionsCreateResend'."]:  # noqa: E501
    """Resend a campaign to specific segments.

    Use this tool to replicate and resend a Mailchimp campaign to segments like non-openers or new subscribers."""  # noqa: E501
    request_data: Any = {"shortcut_type": resend_shortcut_type}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/campaigns/{campaign_id}/actions/create-resend".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_unique_id),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_campaign_content(
    context: ToolContext,
    campaign_id: Annotated[str, "The unique identifier for the Mailchimp campaign to retrieve content for."],  # noqa: E501
    exclude_fields_list: Annotated[str | None, "A comma-separated list of fields to exclude when retrieving campaign content. Use dot notation for sub-object fields."] = None,  # noqa: E501
    included_fields: Annotated[str | None, "A comma-separated list of fields to include in the response. Use dot notation to specify sub-object parameters."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getCampaignsIdContent'."]:
    """Retrieve the HTML and plain-text content for a Mailchimp campaign.

    Use this tool to get the content of a specific Mailchimp campaign by providing its campaign ID. The response includes both HTML and plain-text content, useful for viewing or analyzing email campaigns in detail."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/campaigns/{campaign_id}/content".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": included_fields, "exclude_fields": exclude_fields_list}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def set_campaign_content(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    campaign_id: Annotated[str | None, "The unique identifier for the Mailchimp campaign to set the content for. This ID is required to specify which campaign you are updating.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'putCampaignsIdContent'."]:
    """Set the content for a campaign in Mailchimp.

    Use this tool to update or set the content for a specific campaign in Mailchimp. It is called when you need to change or define what content is included in a campaign.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires path parameters.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.\n      Note: You must also provide the required path parameters when executing.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["SETCAMPAIGNCONTENT"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter along with the required path parameters. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters
    # Validate required parameters
    missing_params = []
    if not campaign_id:
        missing_params.append(("campaign_id", "path"))

    if missing_params:
        param_names = [p[0] for p in missing_params]
        param_details = ", ".join(
            [f"{p[0]} ({p[1]})" for p in missing_params]
        )
        raise RetryableToolError(
            message=f"Missing required parameters: {param_names}",
            developer_message=(
                f"Required parameters validation failed: {param_details}"
            ),
            additional_prompt_content=(
                f"The following required parameters are missing: "
                f"{param_details}. Please call this tool again with all "
                "required parameters."
            ),
        )


    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["SETCAMPAIGNCONTENT"] + "\n```"
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["SETCAMPAIGNCONTENT"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/campaigns/{campaign_id}/content".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_id),  # noqa: E501  # noqa: UP032
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["SETCAMPAIGNCONTENT"],
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_mailchimp_campaign_feedback(
    context: ToolContext,
    campaign_id: Annotated[str, "The unique identifier for the specific Mailchimp campaign from which to retrieve feedback."],  # noqa: E501
    fields_to_exclude: Annotated[str | None, "Comma-separated list of fields to exclude from the feedback data, using dot notation for sub-objects."] = None,  # noqa: E501
    include_fields: Annotated[str | None, "A comma-separated list of specific fields to return, using dot notation for sub-objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getCampaignsIdFeedback'."]:
    """Retrieve feedback comments for a Mailchimp campaign.

    Use this tool to get team feedback for a specific Mailchimp campaign by providing the campaign ID."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/campaigns/{campaign_id}/feedback".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": include_fields, "exclude_fields": fields_to_exclude}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def add_campaign_feedback(
    context: ToolContext,
    campaign_unique_id: Annotated[str, "The unique identifier for the Mailchimp campaign to which feedback will be added."],  # noqa: E501
    feedback_content: Annotated[str, "The content of the feedback to be added to the campaign."],
    editable_block_id: Annotated[int | None, "The ID of the editable block the feedback addresses in the campaign."] = None,  # noqa: E501
    is_feedback_complete: Annotated[bool | None, "Indicates whether the feedback is complete. Use 'true' if complete and 'false' otherwise."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postCampaignsIdFeedback'."]:
    """Add feedback to a specific Mailchimp campaign.

    Use this tool to submit feedback for a particular campaign in Mailchimp. This is helpful when users want to provide input or comments about a campaign."""  # noqa: E501
    request_data: Any = {"block_id": editable_block_id, "message": feedback_content, "is_complete": is_feedback_complete}  # noqa: E501
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/campaigns/{campaign_id}/feedback".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_unique_id),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_campaign_feedback_message(
    context: ToolContext,
    campaign_unique_id: Annotated[str, "The unique identifier for the campaign to retrieve the specific feedback message."],  # noqa: E501
    feedback_message_id: Annotated[str, "The unique identifier for the feedback message to retrieve from the campaign."],  # noqa: E501
    exclude_fields_from_feedback: Annotated[str | None, "A comma-separated list of fields to exclude from the feedback. Use dot notation for sub-object parameters."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to include in the response. Use dot notation for sub-object fields."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getCampaignsIdFeedbackId'."]:
    """Retrieve a specific feedback message from a campaign.

    Use this tool to get detailed feedback from a specific campaign by providing the campaign and feedback identifiers."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/campaigns/{campaign_id}/feedback/{feedback_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_unique_id, feedback_id=feedback_message_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields_from_feedback}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def update_campaign_feedback(
    context: ToolContext,
    campaign_id: Annotated[str, "The unique identifier for the Mailchimp campaign to be updated."],
    feedback_message_id: Annotated[str, "The unique identifier for the specific feedback message to update in the campaign."],  # noqa: E501
    editable_block_id: Annotated[int | None, "The ID of the editable block that the feedback addresses within the campaign."] = None,  # noqa: E501
    feedback_is_complete: Annotated[bool | None, "Indicates if the feedback is marked as complete. Use true for complete and false for incomplete."] = None,  # noqa: E501
    feedback_message: Annotated[str | None, "The text content of the feedback message to be updated."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'patchCampaignsIdFeedbackId'."]:
    """Update specific feedback for a Mailchimp campaign.

    Use this tool to update a particular feedback message for a specific Mailchimp marketing campaign. This is useful when corrections or additional details need to be added to existing feedback."""  # noqa: E501
    request_data: Any = {"block_id": editable_block_id, "message": feedback_message, "is_complete": feedback_is_complete}  # noqa: E501
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/campaigns/{campaign_id}/feedback/{feedback_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_id, feedback_id=feedback_message_id),  # noqa: E501  # noqa: UP032
        method="PATCH",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def remove_campaign_feedback(
    context: ToolContext,
    campaign_unique_id: Annotated[str, "A unique identifier for the campaign from which you want to remove feedback."],  # noqa: E501
    feedback_message_id: Annotated[str, "The unique identifier for the feedback message to be removed from the campaign."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteCampaignsIdFeedbackId'."]:
    """Remove a specific feedback message from a campaign.

    Use this tool to delete a feedback message associated with a specific campaign in Mailchimp."""
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/campaigns/{campaign_id}/feedback/{feedback_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_unique_id, feedback_id=feedback_message_id),  # noqa: E501  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def review_campaign_send_checklist(
    context: ToolContext,
    campaign_unique_id: Annotated[str, "The unique identifier for the campaign in Mailchimp."],
    fields_to_exclude: Annotated[str | None, "Comma-separated list of fields to exclude, using dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "Comma-separated list of fields to return. Use dot notation for sub-objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getCampaignsIdSendChecklist'."]:
    """Review the send checklist for a Mailchimp campaign.

    This tool is used to review the send checklist for a specific Mailchimp campaign. It helps to identify and resolve any potential issues before sending the campaign."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/campaigns/{campaign_id}/send-checklist".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_unique_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": fields_to_exclude}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_connected_sites(
    context: ToolContext,
    exclude_fields_list: Annotated[str | None, "A list of fields to exclude, using dot notation for sub-object parameters."] = None,  # noqa: E501
    included_fields: Annotated[str | None, "A comma-separated list of specific fields to return. Use dot notation for sub-object parameters."] = None,  # noqa: E501
    number_of_records_to_return: Annotated[str | None, "The number of records to return. Default is 10, maximum is 1000."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "Number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getConnectedSites'."]:
    """Retrieve all connected sites from a Mailchimp account.

    Use this tool to get a list of all sites connected to a Mailchimp account. Ideal for managing or reviewing the connected site configurations."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/connected-sites".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": included_fields, "exclude_fields": exclude_fields_list, "count": number_of_records_to_return, "offset": pagination_offset}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def create_mailchimp_connected_site(
    context: ToolContext,
    connected_site_domain: Annotated[str, "The domain of the site you want to connect to Mailchimp."],  # noqa: E501
    site_unique_identifier: Annotated[str, "A unique identifier string for the site. This is used to distinguish different connected sites in Mailchimp."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postConnectedSites'."]:
    """Create a new Mailchimp connected site.

    This tool is used to create a new connected site in Mailchimp. It should be called whenever you need to integrate a new site with Mailchimp's marketing tools."""  # noqa: E501
    request_data: Any = {"foreign_id": site_unique_identifier, "domain": connected_site_domain}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/connected-sites".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_connected_site_info(
    context: ToolContext,
    connected_site_identifier: Annotated[str, "The unique identifier for the connected site to retrieve its information."],  # noqa: E501
    exclude_fields_list: Annotated[str | None, "A comma-separated list of fields to exclude from the response. Use dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "Specify a comma-separated list of fields to return. Use dot notation for sub-object parameters."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getConnectedSitesId'."]:
    """Retrieve details of a specific connected site.

    Use this tool to get information about a connected site using its ID. It provides various details related to the site."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/connected-sites/{connected_site_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), connected_site_id=connected_site_identifier),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields_list}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def remove_mailchimp_connected_site(
    context: ToolContext,
    site_identifier: Annotated[str, "The unique identifier for the connected site you wish to remove from your Mailchimp account."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteConnectedSitesId'."]:
    """Remove a connected site from your Mailchimp account.

    Use this tool to delete a connected site from your Mailchimp account, removing its integration."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/connected-sites/{connected_site_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), connected_site_id=site_identifier),  # noqa: E501  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def verify_script_installation(
    context: ToolContext,
    site_unique_identifier: Annotated[str, "The unique identifier for the Mailchimp connected site to verify script installation."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postConnectedSitesIdActionsVerifyScriptInstallation'."]:  # noqa: E501
    """Verify if the Mailchimp connected site script is installed.

    This tool checks if a Mailchimp connected site's script has been correctly installed using the script URL or fragment. Use it to confirm script deployment."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/connected-sites/{connected_site_id}/actions/verify-script-installation".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), connected_site_id=site_unique_identifier),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def trigger_automation_step(
    context: ToolContext,
    flow_id: Annotated[str, "The unique identifier for the automation flow to trigger a specific step."],  # noqa: E501
    list_member_email_address: Annotated[str, "The email address of the list member to trigger the automation step for."],  # noqa: E501
    step_identifier: Annotated[str, "The unique identifier for the step in the Mailchimp automation flow."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postCustomerJourneysJourneysIdStepsIdActionsTrigger'."]:  # noqa: E501
    """Trigger a step in a Mailchimp automation flow.

    Use this tool to activate a specific step in an existing Mailchimp automation flow. It requires the journey and step IDs, which are provided during the creation process in the Customer Journey API."""  # noqa: E501
    request_data: Any = {"email_address": list_member_email_address}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/customer-journeys/journeys/{journey_id}/steps/{step_id}/actions/trigger".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), journey_id=flow_id, step_id=step_identifier),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_file_manager_files(
    context: ToolContext,
    created_after_date: Annotated[str | None, "Files created after this date will be included in the response. Use ISO 8601 format: 2015-10-21T15:41:36+00:00."] = None,  # noqa: E501
    exclude_fields_list: Annotated[str | None, "Comma-separated fields to omit from the response. Use dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to return. Use dot notation for sub-object parameters."] = None,  # noqa: E501
    file_created_by_user: Annotated[str | None, "The Mailchimp account user who created the File Manager file."] = None,  # noqa: E501
    file_sort_field: Annotated[str | None, "Specify the field to sort the files by, such as 'name', 'date', etc."] = None,  # noqa: E501
    file_type: Annotated[str | None, "The file type to filter File Manager files. Expected as a string value."] = None,  # noqa: E501
    number_of_records_to_return: Annotated[str | None, "Specifies the number of records to return. Default is 10; maximum is 1000."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "The number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
    restrict_files_before_date: Annotated[str | None, "Restrict the response to files created before the specified ISO 8601 date."] = None,  # noqa: E501
    sort_order_direction: Annotated[str | None, "Sets the order direction for sorting results. Use 'ASC' for ascending and 'DESC' for descending."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getFileManagerFiles'."]:
    """Retrieve images and files from the Mailchimp File Manager.

    Use this tool to get a list of all images and files stored in the File Manager of the Mailchimp account. It provides access to media assets used in marketing campaigns."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/file-manager/files".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields_list, "count": number_of_records_to_return, "offset": pagination_offset, "type": file_type, "created_by": file_created_by_user, "before_created_at": restrict_files_before_date, "since_created_at": created_after_date, "sort_field": file_sort_field, "sort_dir": sort_order_direction}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def upload_file_to_file_manager(
    context: ToolContext,
    file_content_base64: Annotated[str, "The base64-encoded contents of the file to be uploaded."],
    file_name: Annotated[str, "The name to be assigned to the uploaded file."],
    folder_id: Annotated[int | None, "The ID of the folder where the file will be uploaded. This should be an integer."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postFileManagerFiles'."]:
    """Upload a new file or image to the File Manager.

    Use this tool to upload files or images to the File Manager, enhancing content management."""
    request_data: Any = {"folder_id": folder_id, "name": file_name, "file_data": file_content_base64}  # noqa: E501
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/file-manager/files".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_file_manager_file_info(
    context: ToolContext,
    file_manager_file_id: Annotated[str, "The unique ID for the File Manager file to retrieve its information."],  # noqa: E501
    exclude_fields_list: Annotated[str | None, "Comma-separated list of fields to exclude, using dot notation for sub-objects."] = None,  # noqa: E501
    return_fields: Annotated[str | None, "A comma-separated list of fields to return. Use dot notation to specify sub-objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getFileManagerFilesId'."]:
    """Retrieve information about a specific file from Mailchimp's File Manager.

    Use this tool to get detailed information about a specific file stored in Mailchimp's File Manager using the file ID."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/file-manager/files/{file_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), file_id=file_manager_file_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": return_fields, "exclude_fields": exclude_fields_list}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def update_file_manager_file(
    context: ToolContext,
    file_manager_file_id: Annotated[str, "The unique identifier for the File Manager file to be updated."],  # noqa: E501
    file_name: Annotated[str | None, "Specify the new name for the file in the File Manager."] = None,  # noqa: E501
    folder_id: Annotated[int | None, "The ID of the folder. Set to `0` to remove a file from its current folder."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'patchFileManagerFilesId'."]:
    """Update a file in the Mailchimp File Manager.

    Use this tool to update an existing file in Mailchimp's File Manager by providing the file ID. It is useful for changing file details or replacing content."""  # noqa: E501
    request_data: Any = {"folder_id": folder_id, "name": file_name}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/file-manager/files/{file_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), file_id=file_manager_file_id),  # noqa: E501  # noqa: UP032
        method="PATCH",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def delete_file_manager_file(
    context: ToolContext,
    file_manager_file_id: Annotated[str, "The unique identifier for the file to be deleted from Mailchimp's File Manager."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteFileManagerFilesId'."]:
    """Remove a specific file from Mailchimp's File Manager.

    Use this tool to delete a specific file by its ID from Mailchimp's File Manager. It helps manage and organize files by removing unwanted or outdated ones."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/file-manager/files/{file_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), file_id=file_manager_file_id),  # noqa: E501  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def list_file_manager_folders(
    context: ToolContext,
    created_after_date: Annotated[str | None, "Restrict the response to files created after the specified date in ISO 8601 format."] = None,  # noqa: E501
    created_by_user: Annotated[str | None, "The Mailchimp account user who created the File Manager file."] = None,  # noqa: E501
    exclude_fields: Annotated[str | None, "A comma-separated list of fields to exclude from the response. Use dot notation for sub-object parameters."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "Comma-separated list of fields to include in the response, using dot notation for sub-objects."] = None,  # noqa: E501
    number_of_records_to_return: Annotated[str | None, "Specify the number of folder records to return, from 1 to 1000. Default is 10."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "Number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
    restrict_to_files_created_before: Annotated[str | None, "Restrict the response to files created before the specified date using ISO 8601 format, e.g., 2015-10-21T15:41:36+00:00."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getFileManagerFolders'."]:
    """Retrieve a list of folders from the File Manager.

    This tool is used to obtain a list of all folders available in the File Manager, which is helpful for organizing and accessing files efficiently."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/file-manager/folders".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields, "count": number_of_records_to_return, "offset": pagination_offset, "created_by": created_by_user, "before_created_at": restrict_to_files_created_before, "since_created_at": created_after_date}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def create_new_file_manager_folder(
    context: ToolContext,
    folder_name: Annotated[str, "The desired name for the new folder in File Manager."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postFileManagerFolders'."]:
    """Create a new folder in Mailchimp's File Manager.

    Use this tool to create a new folder in Mailchimp's File Manager. This can be helpful for organizing files within your Mailchimp account."""  # noqa: E501
    request_data: Any = {"name": folder_name}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/file-manager/folders".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_file_manager_folder_info(
    context: ToolContext,
    file_manager_folder_id: Annotated[str, "The unique identifier for the File Manager folder to retrieve."],  # noqa: E501
    exclude_fields_list: Annotated[str | None, "Comma-separated fields to exclude. Use dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of specific fields to return, use dot notation for sub-objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getFileManagerFoldersId'."]:
    """Retrieve details of a specific folder from File Manager.

    Use this tool to get information about a particular folder in Mailchimp's File Manager. It's useful for accessing folder-specific details, such as name and metadata."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/file-manager/folders/{folder_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), folder_id=file_manager_folder_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields_list}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def update_file_manager_folder(
    context: ToolContext,
    file_manager_folder_id: Annotated[str, "The unique identifier for the File Manager folder to update."],  # noqa: E501
    folder_name: Annotated[str, "The new name for the File Manager folder. It should be a string value."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'patchFileManagerFoldersId'."]:
    """Update a specific File Manager folder in Mailchimp.

    Use this tool to update the details of a specific folder in Mailchimp's File Manager. Useful for organizing files within the platform."""  # noqa: E501
    request_data: Any = {"name": folder_name}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/file-manager/folders/{folder_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), folder_id=file_manager_folder_id),  # noqa: E501  # noqa: UP032
        method="PATCH",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def delete_file_manager_folder(
    context: ToolContext,
    file_manager_folder_id: Annotated[str, "The unique identifier for the folder to be deleted in the File Manager."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteFileManagerFoldersId'."]:
    """Delete a specific folder in the File Manager.

    Use this tool to delete a folder from Mailchimp's File Manager by specifying the folder ID."""
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/file-manager/folders/{folder_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), folder_id=file_manager_folder_id),  # noqa: E501  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_folder_files(
    context: ToolContext,
    file_manager_folder_id: Annotated[str, "The unique identifier for the specific File Manager folder to retrieve files from."],  # noqa: E501
    exclude_fields: Annotated[str | None, "Comma-separated list of fields to exclude. Use dot notation for sub-object parameters."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to return. Use dot notation for sub-object fields."] = None,  # noqa: E501
    file_creator_user: Annotated[str | None, "Mailchimp account user who created the File Manager file. Filter results by this user's contributions."] = None,  # noqa: E501
    file_type: Annotated[str | None, "Specifies the file type to filter files in the folder. Use to retrieve specific types like 'image', 'document', etc."] = None,  # noqa: E501
    filter_files_created_after: Annotated[str | None, "Restrict the response to files created after the specified date in ISO 8601 format (e.g., 2015-10-21T15:41:36+00:00)."] = None,  # noqa: E501
    number_of_records: Annotated[str | None, "Specifies the number of files to retrieve, with a default of 10 and a maximum of 1000."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "The number of records to skip for pagination. Default is 0. Use this to access pages beyond the first one."] = None,  # noqa: E501
    restrict_files_before_date: Annotated[str | None, "Restrict response to files created before this date using ISO 8601 format (e.g., 2015-10-21T15:41:36+00:00)."] = None,  # noqa: E501
    sort_by_field: Annotated[str | None, "Specify the field to sort the files by, such as name or size."] = None,  # noqa: E501
    sort_order_direction: Annotated[str | None, "Specify the order direction for sorting results. Typically 'asc' for ascending or 'desc' for descending order."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getFileManagerFoldersFiles'."]:
    """Retrieve files and images from a specific folder.

    Use this tool to get a list of available images and files stored in a specified folder within Mailchimp's file manager. Ideal for accessing and managing digital assets."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/file-manager/folders/{folder_id}/files".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), folder_id=file_manager_folder_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields, "count": number_of_records, "offset": pagination_offset, "type": file_type, "created_by": file_creator_user, "before_created_at": restrict_files_before_date, "since_created_at": filter_files_created_after, "sort_field": sort_by_field, "sort_dir": sort_order_direction}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def retrieve_mailchimp_lists(
    context: ToolContext,
    created_after_date: Annotated[str | None, "Restrict results to lists created after this date in ISO 8601 format (e.g., 2015-10-21T15:41:36+00:00)."] = None,  # noqa: E501
    created_before_date: Annotated[str | None, "Restrict response to lists created before the specified date in ISO 8601 format (e.g., 2015-10-21T15:41:36+00:00)."] = None,  # noqa: E501
    exclude_fields_list: Annotated[str | None, "Comma-separated list of fields to exclude, using dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to return, using dot notation for sub-objects."] = None,  # noqa: E501
    filter_by_subscriber_email: Annotated[str | None, "Restrict results to lists that include a specific subscriber's email address."] = None,  # noqa: E501
    include_total_contacts: Annotated[str | None, "Set to true to return the total_contacts field, which includes an approximate count of all contacts in any state."] = None,  # noqa: E501
    lists_after_last_campaign_date: Annotated[str | None, "Restrict results to lists created after the last campaign send date. Use ISO 8601 format (e.g., 2015-10-21T15:41:36+00:00)."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "The number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
    records_to_return: Annotated[str | None, "The number of list records to return. Accepts values between 1 and 1000, with a default of 10."] = None,  # noqa: E501
    restrict_to_ecommerce_store_lists: Annotated[str | None, "Restrict results to lists containing an active, connected, undeleted ecommerce store. Expected values are 'true' or 'false'."] = None,  # noqa: E501
    restrict_to_lists_before_last_campaign_sent: Annotated[str | None, "Restrict results to lists created before the last campaign send date (ISO 8601 format)."] = None,  # noqa: E501
    sort_direction: Annotated[str | None, "Determines the order direction for the sorted results. Accepts 'asc' for ascending and 'desc' for descending."] = None,  # noqa: E501
    sort_lists_by_field: Annotated[str | None, "Field by which to sort the list results. Choose from available list fields."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getLists'."]:
    """Retrieve information about all Mailchimp lists.

    Call this tool to obtain details about all the lists associated with a Mailchimp account."""
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields_list, "count": records_to_return, "offset": pagination_offset, "before_date_created": created_before_date, "since_date_created": created_after_date, "before_campaign_last_sent": restrict_to_lists_before_last_campaign_sent, "since_campaign_last_sent": lists_after_last_campaign_date, "email": filter_by_subscriber_email, "sort_field": sort_lists_by_field, "sort_dir": sort_direction, "has_ecommerce_store": restrict_to_ecommerce_store_lists, "include_total_contacts": include_total_contacts}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def create_mailchimp_list(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postLists'."]:
    """Create a new list in your Mailchimp account.



    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["CREATEMAILCHIMPLIST"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters

    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["CREATEMAILCHIMPLIST"] + "\n```"
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["CREATEMAILCHIMPLIST"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/lists".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: UP032
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATEMAILCHIMPLIST"],
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_mailchimp_list_info(
    context: ToolContext,
    mailchimp_list_id: Annotated[str, "The unique ID for the Mailchimp list to retrieve information about."],  # noqa: E501
    exclude_fields_in_mailchimp: Annotated[str | None, "A comma-separated list of fields to exclude. Use dot notation for sub-objects, e.g., 'stats.member_count'."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to return. Use dot notation for sub-object parameters."] = None,  # noqa: E501
    include_total_contacts: Annotated[str | None, "Set to true to include the approximate count of all contacts in any state (total_contacts) in the response."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getListsId'."]:
    """Retrieve details of a specific list in Mailchimp.

    Use this tool to get detailed information about a specific list in your Mailchimp account, including members who are unconfirmed, unsubscribed, or cleaned."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=mailchimp_list_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields_in_mailchimp, "include_total_contacts": include_total_contacts}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def update_mailchimp_list_settings(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    mailchimp_list_id: Annotated[str | None, "The unique ID of the Mailchimp list to be updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'patchListsId'."]:
    """Update settings for a specific Mailchimp list.

    Use this tool to modify the settings of a specific list in Mailchimp. It should be called when you need to update a list's configuration or preferences.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires path parameters.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.\n      Note: You must also provide the required path parameters when executing.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["UPDATEMAILCHIMPLISTSETTINGS"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter along with the required path parameters. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters
    # Validate required parameters
    missing_params = []
    if not mailchimp_list_id:
        missing_params.append(("mailchimp_list_id", "path"))

    if missing_params:
        param_names = [p[0] for p in missing_params]
        param_details = ", ".join(
            [f"{p[0]} ({p[1]})" for p in missing_params]
        )
        raise RetryableToolError(
            message=f"Missing required parameters: {param_names}",
            developer_message=(
                f"Required parameters validation failed: {param_details}"
            ),
            additional_prompt_content=(
                f"The following required parameters are missing: "
                f"{param_details}. Please call this tool again with all "
                "required parameters."
            ),
        )


    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["UPDATEMAILCHIMPLISTSETTINGS"] + "\n```"  # noqa: E501
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["UPDATEMAILCHIMPLISTSETTINGS"] + "\n```"  # noqa: E501
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/lists/{list_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=mailchimp_list_id),  # noqa: E501  # noqa: UP032
        method="PATCH",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEMAILCHIMPLISTSETTINGS"],
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def delete_mailchimp_list(
    context: ToolContext,
    list_id: Annotated[str, "The unique ID for the Mailchimp list to be deleted."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteListsId'."]:
    """Delete a list from your Mailchimp account.

    Use this tool to permanently delete a list from your Mailchimp account. Deleting a list removes its history, including subscriber activity and email addresses, unless previously exported and backed up."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_id),  # noqa: E501  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def manage_mailchimp_list_members(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    list_id: Annotated[str | None, "The unique ID for the specific Mailchimp list to manage.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    allow_incomplete_merge_fields: Annotated[str | None, "Allows member data without required merge fields if set to true. Defaults to false.  Only used when mode is 'execute'."] = None,  # noqa: E501

    ignore_duplicate_members: Annotated[str | None, "Set to true to ignore duplicate entries in the batch request, saving the first occurrence.  Only used when mode is 'execute'."] = None,  # noqa: E501

    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postListsId'."]:
    """Batch subscribe or unsubscribe members in a Mailchimp list.

    Use this tool to add or remove multiple members from a specific Mailchimp list. Ideal for managing subscriber lists efficiently.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires path, query parameters.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.\n      Note: You must also provide the required path, query parameters when executing.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["MANAGEMAILCHIMPLISTMEMBERS"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter along with the required path, query parameters. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters
    # Validate required parameters
    missing_params = []
    if not list_id:
        missing_params.append(("list_id", "path"))

    if missing_params:
        param_names = [p[0] for p in missing_params]
        param_details = ", ".join(
            [f"{p[0]} ({p[1]})" for p in missing_params]
        )
        raise RetryableToolError(
            message=f"Missing required parameters: {param_names}",
            developer_message=(
                f"Required parameters validation failed: {param_details}"
            ),
            additional_prompt_content=(
                f"The following required parameters are missing: "
                f"{param_details}. Please call this tool again with all "
                "required parameters."
            ),
        )


    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["MANAGEMAILCHIMPLISTMEMBERS"] + "\n```"  # noqa: E501
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["MANAGEMAILCHIMPLISTMEMBERS"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/lists/{list_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_id),  # noqa: E501  # noqa: UP032
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["MANAGEMAILCHIMPLISTMEMBERS"],
        params=remove_none_values({"skip_merge_validation": allow_incomplete_merge_fields, "skip_duplicate_check": ignore_duplicate_members}),  # noqa: E501
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_abuse_reports_for_list(
    context: ToolContext,
    list_unique_id: Annotated[str, "The unique ID for the mailing list to retrieve abuse reports for."],  # noqa: E501
    exclude_fields_from_result: Annotated[str | None, "Comma-separated list of fields to exclude from the response, using dot notation for sub-objects."] = None,  # noqa: E501
    number_of_records_to_return: Annotated[str | None, "The number of records to return. Default is 10. Maximum is 1000."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "Number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
    return_fields: Annotated[str | None, "Comma-separated list of fields to include in the response. Use dot notation for sub-object parameters."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getListsIdAbuseReports'."]:
    """Retrieve all abuse reports for a specified mailing list.

    Call this tool to get detailed information about abuse reports associated with a particular mailing list. This can be useful for monitoring and handling abuse feedback effectively."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/abuse-reports".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": return_fields, "exclude_fields": exclude_fields_from_result, "count": number_of_records_to_return, "offset": pagination_offset}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def fetch_abuse_report_details(
    context: ToolContext,
    abuse_report_id: Annotated[str, "The unique identifier for the specific abuse report to fetch details for."],  # noqa: E501
    mailing_list_unique_id: Annotated[str, "The unique ID for the mailing list associated with the abuse report."],  # noqa: E501
    fields_to_exclude: Annotated[str | None, "A comma-separated list of fields to exclude using dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to return. Use dot notation for sub-object parameters."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "The number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
    records_to_return: Annotated[str | None, "Specify the number of records to return, between 1 and 1000. Default is 10."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getListsIdAbuseReportsId'."]:
    """Fetch details about a specific abuse report for a mailing list.

    This tool retrieves detailed information about an abuse report identified by a specific report ID associated with a mailing list via Mailchimp's marketing API. It should be called when specific details about an abuse report are needed."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/abuse-reports/{report_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=mailing_list_unique_id, report_id=abuse_report_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": fields_to_exclude, "count": records_to_return, "offset": pagination_offset}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_daily_list_activity(
    context: ToolContext,
    list_unique_id: Annotated[str, "The unique identifier for the Mailchimp list to retrieve activity stats."],  # noqa: E501
    exclude_fields: Annotated[str | None, "Comma-separated list of fields to exclude. Use dot notation for sub-object parameters."] = None,  # noqa: E501
    include_fields: Annotated[str | None, "Comma-separated list of specific fields to include in the response, using dot notation for sub-objects."] = None,  # noqa: E501
    number_of_records_to_return: Annotated[str | None, "The number of records to return. Default is 10, maximum is 1000."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "The number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getListsIdActivity'."]:
    """Fetch daily detailed activity stats for a list in Mailchimp.

    Retrieve up to the previous 180 days of aggregated daily activity statistics for a specific list, excluding Automation activity."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/activity".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"count": number_of_records_to_return, "offset": pagination_offset, "fields": include_fields, "exclude_fields": exclude_fields}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_top_email_clients(
    context: ToolContext,
    list_unique_id: Annotated[str, "The unique identifier for the email list to retrieve client data from."],  # noqa: E501
    exclude_fields: Annotated[str | None, "Comma-separated list of fields to exclude from the response. Use dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to return. Use dot notation for sub-objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getListsIdClients'."]:
    """Retrieve the top email clients from a specific list.

    This tool retrieves a list of the top email clients based on user-agent strings for a specified list ID. It should be called when there's a need to analyze or report on the most popular email clients among subscribers of a particular list."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/clients".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_monthly_list_growth_summary(
    context: ToolContext,
    list_unique_id: Annotated[str, "The unique identifier for the specific list in Mailchimp. Required for retrieving growth activity."],  # noqa: E501
    exclude_fields_to_return: Annotated[str | None, "A comma-separated list of fields to exclude from the response, using dot notation for sub-objects."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "Number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
    records_to_return: Annotated[str | None, "Specify the number of records to return, with a default of 10 and a maximum of 1000."] = None,  # noqa: E501
    return_fields: Annotated[str | None, "A comma-separated list of specific fields to return. Use dot notation for sub-object parameters."] = None,  # noqa: E501
    sort_order_direction: Annotated[str | None, "Determines the sorting order for the results, either ascending or descending."] = None,  # noqa: E501
    sort_results_by_field: Annotated[str | None, "Specify the field by which results should be sorted. Use dot notation for sub-object fields."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getListsIdGrowthHistory'."]:
    """Retrieve monthly summary of a list's growth activity.

    Use this tool to get a detailed month-by-month summary of the growth activity for a specific list in Mailchimp. It provides insights into subscriber count changes over time."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/growth-history".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": return_fields, "exclude_fields": exclude_fields_to_return, "count": records_to_return, "offset": pagination_offset, "sort_field": sort_results_by_field, "sort_dir": sort_order_direction}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_list_growth_summary(
    context: ToolContext,
    list_unique_id: Annotated[str, "The unique ID for the specific list in Mailchimp."],
    specific_month_of_growth_history: Annotated[str, "Specify the month and year (in 'YYYY-MM' format) for retrieving the list's growth history."],  # noqa: E501
    exclude_fields_list: Annotated[str | None, "Comma-separated list of fields to exclude. Use dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "Comma-separated list of fields to return, using dot notation for sub-objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getListsIdGrowthHistoryId'."]:
    """Get a list's growth activity summary for a specific month and year.

    Use this tool to obtain a summary of the growth activity for a specific list in a given month and year on Mailchimp."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/growth-history/{month}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id, month=specific_month_of_growth_history),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields_list}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_list_interest_categories(
    context: ToolContext,
    list_id: Annotated[str, "The unique identifier for the mailing list you want to retrieve interest categories for."],  # noqa: E501
    exclude_fields_list: Annotated[str | None, "Comma-separated list of fields to exclude using dot notation for sub-objects. Helps reduce the size of the response by omitting unnecessary data."] = None,  # noqa: E501
    include_fields: Annotated[str | None, "A comma-separated list of fields to return. Use dot notation for sub-objects."] = None,  # noqa: E501
    interest_group_type: Annotated[str | None, "Specify the type of interest group to restrict results. Example: 'checkboxes', 'radio_buttons'."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "The number of records to skip for pagination. Default is 0. Use to manage pagination flow."] = None,  # noqa: E501
    record_count: Annotated[str | None, "The number of records to return. Specify a value from 10 to 1000. Defaults to 10 if not provided."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getListsIdInterestCategories'."]:
    """Retrieve interest categories for a specific mailing list.

    Use this tool to obtain detailed information about the interest categories associated with a specific mailing list in Mailchimp Marketing."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/interest-categories".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": include_fields, "exclude_fields": exclude_fields_list, "count": record_count, "offset": pagination_offset, "type": interest_group_type}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def create_interest_category(
    context: ToolContext,
    category_description: Annotated[str, "Text description of the interest category. Appears on signup forms, often phrased as a question."],  # noqa: E501
    category_display_type: Annotated[str, "Determines how the interest category appears on signup forms. Options include: 'checkboxes', 'dropdown', 'radio', or 'hidden'."],  # noqa: E501
    list_unique_id: Annotated[str, "The unique ID identifying the Mailchimp list where the interest category will be created."],  # noqa: E501
    category_display_order: Annotated[int | None, "The numerical order for displaying categories. Lower numbers appear first."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postListsIdInterestCategories'."]:
    """Create a new interest category in a Mailchimp list.

    This tool is used to create a new interest category for a specified Mailchimp list. It is useful when you want to categorize subscriber interests within a list."""  # noqa: E501
    request_data: Any = {"title": category_description, "display_order": category_display_order, "type": category_display_type}  # noqa: E501
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/interest-categories".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_interest_category_info(
    context: ToolContext,
    interest_category_unique_id: Annotated[str, "The unique ID for the interest category you want to retrieve information about."],  # noqa: E501
    list_unique_id: Annotated[str, "The unique ID for the Mailchimp list you want to retrieve interest category details from."],  # noqa: E501
    fields_to_exclude: Annotated[str | None, "Comma-separated list of fields to exclude, using dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "Comma-separated list of fields to include in the response, using dot notation for sub-objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getListsIdInterestCategoriesId'."]:
    """Fetch specific interest category details from a Mailchimp list.

    Use this tool to get detailed information about a specific interest category within a Mailchimp list. This is useful for understanding subscriber interests and organizing lists more effectively."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/interest-categories/{interest_category_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id, interest_category_id=interest_category_unique_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": fields_to_exclude}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def update_interest_category(
    context: ToolContext,
    category_display_type: Annotated[str, "Specifies how the category's interests are shown on signup forms. Options: 'checkboxes', 'dropdown', 'radio', 'hidden'."],  # noqa: E501
    interest_category_id: Annotated[str, "The unique ID for the interest category to be updated."],
    interest_category_title: Annotated[str, "The text description of this interest category for signup forms, often phrased as a question."],  # noqa: E501
    list_unique_id: Annotated[str, "The unique identifier for the Mailchimp list to be updated."],
    category_display_order: Annotated[int | None, "The numerical order for displaying the category. Lower numbers appear first."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'patchListsIdInterestCategoriesId'."]:  # noqa: E501
    """Update a specific interest category in Mailchimp.

    Use this tool to update the details of a specific interest category within a Mailchimp list. Ideal for modifying category information to better organize your audience."""  # noqa: E501
    request_data: Any = {"title": interest_category_title, "display_order": category_display_order, "type": category_display_type}  # noqa: E501
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/interest-categories/{interest_category_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id, interest_category_id=interest_category_id),  # noqa: E501  # noqa: UP032
        method="PATCH",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def delete_interest_category(
    context: ToolContext,
    interest_category_id: Annotated[str, "The unique ID of the interest category to be deleted from a list."],  # noqa: E501
    list_id: Annotated[str, "The unique ID for the Mailchimp list from which you want to delete an interest category."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteListsIdInterestCategoriesId'."]:  # noqa: E501
    """Delete a specific interest category from a list.

    Use this tool to delete a particular interest category from a specified list in Mailchimp. This might be called when managing email list segments and you need to remove an unwanted audience category."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/interest-categories/{interest_category_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_id, interest_category_id=interest_category_id),  # noqa: E501  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_interest_category_interests(
    context: ToolContext,
    interest_category_unique_id: Annotated[str, "The unique identifier for a specific interest category in a Mailchimp list."],  # noqa: E501
    list_unique_id: Annotated[str, "The unique ID for the Mailchimp list."],
    excluded_fields: Annotated[str | None, "Comma-separated list of fields to exclude, using dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "Comma-separated list of fields to return, using dot notation as needed."] = None,  # noqa: E501
    number_of_records_to_return: Annotated[str | None, "Specify the number of records to return, between 10 and 1000. Default is 10."] = None,  # noqa: E501
    pagination_skip_count: Annotated[str | None, "The number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getListsIdInterestCategoriesIdInterests'."]:  # noqa: E501
    """Retrieve interests for a specific category in Mailchimp.

    Use this tool to get a list of interests within a specific category of a Mailchimp list. It helps in understanding what options are available under a given interest category for targeted marketing strategies."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/interest-categories/{interest_category_id}/interests".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id, interest_category_id=interest_category_unique_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": excluded_fields, "count": number_of_records_to_return, "offset": pagination_skip_count}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def create_interest_group(
    context: ToolContext,
    interest_category_unique_id: Annotated[str, "The unique ID for the interest category to which the new group belongs."],  # noqa: E501
    interest_group_name: Annotated[str, "The name of the interest group, shown publicly on subscription forms."],  # noqa: E501
    list_unique_id: Annotated[str, "The unique ID for the Mailchimp list to which the interest group will be added."],  # noqa: E501
    interest_display_order: Annotated[int | None, "The order in which this interest is displayed relative to others. Use an integer value."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postListsIdInterestCategoriesIdInterests'."]:  # noqa: E501
    """Create a new interest group for a specific category.

    This tool is used to create a new interest or 'group name' within a specific interest category for a Mailchimp list. Use it when you need to organize and segment your list subscribers into specific interest groups."""  # noqa: E501
    request_data: Any = {"name": interest_group_name, "display_order": interest_display_order}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/interest-categories/{interest_category_id}/interests".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id, interest_category_id=interest_category_unique_id),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_interest_group_names(
    context: ToolContext,
    interest_category_id: Annotated[str, "The unique identifier for the interest category in a Mailchimp list."],  # noqa: E501
    list_unique_id: Annotated[str, "The unique identifier for the Mailchimp list to retrieve interest group names from."],  # noqa: E501
    specific_interest_group_name: Annotated[str, "The specific interest or group name to retrieve in the category."],  # noqa: E501
    exclude_fields: Annotated[str | None, "Comma-separated list of fields to exclude, using dot notation for sub-objects."] = None,  # noqa: E501
    include_fields: Annotated[str | None, "A comma-separated list of fields to return, using dot notation for sub-objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getListsIdInterestCategoriesIdInterestsId'."]:  # noqa: E501
    """Retrieve interest group names for a specific category.

    Use this tool to fetch interests or 'group names' associated with a specific category in a Mailchimp list. It is useful for managing or displaying group names to users."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/interest-categories/{interest_category_id}/interests/{interest_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id, interest_category_id=interest_category_id, interest_id=specific_interest_group_name),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": include_fields, "exclude_fields": exclude_fields}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def update_interest_group_name(
    context: ToolContext,
    interest_category_id: Annotated[str, "The unique ID for the interest category to be updated."],
    interest_group_name: Annotated[str, "The new name for the interest group, displayed publicly on subscription forms."],  # noqa: E501
    list_unique_id: Annotated[str, "The unique ID for the list to be updated."],
    specific_interest_id: Annotated[str, "The unique ID for the specific interest group name within the category."],  # noqa: E501
    interest_display_order: Annotated[int | None, "The numerical order in which the interest should appear in a list."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'patchListsIdInterestCategoriesIdInterestsId'."]:  # noqa: E501
    """Update group names in a specific interest category.

    Use this tool to update the names of interest groups within a specified category on a Mailchimp list. This is helpful for managing and organizing subscriber interests."""  # noqa: E501
    request_data: Any = {"name": interest_group_name, "display_order": interest_display_order}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/interest-categories/{interest_category_id}/interests/{interest_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id, interest_category_id=interest_category_id, interest_id=specific_interest_id),  # noqa: E501  # noqa: UP032
        method="PATCH",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def delete_interest_from_category(
    context: ToolContext,
    interest_category_id: Annotated[str, "The unique ID for the interest category to delete the interest from. This ID is essential to specify the correct category in Mailchimp."],  # noqa: E501
    interest_identifier: Annotated[str, "The unique identifier for the specific interest or group name to be deleted."],  # noqa: E501
    list_unique_id: Annotated[str, "The unique ID for the list to be targeted for deleting an interest."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteListsIdInterestCategoriesIdInterestsId'."]:  # noqa: E501
    """Delete an interest from a specific category.

    Use this tool to delete interests or group names within a specified category in Mailchimp. This is useful for managing interests in a mailing list."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/interest-categories/{interest_category_id}/interests/{interest_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id, interest_category_id=interest_category_id, interest_id=interest_identifier),  # noqa: E501  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_list_segments_info(
    context: ToolContext,
    list_identifier: Annotated[str, "The unique identifier for the mailing list whose segments are to be retrieved."],  # noqa: E501
    created_after_datetime: Annotated[str | None, "Restrict results to segments created after the specified time using ISO 8601 format (e.g., 2015-10-21T15:41:36+00:00)."] = None,  # noqa: E501
    exclude_fields: Annotated[str | None, "Comma-separated list of fields to exclude from the response. Use dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to return, using dot notation for sub-objects."] = None,  # noqa: E501
    include_cleaned_members: Annotated[str | None, "Set to 'true' to include cleaned (bounced) members in the response. Use this to see members who have been removed due to email issues."] = None,  # noqa: E501
    include_transactional_members: Annotated[str | None, "Specify whether to include transactional members in the response. Use 'true' or 'false'."] = None,  # noqa: E501
    include_unsubscribed_members: Annotated[str | None, "Set to 'true' to include unsubscribed members in the response."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "The number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
    records_count: Annotated[str | None, "The number of records to return. Default: 10. Max: 1000."] = None,  # noqa: E501
    restrict_since_updated_time: Annotated[str | None, "Restrict results to segments updated after this time using ISO 8601 format (e.g., 2015-10-21T15:41:36+00:00)."] = None,  # noqa: E501
    restrict_to_segments_created_before: Annotated[str | None, "Restrict results to segments created before the specified time. Use ISO 8601 format: 2015-10-21T15:41:36+00:00."] = None,  # noqa: E501
    restrict_to_segments_updated_before: Annotated[str | None, "Restrict results to segments updated before the specified time using ISO 8601 format (e.g., 2015-10-21T15:41:36+00:00)."] = None,  # noqa: E501
    segment_type: Annotated[str | None, "Specify the type of segment to filter results. Use known segment types as strings."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'previewASegment'."]:
    """Retrieve details of all segments for a specific list.

    Use this tool to get information about all available segments for a specific list in Mailchimp. It helps in understanding the segmentation structure of a mailing list."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/segments".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_identifier),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields, "count": records_count, "offset": pagination_offset, "type": segment_type, "since_created_at": created_after_datetime, "before_created_at": restrict_to_segments_created_before, "include_cleaned": include_cleaned_members, "include_transactional": include_transactional_members, "include_unsubscribed": include_unsubscribed_members, "since_updated_at": restrict_since_updated_time, "before_updated_at": restrict_to_segments_updated_before}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def create_mailchimp_segment(
    context: ToolContext,
    list_unique_id: Annotated[str, "The unique identifier for the Mailchimp list where the new segment will be created."],  # noqa: E501
    segment_name: Annotated[str, "The name of the segment to be created in Mailchimp."],
    emails_for_static_segment: Annotated[list[str] | None, "An array of emails for creating a static segment. An empty array means no subscribers. Cannot be used with 'options'."] = None,  # noqa: E501
    segment_match_conditions: Annotated[list[dict[str, str]] | None, "Array of conditions to define how the segment matches subscribers. Refer to the Mailchimp documentation for various condition types."] = None,  # noqa: E501
    segment_match_type: Annotated[str | None, "Specifies the match type for the segment conditions. Use 'any' to match any condition and 'all' to match all conditions."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postListsIdSegments'."]:
    """Create a new segment in a specific Mailchimp list.

    This tool is used to create a new segment within a specified Mailchimp list. It should be called when you need to categorize or target specific subsets of your mailing list for marketing purposes."""  # noqa: E501
    request_data: Any = {"name": segment_name, "static_segment": emails_for_static_segment, "options": {"match": segment_match_type, "conditions": segment_match_conditions}}  # noqa: E501
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/segments".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_segment_info(
    context: ToolContext,
    list_unique_id: Annotated[str, "The unique ID for the Mailchimp list to fetch segment information from."],  # noqa: E501
    segment_id: Annotated[str, "Provide the unique ID for the segment you want information on."],
    exclude_fields_list: Annotated[str | None, "Comma-separated list of fields to exclude, using dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "Comma-separated list of fields to return, using dot notation for sub-objects."] = None,  # noqa: E501
    include_cleaned_members: Annotated[str | None, "Set to 'true' to include cleaned members in the response. Cleaned members are those deleted due to bounce or other delivery issues."] = None,  # noqa: E501
    include_transactional_members: Annotated[str | None, "Set to 'true' to include transactional members in the response."] = None,  # noqa: E501
    include_unsubscribed_members: Annotated[str | None, "Set to 'true' to include unsubscribed members in the response."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getListsIdSegmentsId'."]:
    """Retrieve information about a specific Mailchimp segment.

    Use this tool to get detailed information about a specific segment in a Mailchimp list by providing the list and segment IDs."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/segments/{segment_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id, segment_id=segment_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields_list, "include_cleaned": include_cleaned_members, "include_transactional": include_transactional_members, "include_unsubscribed": include_unsubscribed_members}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def delete_specific_segment(
    context: ToolContext,
    list_unique_id: Annotated[str, "The unique ID for the Mailchimp list to target for segment deletion."],  # noqa: E501
    segment_unique_id: Annotated[str, "The unique identifier for the segment to be deleted. It must match the segment ID in Mailchimp."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteListsIdSegmentsId'."]:
    """Delete a specific segment from a Mailchimp list.

    Use this tool to delete a specific segment within a Mailchimp list by providing the list and segment IDs. This is useful for managing and organizing your email marketing lists."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/segments/{segment_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id, segment_id=segment_unique_id),  # noqa: E501  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def update_mailchimp_segment(
    context: ToolContext,
    list_unique_id: Annotated[str, "The unique ID for the list to update the segment in. This ID is required to identify the list containing the target segment."],  # noqa: E501
    segment_name: Annotated[str, "The new name for the segment to be updated."],
    segment_unique_id: Annotated[str, "The unique ID for the segment to update."],
    segment_conditions: Annotated[list[dict[str, str]] | None, "An array of conditions that define the segment criteria. Each condition should be a JSON object specifying the targeting parameters."] = None,  # noqa: E501
    segment_match_type: Annotated[str | None, "Determines if any or all conditions must be met for the segment. Allowed values: 'any', 'all'."] = None,  # noqa: E501
    static_email_list: Annotated[list[str] | None, "An array of emails for the static segment. Emails not on the list are ignored. An empty array resets the segment, removing all members. Cannot be used with 'options'."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'patchListsIdSegmentsId'."]:
    """Update the details of a specific segment in a Mailchimp list.

    This tool updates a specific segment within a designated list in Mailchimp. It should be called when there is a need to modify segment criteria or details in an existing list."""  # noqa: E501
    request_data: Any = {"name": segment_name, "static_segment": static_email_list, "options": {"match": segment_match_type, "conditions": segment_conditions}}  # noqa: E501
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/segments/{segment_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id, segment_id=segment_unique_id),  # noqa: E501  # noqa: UP032
        method="PATCH",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def update_list_segment(
    context: ToolContext,
    list_unique_id: Annotated[str, "The unique identifier for the Mailchimp list."],
    segment_unique_id: Annotated[str, "The unique ID of the segment in the Mailchimp list for member updates."],  # noqa: E501
    emails_to_add_to_segment: Annotated[list[str] | None, "An array of email addresses to add to the specified static segment. Only existing list emails will be added. Limit of 500."] = None,  # noqa: E501
    emails_to_remove_from_segment: Annotated[list[str] | None, "An array of up to 500 emails to remove from the static segment. Emails not in the list will be ignored."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postListsIdSegmentsId'."]:
    """Batch update members in a Mailchimp list segment.

    Use this tool to batch add or remove members in a specified static segment of a Mailchimp list. This is useful for efficiently managing segment membership within a list."""  # noqa: E501
    request_data: Any = {"members_to_add": emails_to_add_to_segment, "members_to_remove": emails_to_remove_from_segment}  # noqa: E501
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/segments/{segment_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id, segment_id=segment_unique_id),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_segment_members_info(
    context: ToolContext,
    list_identifier: Annotated[str, "The unique ID representing the mailing list from which the segment members will be retrieved. This ID is required to specify the context of the segment."],  # noqa: E501
    segment_unique_id: Annotated[str, "The unique ID for the segment to retrieve members from."],
    fields_to_exclude: Annotated[str | None, "Comma-separated list of fields to exclude using dot notation for sub-objects."] = None,  # noqa: E501
    include_cleaned_members: Annotated[str | None, "Specify 'true' to include cleaned (invalid or bounced) members in the response. Otherwise, specify 'false'."] = None,  # noqa: E501
    include_transactional_members: Annotated[str | None, "Set to true to include transactional members in the response."] = None,  # noqa: E501
    include_unsubscribed_members: Annotated[str | None, "Specify 'true' to include unsubscribed members in the response, 'false' to exclude them."] = None,  # noqa: E501
    included_fields: Annotated[str | None, "Comma-separated list of specific fields to return. Use dot notation for sub-object parameters."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "The number of records to skip for pagination purposes. Default is 0."] = None,  # noqa: E501
    records_to_return: Annotated[str | None, "The number of records to return. Default is 10; maximum is 1000."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getListsIdSegmentsIdMembers'."]:
    """Get information about members in a saved segment.

    Use this tool to retrieve information about members within a specified segment. It is useful when you need details on who is part of a particular saved segment in a mailing list."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/segments/{segment_id}/members".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_identifier, segment_id=segment_unique_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": included_fields, "exclude_fields": fields_to_exclude, "count": records_to_return, "offset": pagination_offset, "include_cleaned": include_cleaned_members, "include_transactional": include_transactional_members, "include_unsubscribed": include_unsubscribed_members}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def add_member_to_static_segment(
    context: ToolContext,
    list_unique_id: Annotated[str, "The unique ID for the Mailchimp list to which the segment belongs."],  # noqa: E501
    segment_id: Annotated[str, "The unique ID for the segment to which the member will be added."],
    subscriber_email_address: Annotated[str, "The email address of the subscriber to be added to the static segment."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postListsIdSegmentsIdMembers'."]:
    """Add a member to a Mailchimp static segment.

    Use this tool to add a new member to a specific static segment within a Mailchimp list. This is helpful for updating subscriber lists with targeted segments."""  # noqa: E501
    request_data: Any = {"email_address": subscriber_email_address}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/segments/{segment_id}/members".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id, segment_id=segment_id),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def remove_member_from_mailchimp_segment(
    context: ToolContext,
    email_md5_hash: Annotated[str, "The MD5 hash of the lowercase version of the list member's email address."],  # noqa: E501
    list_unique_id: Annotated[str, "The unique ID of the mailing list from which the member will be removed."],  # noqa: E501
    segment_unique_id: Annotated[str, "The unique identifier for the Mailchimp segment from which the member will be removed."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteListsIdSegmentsIdMembersId'."]:  # noqa: E501
    """Remove a member from a Mailchimp static segment.

    Use this tool to delete a member from a specific static segment in Mailchimp. It should be called when you need to manage segment memberships by removing a subscriber."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/segments/{segment_id}/members/{subscriber_hash}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id, segment_id=segment_unique_id, subscriber_hash=email_md5_hash),  # noqa: E501  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def search_tags_by_name(
    context: ToolContext,
    list_id: Annotated[str, "The unique identifier for a Mailchimp list. This is essential for specifying which list to search for tags."],  # noqa: E501
    tag_name_search_query: Annotated[str | None, "The prefix to filter tags by name. Returns tags where names start with this query."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'searchTagsByName'."]:
    """Search for tags on a list by name.

    Use this tool to find specific tags by name within a Mailchimp list. If no name is provided, it will return all tags on the list."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/tag-search".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"name": tag_name_search_query}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_mailchimp_list_members(
    context: ToolContext,
    list_unique_id: Annotated[str, "The unique ID for the Mailchimp list to retrieve member information from."],  # noqa: E501
    changed_after_timestamp: Annotated[str | None, "Restrict results to subscribers whose information changed after the specified timestamp in ISO 8601 format (e.g., 2015-10-21T15:41:36+00:00)."] = None,  # noqa: E501
    email_type: Annotated[str | None, "Specify the type of email format. Typically 'html' or 'text'."] = None,  # noqa: E501
    fields_to_exclude: Annotated[str | None, "Comma-separated list of fields to exclude from the response, using dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to return. Use dot notation for sub-object parameters."] = None,  # noqa: E501
    filter_by_interest_ids: Annotated[str | None, "Comma-separated list of interest IDs to filter list members. Must be combined with interest_category_id and interest_match."] = None,  # noqa: E501
    filter_by_since_last_campaign: Annotated[str | None, "Filter subscribers by their status (subscribed/unsubscribed/pending/cleaned) since the last email campaign. Requires member status."] = None,  # noqa: E501
    filter_unsubscribed_since: Annotated[str | None, "Filter subscribers who unsubscribed since a specific date. Must use 'unsubscribed' status only."] = None,  # noqa: E501
    filter_vip_members: Annotated[str | None, "Filter to return only VIP list members. Use `true` for VIPs only, `false` for all members."] = None,  # noqa: E501
    interest_category_id: Annotated[str | None, "The unique id for the interest category used to filter Mailchimp list members."] = None,  # noqa: E501
    interest_match_filter: Annotated[str | None, "Specify how to match list members by interests. Options: 'any', 'all', or 'none'. Must accompany interest_category_id and interest_ids."] = None,  # noqa: E501
    number_of_records_to_return: Annotated[str | None, "Specify the number of records to return, between 10 and 1000, default is 10."] = None,  # noqa: E501
    opt_in_after_timestamp: Annotated[str | None, "Restrict results to subscribers who opted-in after the specified timeframe in ISO 8601 format: 2015-10-21T15:41:36+00:00."] = None,  # noqa: E501
    opt_in_before_timestamp: Annotated[str | None, "Restrict results to subscribers who opted in before the specified timeframe. Use ISO 8601 format."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "The number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
    restrict_change_before_timeframe: Annotated[str | None, "Restrict results to subscribers whose information changed before the provided timeframe in ISO 8601 format (e.g., '2015-10-21T15:41:36+00:00')."] = None,  # noqa: E501
    sort_field_for_members: Annotated[str | None, "Specifies the field by which to sort the list members."] = None,  # noqa: E501
    sort_order_direction: Annotated[str | None, "Determines the order direction for sorted results. Common values are 'asc' for ascending and 'desc' for descending."] = None,  # noqa: E501
    subscriber_status: Annotated[str | None, "The status of the subscriber (e.g., subscribed, unsubscribed, cleaned, pending)."] = None,  # noqa: E501
    unique_email_identifier: Annotated[str | None, "A unique identifier for the email address across all Mailchimp lists. Use this to filter for a specific member."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getListsIdMembers'."]:
    """Retrieve member details from a specific Mailchimp list.

    Use this tool to get information about members within a specified Mailchimp list. It's useful for accessing subscriber details such as email addresses and subscription status."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/members".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": fields_to_exclude, "count": number_of_records_to_return, "offset": pagination_offset, "email_type": email_type, "status": subscriber_status, "since_timestamp_opt": opt_in_after_timestamp, "before_timestamp_opt": opt_in_before_timestamp, "since_last_changed": changed_after_timestamp, "before_last_changed": restrict_change_before_timeframe, "unique_email_id": unique_email_identifier, "vip_only": filter_vip_members, "interest_category_id": interest_category_id, "interest_ids": filter_by_interest_ids, "interest_match": interest_match_filter, "sort_field": sort_field_for_members, "sort_dir": sort_order_direction, "since_last_campaign": filter_by_since_last_campaign, "unsubscribed_since": filter_unsubscribed_since}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def add_member_to_mailchimp_list(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    list_unique_id: Annotated[str | None, "The unique ID for the Mailchimp list to which a new member will be added. This ID can be found in the Mailchimp account settings.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    bypass_merge_field_validation: Annotated[str | None, "Set to true to accept member data without required merge fields. Defaults to false.  Only used when mode is 'execute'."] = None,  # noqa: E501

    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postListsIdMembers'."]:
    """Add a new member to a Mailchimp list.

    Use this tool to add a new subscriber to a specific Mailchimp list. It should be called when you need to manage mailing lists by adding new contacts.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires path, query parameters.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.\n      Note: You must also provide the required path, query parameters when executing.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["ADDMEMBERTOMAILCHIMPLIST"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter along with the required path, query parameters. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters
    # Validate required parameters
    missing_params = []
    if not list_unique_id:
        missing_params.append(("list_unique_id", "path"))

    if missing_params:
        param_names = [p[0] for p in missing_params]
        param_details = ", ".join(
            [f"{p[0]} ({p[1]})" for p in missing_params]
        )
        raise RetryableToolError(
            message=f"Missing required parameters: {param_names}",
            developer_message=(
                f"Required parameters validation failed: {param_details}"
            ),
            additional_prompt_content=(
                f"The following required parameters are missing: "
                f"{param_details}. Please call this tool again with all "
                "required parameters."
            ),
        )


    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["ADDMEMBERTOMAILCHIMPLIST"] + "\n```"
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["ADDMEMBERTOMAILCHIMPLIST"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/lists/{list_id}/members".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id),  # noqa: E501  # noqa: UP032
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["ADDMEMBERTOMAILCHIMPLIST"],
        params=remove_none_values({"skip_merge_validation": bypass_merge_field_validation}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_list_member_info(
    context: ToolContext,
    list_id: Annotated[str, "The unique ID for the Mailchimp list to retrieve the member from."],
    member_identifier: Annotated[str, "The MD5 hash of the lowercase list member's email, or the email address/contact_id itself."],  # noqa: E501
    fields_to_exclude: Annotated[str | None, "A comma-separated list of fields to exclude from the response. Use dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "Comma-separated list of fields to return. Use dot notation for sub-object parameters."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getListsIdMembersId'."]:
    """Retrieve details about a specific list member in Mailchimp.

    Get information about a specific list member, including their subscription status and other details. Useful for tracking and managing member information in Mailchimp mailing lists."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/members/{subscriber_hash}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_id, subscriber_hash=member_identifier),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": fields_to_exclude}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def add_or_update_list_member(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    unique_list_id: Annotated[str | None, "The unique ID identifying the Mailchimp list where members are added or updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    subscriber_identifier: Annotated[str | None, "MD5 hash of the lowercase version of the member's email address, email address, or contact ID.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    bypass_merge_field_check: Annotated[str | None, "Set to true to allow member data without required merge fields. Defaults to false.  Only used when mode is 'execute'."] = None,  # noqa: E501

    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'putListsIdMembersId'."]:
    """Add or update a member in a Mailchimp list.

    Use this tool to add a new member to a specific Mailchimp list or update the information of an existing member. This is useful for managing list subscriptions effectively.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires path, query parameters.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.\n      Note: You must also provide the required path, query parameters when executing.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["ADDORUPDATELISTMEMBER"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter along with the required path, query parameters. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters
    # Validate required parameters
    missing_params = []
    if not unique_list_id:
        missing_params.append(("unique_list_id", "path"))
    if not subscriber_identifier:
        missing_params.append(("subscriber_identifier", "path"))

    if missing_params:
        param_names = [p[0] for p in missing_params]
        param_details = ", ".join(
            [f"{p[0]} ({p[1]})" for p in missing_params]
        )
        raise RetryableToolError(
            message=f"Missing required parameters: {param_names}",
            developer_message=(
                f"Required parameters validation failed: {param_details}"
            ),
            additional_prompt_content=(
                f"The following required parameters are missing: "
                f"{param_details}. Please call this tool again with all "
                "required parameters."
            ),
        )


    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["ADDORUPDATELISTMEMBER"] + "\n```"
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["ADDORUPDATELISTMEMBER"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/lists/{list_id}/members/{subscriber_hash}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=unique_list_id, subscriber_hash=subscriber_identifier),  # noqa: E501  # noqa: UP032
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["ADDORUPDATELISTMEMBER"],
        params=remove_none_values({"skip_merge_validation": bypass_merge_field_check}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def update_list_member_info(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    list_unique_id: Annotated[str | None, "The unique ID for the Mailchimp list. This ID identifies which list to update the member information in.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    member_identifier: Annotated[str | None, "The MD5 hash of the lowercase list member's email, email address, or contact_id.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    skip_merge_validation: Annotated[str | None, "Set to true to allow member data without merge field values, even if usually required. Defaults to false.  Only used when mode is 'execute'."] = None,  # noqa: E501

    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'patchListsIdMembersId'."]:
    """Update information for a specific list member in Mailchimp.

    Use this tool to update the details of a particular member on a Mailchimp list. It should be called when you need to modify any member's information, such as their email address or other personal details, within a given list.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires path, query parameters.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.\n      Note: You must also provide the required path, query parameters when executing.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["UPDATELISTMEMBERINFO"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter along with the required path, query parameters. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters
    # Validate required parameters
    missing_params = []
    if not list_unique_id:
        missing_params.append(("list_unique_id", "path"))
    if not member_identifier:
        missing_params.append(("member_identifier", "path"))

    if missing_params:
        param_names = [p[0] for p in missing_params]
        param_details = ", ".join(
            [f"{p[0]} ({p[1]})" for p in missing_params]
        )
        raise RetryableToolError(
            message=f"Missing required parameters: {param_names}",
            developer_message=(
                f"Required parameters validation failed: {param_details}"
            ),
            additional_prompt_content=(
                f"The following required parameters are missing: "
                f"{param_details}. Please call this tool again with all "
                "required parameters."
            ),
        )


    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["UPDATELISTMEMBERINFO"] + "\n```"
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["UPDATELISTMEMBERINFO"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/lists/{list_id}/members/{subscriber_hash}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id, subscriber_hash=member_identifier),  # noqa: E501  # noqa: UP032
        method="PATCH",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATELISTMEMBERINFO"],
        params=remove_none_values({"skip_merge_validation": skip_merge_validation}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def archive_list_member(
    context: ToolContext,
    mailing_list_id: Annotated[str, "The unique identifier for the specific Mailchimp list to archive a member from."],  # noqa: E501
    member_identifier: Annotated[str, "The MD5 hash of the lowercase version of the list member's email address, or use the email address/contact_id directly."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteListsIdMembersId'."]:
    """Archives a member from a Mailchimp list.

    Use this tool to archive a member from a specific Mailchimp list when they should no longer receive communications. Note that this is not a permanent deletion."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/members/{subscriber_hash}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=mailing_list_id, subscriber_hash=member_identifier),  # noqa: E501  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_member_activity(
    context: ToolContext,
    list_unique_id: Annotated[str, "The unique ID for the Mailchimp list you want to query."],
    member_identifier: Annotated[str, "MD5 hash of the lowercase email, email address, or contact ID of the list member."],  # noqa: E501
    actions_to_return: Annotated[str | None, "Comma-separated list of specific member actions to retrieve, such as opens, clicks, and unsubscribes."] = None,  # noqa: E501
    exclude_fields_from_activity: Annotated[str | None, "A comma-separated list of fields to exclude from the member activity response. Use dot notation for sub-objects."] = None,  # noqa: E501
    included_fields: Annotated[str | None, "Comma-separated list of specific fields to retrieve for member activity, using dot notation for sub-objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getListsIdMembersIdActivity'."]:
    """Retrieve recent email activity for a list member.

    Call this tool to get the last 50 activity events for a specific member on a Mailchimp list, including actions like opens, clicks, and unsubscribes."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/members/{subscriber_hash}/activity".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id, subscriber_hash=member_identifier),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": included_fields, "exclude_fields": exclude_fields_from_activity, "action": actions_to_return}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_member_activity_feed(
    context: ToolContext,
    list_unique_id: Annotated[str, "The unique ID for the Mailchimp list. Required to retrieve the member's activity data."],  # noqa: E501
    member_identifier: Annotated[str, "The MD5 hash of the lowercase version of the list member's email address, or the email address itself, or contact_id."],  # noqa: E501
    activity_type_filters: Annotated[str | None, "Comma-separated list of activity types to filter by, such as 'open', 'bounce', or 'click'."] = None,  # noqa: E501
    exclude_fields_from_response: Annotated[str | None, "Comma-separated list of fields to exclude from the response, use dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to include in the response. Use dot notation for sub-objects."] = None,  # noqa: E501
    number_of_records_to_return: Annotated[str | None, "The number of activity records to return. Default is 10, max is 1000."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "The number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getListsIdMembersIdActivityFeed'."]:
    """Fetch a Mailchimp list member's activity details.

    Use this tool to get a detailed record of a member's activities on a specific Mailchimp list, including email opens, link clicks, and unsubscribe actions."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/members/{subscriber_hash}/activity-feed".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id, subscriber_hash=member_identifier),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields_from_response, "count": number_of_records_to_return, "offset": pagination_offset, "activity_filters": activity_type_filters}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def retrieve_member_tags(
    context: ToolContext,
    list_unique_id: Annotated[str, "The unique identifier for the mailing list. Required to specify which list to retrieve member tags from."],  # noqa: E501
    member_identifier: Annotated[str, "The MD5 hash of the lowercase version of the email, or email address, or contact_id of the list member."],  # noqa: E501
    exclude_specific_fields: Annotated[str | None, "A comma-separated list of fields to exclude using dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to return. Use dot notation for sub-object parameters."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "The number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
    record_count: Annotated[str | None, "Specify the number of records to return, between 1 and 1000. Default is 10."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getListMemberTags'."]:
    """Fetches tags for a specific mailing list member.

    Use this tool to retrieve all tags associated with a specific member of a mailing list identified by their subscriber hash."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/members/{subscriber_hash}/tags".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id, subscriber_hash=member_identifier),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_specific_fields, "count": record_count, "offset": pagination_offset}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def update_list_member_tags(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    list_unique_id: Annotated[str | None, "The unique ID for the Mailchimp list to update tags for a member.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    subscriber_email_hash: Annotated[str | None, "The MD5 hash of the lowercase version of the list member's email address.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postListMemberTags'."]:
    """Add or remove tags from a Mailchimp list member.

    Use this tool to manage tags for a specific member in a Mailchimp list. It allows adding new tags or removing existing ones. If a non-existent tag is added and marked as 'active', it will be created automatically.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires path parameters.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.\n      Note: You must also provide the required path parameters when executing.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["UPDATELISTMEMBERTAGS"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter along with the required path parameters. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters
    # Validate required parameters
    missing_params = []
    if not list_unique_id:
        missing_params.append(("list_unique_id", "path"))
    if not subscriber_email_hash:
        missing_params.append(("subscriber_email_hash", "path"))

    if missing_params:
        param_names = [p[0] for p in missing_params]
        param_details = ", ".join(
            [f"{p[0]} ({p[1]})" for p in missing_params]
        )
        raise RetryableToolError(
            message=f"Missing required parameters: {param_names}",
            developer_message=(
                f"Required parameters validation failed: {param_details}"
            ),
            additional_prompt_content=(
                f"The following required parameters are missing: "
                f"{param_details}. Please call this tool again with all "
                "required parameters."
            ),
        )


    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["UPDATELISTMEMBERTAGS"] + "\n```"
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["UPDATELISTMEMBERTAGS"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/lists/{list_id}/members/{subscriber_hash}/tags".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id, subscriber_hash=subscriber_email_hash),  # noqa: E501  # noqa: UP032
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATELISTMEMBERTAGS"],
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def retrieve_contact_events(
    context: ToolContext,
    contact_identifier: Annotated[str, "The unique identifier for the list member. This can be the MD5 hash of the lowercase email address, the email address itself, or the contact ID."],  # noqa: E501
    list_unique_id: Annotated[str, "The unique identifier for the Mailchimp list from which to retrieve contact events."],  # noqa: E501
    exclude_fields: Annotated[str | None, "Comma-separated fields to exclude from the response using dot notation for sub-objects."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "The number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
    records_to_return_count: Annotated[str | None, "The number of records to return. Default is 10 and maximum is 1000."] = None,  # noqa: E501
    return_field_list: Annotated[str | None, "A comma-separated list of fields to return, using dot notation for sub-objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getListsIdMembersIdEvents'."]:
    """Retrieve events for a specific contact in a list.

    Use this tool to obtain detailed event information for a specific contact in a Mailchimp list. This is useful for tracking interactions or activities associated with a subscriber."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/members/{subscriber_hash}/events".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id, subscriber_hash=contact_identifier),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"count": records_to_return_count, "offset": pagination_offset, "fields": return_field_list, "exclude_fields": exclude_fields}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def add_list_member_event(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    list_identifier: Annotated[str | None, "The unique identifier for the Mailchimp list.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    list_member_identifier: Annotated[str | None, "The MD5 hash of the lowercase version of the list member's email address, or the email address/contact_id.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postListMemberEvents'."]:
    """Add an event for a list member in Mailchimp.

    This tool adds an event to a specific list member in Mailchimp. It should be called when you need to track a specific activity or event for a subscriber in a mailing list.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires path parameters.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.\n      Note: You must also provide the required path parameters when executing.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["ADDLISTMEMBEREVENT"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter along with the required path parameters. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters
    # Validate required parameters
    missing_params = []
    if not list_identifier:
        missing_params.append(("list_identifier", "path"))
    if not list_member_identifier:
        missing_params.append(("list_member_identifier", "path"))

    if missing_params:
        param_names = [p[0] for p in missing_params]
        param_details = ", ".join(
            [f"{p[0]} ({p[1]})" for p in missing_params]
        )
        raise RetryableToolError(
            message=f"Missing required parameters: {param_names}",
            developer_message=(
                f"Required parameters validation failed: {param_details}"
            ),
            additional_prompt_content=(
                f"The following required parameters are missing: "
                f"{param_details}. Please call this tool again with all "
                "required parameters."
            ),
        )


    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["ADDLISTMEMBEREVENT"] + "\n```"
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["ADDLISTMEMBEREVENT"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/lists/{list_id}/members/{subscriber_hash}/events".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_identifier, subscriber_hash=list_member_identifier),  # noqa: E501  # noqa: UP032
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["ADDLISTMEMBEREVENT"],
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_member_goal_events(
    context: ToolContext,
    list_unique_id: Annotated[str, "The unique identifier for the Mailchimp list. Required for fetching member goal events."],  # noqa: E501
    member_identifier: Annotated[str, "The MD5 hash of the lowercase version of the member's email, email address, or contact_id."],  # noqa: E501
    exclude_fields_list: Annotated[str | None, "Comma-separated list of fields to exclude, using dot notation for sub-objects."] = None,  # noqa: E501
    include_fields: Annotated[str | None, "Comma-separated list of specific fields to return, using dot notation for sub-objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getListsIdMembersIdGoals'."]:
    """Retrieve the last 50 goal events for a specific list member.

    Use this tool to get the most recent goal achievement events for a member within a particular Mailchimp list. This can be useful for tracking user engagement and performance metrics."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/members/{subscriber_hash}/goals".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id, subscriber_hash=member_identifier),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": include_fields, "exclude_fields": exclude_fields_list}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_member_notes(
    context: ToolContext,
    list_id: Annotated[str, "The unique ID of the Mailchimp list to retrieve notes for."],
    subscriber_hash: Annotated[str, "The MD5 hash of the lowercase version of the list member's email address. Used to identify the list member."],  # noqa: E501
    exclude_fields: Annotated[str | None, "Comma-separated list of fields to exclude using dot notation for sub-objects."] = None,  # noqa: E501
    include_fields: Annotated[str | None, "A comma-separated list of fields to include in the response. Use dot notation for sub-object parameters."] = None,  # noqa: E501
    number_of_records_to_return: Annotated[str | None, "Specify the number of member notes to return, between 1 and 1000. Default is 10."] = None,  # noqa: E501
    order_direction: Annotated[str | None, "Specifies the order direction for sorted note results. Accepts 'asc' or 'desc'."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "The number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
    sort_notes_by_field: Annotated[str | None, "Specify the field to sort the notes by, e.g., 'created_at' or 'updated_at'."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getListsIdMembersIdNotes'."]:
    """Retrieve recent notes for a Mailchimp list member.

    Use this tool to access the most recent notes associated with a specific member of a Mailchimp list, identified by their subscriber hash."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/members/{subscriber_hash}/notes".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_id, subscriber_hash=subscriber_hash),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"sort_field": sort_notes_by_field, "sort_dir": order_direction, "fields": include_fields, "exclude_fields": exclude_fields, "count": number_of_records_to_return, "offset": pagination_offset}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def add_note_to_subscriber(
    context: ToolContext,
    list_unique_id: Annotated[str, "The unique identifier for the Mailchimp list. This is required to add a note to a subscriber's profile in the specified list."],  # noqa: E501
    subscriber_email_hash: Annotated[str, "MD5 hash of the lowercase version of the subscriber's email address."],  # noqa: E501
    subscriber_note_content: Annotated[str | None, "The content of the note for a subscriber. It must be limited to 1,000 characters."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postListsIdMembersIdNotes'."]:
    """Add a new note for a specific subscriber in Mailchimp.

    Use this tool to add a note to a subscriber's profile in a specific list on Mailchimp. This is useful for keeping track of important information or interactions related to the subscriber."""  # noqa: E501
    request_data: Any = {"note": subscriber_note_content}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/members/{subscriber_hash}/notes".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id, subscriber_hash=subscriber_email_hash),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_list_member_note(
    context: ToolContext,
    list_unique_id: Annotated[str, "The unique identifier for the mailing list to retrieve a member's note from."],  # noqa: E501
    member_identifier: Annotated[str, "The MD5 hash of the lowercase email, the email address itself, or contact ID for a list member."],  # noqa: E501
    note_id: Annotated[str, "The unique identifier for the note associated with a list member."],
    exclude_fields: Annotated[str | None, "A comma-separated list of fields to exclude using dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to return, using dot notation for sub-objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getListsIdMembersIdNotesId'."]:
    """Retrieve a specific note for a list member.

    Use this tool to obtain details of a particular note associated with a member of a specific list. It's helpful for accessing specific interactions or annotations recorded for a list member."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/members/{subscriber_hash}/notes/{note_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id, subscriber_hash=member_identifier, note_id=note_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def update_member_note(
    context: ToolContext,
    list_unique_id: Annotated[str, "The unique ID for the mailing list where the note is being updated."],  # noqa: E501
    member_identifier: Annotated[str, "The MD5 hash, email address, or contact_id of the list member."],  # noqa: E501
    note_identifier: Annotated[str, "The unique identifier for the note to be updated."],
    note_content: Annotated[str | None, "Content of the note to be updated. Must not exceed 1,000 characters."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'patchListsIdMembersIdNotesId'."]:
    """Update a specific note for a list member in Mailchimp.

    This tool updates a specific note for a given list member on Mailchimp. Use this when you need to modify the content of an existing note associated with a subscriber in a mailing list."""  # noqa: E501
    request_data: Any = {"note": note_content}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/members/{subscriber_hash}/notes/{note_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id, subscriber_hash=member_identifier, note_id=note_identifier),  # noqa: E501  # noqa: UP032
        method="PATCH",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def delete_member_note(
    context: ToolContext,
    list_unique_id: Annotated[str, "The unique identifier for the list in which the member's note is to be deleted."],  # noqa: E501
    member_identifier: Annotated[str, "The MD5 hash of the member's email (in lowercase), the email itself, or contact_id for identifying list members."],  # noqa: E501
    note_id: Annotated[str, "The ID for the specific note you want to delete for a list member."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteListsIdMembersIdNotesId'."]:
    """Delete a specific note for a list member.

    Use this tool to delete a specific note associated with a list member in Mailchimp. It should be called when there is a need to remove a note from a contact's record in a specific list."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/members/{subscriber_hash}/notes/{note_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id, subscriber_hash=member_identifier, note_id=note_id),  # noqa: E501  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def delete_member_data_permanently(
    context: ToolContext,
    list_unique_id: Annotated[str, "The unique ID of the list from which the member will be deleted. This ID identifies the target list in Mailchimp."],  # noqa: E501
    member_email_hash: Annotated[str, "MD5 hash of the lowercase version of the member's email address."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postListsIdMembersHashActionsDeletePermanent'."]:  # noqa: E501
    """Permanently delete a list member's data in Mailchimp.

    This tool deletes all personally identifiable information related to a specific list member and removes them from the list, ensuring they cannot be re-imported."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/members/{subscriber_hash}/actions/delete-permanent".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id, subscriber_hash=member_email_hash),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_audience_merge_fields(
    context: ToolContext,
    audience_list_id: Annotated[str, "The unique ID for the audience list in Mailchimp."],
    exclude_fields_list: Annotated[str | None, "A comma-separated list of fields to exclude from the response. Use dot notation for sub-object fields."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "Comma-separated list of fields to return, using dot notation for sub-objects."] = None,  # noqa: E501
    is_required_merge_field: Annotated[str | None, "Indicates if the merge field is required. Pass 'true' or 'false'."] = None,  # noqa: E501
    merge_field_type: Annotated[str | None, "Specify the type of merge field to retrieve, such as 'text', 'number', etc."] = None,  # noqa: E501
    number_of_records_to_return: Annotated[str | None, "Specify the number of records to return, between 1 and 1000 (default is 10)."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "The number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getListsIdMergeFields'."]:
    """Get a list of all merge fields for an audience.

    Use this tool to retrieve all the merge fields associated with a specific audience in Mailchimp. This is useful for understanding the structure and data fields available within an audience."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/merge-fields".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=audience_list_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields_list, "count": number_of_records_to_return, "offset": pagination_offset, "type": merge_field_type, "required": is_required_merge_field}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def add_audience_merge_field(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    audience_list_id: Annotated[str | None, "The unique ID of the Mailchimp audience list to which the merge field will be added.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postListsIdMergeFields'."]:
    """Add a new merge field to a specific audience.

    This tool is used to add a new merge field for a specific audience in Mailchimp. It should be called when you need to enhance the audience profile with additional information fields.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires path parameters.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.\n      Note: You must also provide the required path parameters when executing.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["ADDAUDIENCEMERGEFIELD"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter along with the required path parameters. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters
    # Validate required parameters
    missing_params = []
    if not audience_list_id:
        missing_params.append(("audience_list_id", "path"))

    if missing_params:
        param_names = [p[0] for p in missing_params]
        param_details = ", ".join(
            [f"{p[0]} ({p[1]})" for p in missing_params]
        )
        raise RetryableToolError(
            message=f"Missing required parameters: {param_names}",
            developer_message=(
                f"Required parameters validation failed: {param_details}"
            ),
            additional_prompt_content=(
                f"The following required parameters are missing: "
                f"{param_details}. Please call this tool again with all "
                "required parameters."
            ),
        )


    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["ADDAUDIENCEMERGEFIELD"] + "\n```"
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["ADDAUDIENCEMERGEFIELD"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/lists/{list_id}/merge-fields".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=audience_list_id),  # noqa: E501  # noqa: UP032
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["ADDAUDIENCEMERGEFIELD"],
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_merge_field_info(
    context: ToolContext,
    list_id: Annotated[str, "The unique ID of the Mailchimp list to get merge field information from."],  # noqa: E501
    merge_field_id: Annotated[str, "The unique identifier for the merge field in the list."],
    exclude_merge_fields: Annotated[str | None, "Comma-separated list of fields to exclude using dot notation for sub-object parameters."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "Specify the fields to return, using comma-separated dot notation for nested fields."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getListsIdMergeFieldsId'."]:
    """Retrieve information about a specific merge field.

    Use this tool to obtain detailed information about a specific merge field in a Mailchimp list. It's useful for accessing customized data fields associated with members of email lists."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/merge-fields/{merge_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_id, merge_id=merge_field_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"exclude_fields": exclude_merge_fields, "fields": fields_to_return}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def update_merge_field(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    list_id: Annotated[str | None, "The unique ID for the list to update the merge field in.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    merge_field_id: Annotated[str | None, "The unique ID for the specific merge field to be updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'patchListsIdMergeFieldsId'."]:
    """Update a specific merge field in a list.

    This tool updates a specific merge field for a given list in Mailchimp. Use it when you need to modify the properties of a merge field, such as its name or type, within a specific list.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires path parameters.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.\n      Note: You must also provide the required path parameters when executing.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["UPDATEMERGEFIELD"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter along with the required path parameters. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters
    # Validate required parameters
    missing_params = []
    if not list_id:
        missing_params.append(("list_id", "path"))
    if not merge_field_id:
        missing_params.append(("merge_field_id", "path"))

    if missing_params:
        param_names = [p[0] for p in missing_params]
        param_details = ", ".join(
            [f"{p[0]} ({p[1]})" for p in missing_params]
        )
        raise RetryableToolError(
            message=f"Missing required parameters: {param_names}",
            developer_message=(
                f"Required parameters validation failed: {param_details}"
            ),
            additional_prompt_content=(
                f"The following required parameters are missing: "
                f"{param_details}. Please call this tool again with all "
                "required parameters."
            ),
        )


    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["UPDATEMERGEFIELD"] + "\n```"
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["UPDATEMERGEFIELD"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/lists/{list_id}/merge-fields/{merge_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_id, merge_id=merge_field_id),  # noqa: E501  # noqa: UP032
        method="PATCH",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEMERGEFIELD"],
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def delete_merge_field(
    context: ToolContext,
    list_unique_id: Annotated[str, "The unique ID for the Mailchimp list from which to delete the merge field."],  # noqa: E501
    merge_field_id: Annotated[str, "The ID for the merge field to delete from the Mailchimp list."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteListsIdMergeFieldsId'."]:
    """Delete a specific merge field from a Mailchimp list.

    Use this tool to remove a specific merge field from a Mailchimp list. This action is irreversible and will delete the specified merge field associated with the given list."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/merge-fields/{merge_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id, merge_id=merge_field_id),  # noqa: E501  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_list_webhooks_info(
    context: ToolContext,
    list_unique_identifier: Annotated[str, "The unique identifier for the mailing list to retrieve webhook information."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getListsIdWebhooks'."]:
    """Get information about all webhooks for a specific list.

    Use this tool to retrieve detailed information about all the webhooks associated with a specified mailing list. Ideal for managing or auditing webhook configurations."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/webhooks".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_identifier),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def create_mailchimp_webhook(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    mailchimp_list_id: Annotated[str | None, "The unique ID for the Mailchimp list for which the webhook will be created.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postListsIdWebhooks'."]:
    """Create a new webhook for a specific Mailchimp list.

    Use this tool to set up a new webhook for a designated list in Mailchimp, allowing automated event-driven notifications.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires path parameters.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.\n      Note: You must also provide the required path parameters when executing.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["CREATEMAILCHIMPWEBHOOK"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter along with the required path parameters. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters
    # Validate required parameters
    missing_params = []
    if not mailchimp_list_id:
        missing_params.append(("mailchimp_list_id", "path"))

    if missing_params:
        param_names = [p[0] for p in missing_params]
        param_details = ", ".join(
            [f"{p[0]} ({p[1]})" for p in missing_params]
        )
        raise RetryableToolError(
            message=f"Missing required parameters: {param_names}",
            developer_message=(
                f"Required parameters validation failed: {param_details}"
            ),
            additional_prompt_content=(
                f"The following required parameters are missing: "
                f"{param_details}. Please call this tool again with all "
                "required parameters."
            ),
        )


    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["CREATEMAILCHIMPWEBHOOK"] + "\n```"
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["CREATEMAILCHIMPWEBHOOK"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/lists/{list_id}/webhooks".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=mailchimp_list_id),  # noqa: E501  # noqa: UP032
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATEMAILCHIMPWEBHOOK"],
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_webhook_info(
    context: ToolContext,
    list_unique_id: Annotated[str, "The unique ID for the Mailchimp list to retrieve the webhook information."],  # noqa: E501
    webhook_id: Annotated[str, "Provide the unique ID of the webhook to retrieve its information."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getListsIdWebhooksId'."]:
    """Retrieve details of a specific Mailchimp webhook.

    Use this tool to get detailed information about a specific webhook in your Mailchimp list by providing the list and webhook IDs."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/webhooks/{webhook_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id, webhook_id=webhook_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def delete_mailchimp_webhook(
    context: ToolContext,
    list_id: Annotated[str, "The unique ID for the Mailchimp list from which the webhook will be deleted. This ID identifies the list containing the target webhook."],  # noqa: E501
    webhook_id: Annotated[str, "The unique identifier for the webhook to be deleted from the specified Mailchimp list."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteListsIdWebhooksId'."]:
    """Delete a specific webhook from a Mailchimp list.

    Use this tool to remove a webhook from a specified Mailchimp list by providing the list and webhook IDs."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/webhooks/{webhook_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_id, webhook_id=webhook_id),  # noqa: E501  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def update_webhook_settings(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    list_id: Annotated[str | None, "The unique identifier for the mailing list associated with the webhook.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    webhook_identifier: Annotated[str | None, "The unique identifier for the webhook to be updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'patchListsIdWebhooksId'."]:
    """Update the settings for an existing webhook.

    Use this tool to modify the configuration of a specific webhook linked to a mailing list. This is useful for changing how the webhook operates without creating a new one.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires path parameters.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.\n      Note: You must also provide the required path parameters when executing.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["UPDATEWEBHOOKSETTINGS"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter along with the required path parameters. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters
    # Validate required parameters
    missing_params = []
    if not list_id:
        missing_params.append(("list_id", "path"))
    if not webhook_identifier:
        missing_params.append(("webhook_identifier", "path"))

    if missing_params:
        param_names = [p[0] for p in missing_params]
        param_details = ", ".join(
            [f"{p[0]} ({p[1]})" for p in missing_params]
        )
        raise RetryableToolError(
            message=f"Missing required parameters: {param_names}",
            developer_message=(
                f"Required parameters validation failed: {param_details}"
            ),
            additional_prompt_content=(
                f"The following required parameters are missing: "
                f"{param_details}. Please call this tool again with all "
                "required parameters."
            ),
        )


    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["UPDATEWEBHOOKSETTINGS"] + "\n```"
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["UPDATEWEBHOOKSETTINGS"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/lists/{list_id}/webhooks/{webhook_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_id, webhook_id=webhook_identifier),  # noqa: E501  # noqa: UP032
        method="PATCH",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEWEBHOOKSETTINGS"],
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_list_signup_forms(
    context: ToolContext,
    list_unique_id: Annotated[str, "The unique ID of the Mailchimp list for retrieving signup forms."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getListsIdSignupForms'."]:
    """Retrieve signup forms for a Mailchimp list.

    Use this tool to fetch all signup forms associated with a specific Mailchimp list using the list ID."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/signup-forms".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def customize_list_signup_form(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    list_unique_id: Annotated[str | None, "The unique ID for the Mailchimp list to customize the signup form.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postListsIdSignupForms'."]:
    """Customize a list's default signup form in Mailchimp.

    Use this tool to modify the default signup form for a specific list in Mailchimp's marketing platform. Ideal for tailoring signup forms to better match branding or collect specific user information.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires path parameters.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.\n      Note: You must also provide the required path parameters when executing.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["CUSTOMIZELISTSIGNUPFORM"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter along with the required path parameters. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters
    # Validate required parameters
    missing_params = []
    if not list_unique_id:
        missing_params.append(("list_unique_id", "path"))

    if missing_params:
        param_names = [p[0] for p in missing_params]
        param_details = ", ".join(
            [f"{p[0]} ({p[1]})" for p in missing_params]
        )
        raise RetryableToolError(
            message=f"Missing required parameters: {param_names}",
            developer_message=(
                f"Required parameters validation failed: {param_details}"
            ),
            additional_prompt_content=(
                f"The following required parameters are missing: "
                f"{param_details}. Please call this tool again with all "
                "required parameters."
            ),
        )


    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["CUSTOMIZELISTSIGNUPFORM"] + "\n```"
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["CUSTOMIZELISTSIGNUPFORM"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/lists/{list_id}/signup-forms".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id),  # noqa: E501  # noqa: UP032
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CUSTOMIZELISTSIGNUPFORM"],
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_list_subscriber_locations(
    context: ToolContext,
    list_unique_id: Annotated[str, "The unique ID for the subscriber list in Mailchimp."],
    exclude_fields: Annotated[str | None, "Comma-separated list of fields to exclude using dot notation for sub-objects."] = None,  # noqa: E501
    include_fields: Annotated[str | None, "A comma-separated list of fields to include in the response. Use dot notation for sub-object parameters."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getListsIdLocations'."]:
    """Retrieve subscriber location data by list.

    Call this tool to get the countries associated with the subscribers of a specific list in Mailchimp, based on geocoded IP addresses."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/locations".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": include_fields, "exclude_fields": exclude_fields}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_list_surveys_info(
    context: ToolContext,
    list_unique_id: Annotated[str, "The unique identifier for the list to retrieve survey information. This ID is essential for specifying which list's surveys to access."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getListsIdSurveys'."]:
    """Retrieve information about surveys for a specific list.

    Call this tool to get information about all available surveys associated with a specific list in Mailchimp. Useful for managing and analyzing survey data linked to email lists."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/surveys".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_survey_details(
    context: ToolContext,
    list_unique_id: Annotated[str, "The unique identifier for the Mailchimp list associated with the survey."],  # noqa: E501
    survey_id: Annotated[str, "The unique ID of the survey to retrieve details for in Mailchimp."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getListsIdSurveysId'."]:
    """Retrieve details about a specific Mailchimp survey.

    Use this tool to gather detailed information about a particular survey associated with a specific list in Mailchimp. It is helpful for understanding survey content, status, and related data."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/surveys/{survey_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_unique_id, survey_id=survey_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def publish_mailchimp_survey(
    context: ToolContext,
    mailchimp_list_id: Annotated[str, "The unique ID for the Mailchimp list associated with the survey."],  # noqa: E501
    survey_id: Annotated[str, "The unique identifier of the survey to be published. Required for specifying which survey to publish."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postListsIdSurveysIdActionsPublish'."]:  # noqa: E501
    """Publishes a Mailchimp survey from draft to published status.

    Use this tool to publish a Mailchimp survey that is currently in draft, unpublished, or has been edited after previous publication. The tool confirms the survey's new status upon successful publishing."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/surveys/{survey_id}/actions/publish".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=mailchimp_list_id, survey_id=survey_id),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def unpublish_mailchimp_survey(
    context: ToolContext,
    mailchimp_list_id: Annotated[str, "The unique ID for the Mailchimp list associated with the survey to unpublish."],  # noqa: E501
    survey_id: Annotated[str, "Enter the unique ID of the survey to unpublish in Mailchimp."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postListsIdSurveysIdActionsUnpublish'."]:  # noqa: E501
    """Unpublish a survey in Mailchimp Marketing.

    Use this tool to unpublish a survey that has been published in Mailchimp Marketing. This action is useful when you need to deactivate a survey for any reason."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/surveys/{survey_id}/actions/unpublish".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=mailchimp_list_id, survey_id=survey_id),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def create_survey_campaign_email(
    context: ToolContext,
    list_identifier: Annotated[str, "The unique identifier for the email list."],
    survey_identifier: Annotated[str, "The unique identifier for the survey to link in the campaign email."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postListsIdSurveysIdActionsCreateEmail'."]:  # noqa: E501
    """Generate a campaign email linking to a survey.

    Use this tool to create an email campaign that includes a link to a given survey, using specified List ID and Survey ID."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/lists/{list_id}/surveys/{survey_id}/actions/create-email".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), list_id=list_identifier, survey_id=survey_identifier),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_all_landing_pages(
    context: ToolContext,
    exclude_fields_list: Annotated[str | None, "A comma-separated list of fields to exclude using dot notation for sub-objects."] = None,  # noqa: E501
    include_fields: Annotated[str | None, "Comma-separated list of fields to include in the response, using dot notation for nested fields."] = None,  # noqa: E501
    record_count: Annotated[str | None, "Specify the number of landing page records to return. Defaults to 10; maximum is 1000."] = None,  # noqa: E501
    sort_by_field: Annotated[str | None, "Specify the field by which the landing pages should be sorted."] = None,  # noqa: E501
    sort_direction: Annotated[str | None, "Specifies the order direction for sorting the results (e.g., ascending or descending)."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getAllLandingPages'."]:
    """Retrieve all landing pages from Mailchimp.

    Use this tool to obtain a comprehensive list of all landing pages available in your Mailchimp account. Useful for marketing analysis and content management."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/landing-pages".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"sort_dir": sort_direction, "sort_field": sort_by_field, "fields": include_fields, "exclude_fields": exclude_fields_list, "count": record_count}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def create_mailchimp_landing_page(
    context: ToolContext,
    enable_restricted_data_processing: Annotated[bool | None, "Enable restricted data processing under CCPA for tracking. True ensures compliance with CCPA."] = None,  # noqa: E501
    landing_page_description: Annotated[str | None, "Provide a description for the Mailchimp landing page."] = None,  # noqa: E501
    landing_page_name: Annotated[str | None, "The name of the landing page to be created."] = None,
    landing_page_template_id: Annotated[int | None, "The integer ID representing the template of the Mailchimp landing page."] = None,  # noqa: E501
    landing_page_template_type: Annotated[str | None, "Specifies the template type for the landing page. Options are 'signup' or 'product'."] = None,  # noqa: E501
    landing_page_title: Annotated[str | None, "The title that appears in the browser's title bar for the landing page."] = None,  # noqa: E501
    mailchimp_list_id: Annotated[str | None, "The ID of the Mailchimp list associated with the landing page."] = None,  # noqa: E501
    store_identifier: Annotated[str | None, "The unique identifier of the store linked to this landing page."] = None,  # noqa: E501
    track_with_mailchimp: Annotated[bool | None, "Set to true to use cookies for tracking unique visitors and calculating conversion rates."] = None,  # noqa: E501
    use_account_default_list: Annotated[str | None, "Set to 'true' to use the account's default list instead of specifying a list_id for the landing page."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postAllLandingPages'."]:
    """Create an unpublished Mailchimp landing page.

    This tool is used to create a new, unpublished landing page in Mailchimp without any content. It should be called when there's a need to set up a basic landing page framework in Mailchimp."""  # noqa: E501
    request_data: Any = {"name": landing_page_name, "title": landing_page_title, "description": landing_page_description, "store_id": store_identifier, "list_id": mailchimp_list_id, "type": landing_page_template_type, "template_id": landing_page_template_id, "tracking": {"track_with_mailchimp": track_with_mailchimp, "enable_restricted_data_processing": enable_restricted_data_processing}}  # noqa: E501
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/landing-pages".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({"use_default_list": use_account_default_list}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_landing_page_info(
    context: ToolContext,
    landing_page_id: Annotated[str, "The unique identifier for the landing page to retrieve information about."],  # noqa: E501
    exclude_fields_list: Annotated[str | None, "A comma-separated list of fields to exclude. Use dot notation for sub-object parameters."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to return. Use dot notation for sub-object parameters."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getLandingPageId'."]:
    """Retrieve information about a specific landing page by ID.

    This tool is used to fetch detailed information about a landing page using its ID. It should be called when you need to access the specifics of a given landing page."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/landing-pages/{page_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), page_id=landing_page_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields_list}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def update_landing_page(
    context: ToolContext,
    landing_page_id: Annotated[str, "The unique ID for the landing page to be updated."],
    enable_restricted_data_processing: Annotated[bool | None, "Set to true to enable Google’s restricted data processing in compliance with the CCPA for this landing page."] = None,  # noqa: E501
    enable_tracking_with_mailchimp: Annotated[bool | None, "Enable cookie tracking to monitor unique visitors and calculate conversion rates. More info: [here](https://mailchimp.com/help/use-track-mailchimp/)."] = None,  # noqa: E501
    landing_page_description: Annotated[str | None, "Provide a description for the landing page. This text summarizes the page's purpose and content."] = None,  # noqa: E501
    landing_page_name: Annotated[str | None, "The name for the landing page to be updated."] = None,
    landing_page_title: Annotated[str | None, "The title displayed in the browser's title bar for the landing page."] = None,  # noqa: E501
    list_id_for_landing_page: Annotated[str | None, "The ID of the list associated with this landing page."] = None,  # noqa: E501
    store_id: Annotated[str | None, "The ID of the store associated with this landing page. It must match an existing store in the Mailchimp account."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'patchLandingPageId'."]:
    """Update a landing page on Mailchimp.

    Use this tool to update an existing landing page on Mailchimp. Provide the necessary details for the landing page you wish to update."""  # noqa: E501
    request_data: Any = {"name": landing_page_name, "title": landing_page_title, "description": landing_page_description, "store_id": store_id, "list_id": list_id_for_landing_page, "tracking": {"track_with_mailchimp": enable_tracking_with_mailchimp, "enable_restricted_data_processing": enable_restricted_data_processing}}  # noqa: E501
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/landing-pages/{page_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), page_id=landing_page_id),  # noqa: E501  # noqa: UP032
        method="PATCH",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def delete_landing_page(
    context: ToolContext,
    landing_page_id: Annotated[str, "The unique ID for the landing page to be deleted."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteLandingPageId'."]:
    """Delete a specified landing page.

    Use this tool to delete a landing page by providing its ID. Ideal for managing or updating landing pages by removing outdated or unnecessary ones."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/landing-pages/{page_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), page_id=landing_page_id),  # noqa: E501  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def publish_landing_page(
    context: ToolContext,
    landing_page_id: Annotated[str, "The unique identifier for the landing page to publish."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postLandingPageIdActionsPublish'."]:
    """Publishes a landing page from draft or edited state.

    Use this tool to publish a landing page that is currently in draft, unpublished, or has been edited after a previous publication."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/landing-pages/{page_id}/actions/publish".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), page_id=landing_page_id),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def unpublish_landing_page(
    context: ToolContext,
    landing_page_id: Annotated[str, "The unique ID of the landing page to be unpublished. Required for identifying the specific page on Mailchimp."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postLandingPageIdActionsUnpublish'."]:  # noqa: E501
    """Unpublish a draft or published landing page.

    Used to unpublish a landing page that is currently in draft or has been published on Mailchimp. This can be useful for managing the visibility of a page."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/landing-pages/{page_id}/actions/unpublish".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), page_id=landing_page_id),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_landing_page_html(
    context: ToolContext,
    landing_page_id: Annotated[str, "The unique identifier for the Mailchimp landing page to retrieve."],  # noqa: E501
    exclude_fields_list: Annotated[str | None, "A comma-separated list of fields to exclude from the response using dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to return, using dot notation for nested objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getLandingPageIdContent'."]:
    """Retrieve the HTML content of a Mailchimp landing page.

"""
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/landing-pages/{page_id}/content".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), page_id=landing_page_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields_list}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_campaign_reports(
    context: ToolContext,
    campaign_type: Annotated[str | None, "Specify the type of campaign to retrieve reports for. Valid options are dependent on Mailchimp's supported campaign types."] = None,  # noqa: E501
    exclude_fields_list: Annotated[str | None, "A comma-separated list of fields to exclude from the report. Use dot notation for sub-objects."] = None,  # noqa: E501
    included_fields: Annotated[str | None, "Comma-separated list of fields to include in the response, using dot notation for sub-objects."] = None,  # noqa: E501
    number_of_records_to_return: Annotated[str | None, "Specify the number of records to return, ranging from 10 to 1000. Default is 10."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "The number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
    restrict_to_campaigns_sent_after: Annotated[str | None, "Restrict the response to campaigns sent after the specified ISO 8601 date and time."] = None,  # noqa: E501
    restrict_to_campaigns_sent_before: Annotated[str | None, "Restrict response to campaigns sent before this ISO 8601 time format (e.g., 2015-10-21T15:41:36+00:00)."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReports'."]:
    """Retrieve detailed campaign reports from Mailchimp.

    This tool retrieves campaign performance reports from Mailchimp Marketing. It should be called when detailed analytics about email campaigns are needed, such as open rates, click rates, and other metrics."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/reports".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": included_fields, "exclude_fields": exclude_fields_list, "count": number_of_records_to_return, "offset": pagination_offset, "type": campaign_type, "before_send_time": restrict_to_campaigns_sent_before, "since_send_time": restrict_to_campaigns_sent_after}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_campaign_report_details(
    context: ToolContext,
    campaign_unique_id: Annotated[str, "The unique ID for the campaign to retrieve its report details."],  # noqa: E501
    exclude_fields_list: Annotated[str | None, "Comma-separated list of fields to be excluded from the response. Use dot notation for sub-object references."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "Comma-separated list of fields to return. Use dot notation for sub-objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportsId'."]:
    """Retrieve detailed report for a specific sent campaign.

    Use this tool to access the report details of a specific campaign that has been sent. It provides insights and metrics for evaluating the campaign's performance."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/reports/{campaign_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_unique_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields_list}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_campaign_abuse_reports(
    context: ToolContext,
    campaign_unique_id: Annotated[str, "The unique identifier for the email marketing campaign to fetch abuse complaints."],  # noqa: E501
    exclude_fields: Annotated[str | None, "Comma-separated list of fields to exclude in the response using dot notation for sub-objects."] = None,  # noqa: E501
    include_fields: Annotated[str | None, "A comma-separated list of fields to include in the response. Use dot notation for nested fields."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportsIdAbuseReportsId'."]:
    """Get a list of abuse complaints for a specific campaign.

    Call this tool to retrieve and review all abuse complaints related to a particular email marketing campaign. Useful for tracking and managing issues with campaign recipients reporting spam or other abuses."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/reports/{campaign_id}/abuse-reports".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_unique_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": include_fields, "exclude_fields": exclude_fields}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_campaign_abuse_report_details(
    context: ToolContext,
    abuse_report_id: Annotated[str, "The unique identifier for the abuse report. This ID is necessary to retrieve the specific report details."],  # noqa: E501
    campaign_unique_id: Annotated[str, "The unique identifier for the campaign to fetch the abuse report details."],  # noqa: E501
    exclude_fields_list: Annotated[str | None, "A comma-separated list of fields to exclude from the response. Use dot notation for sub-objects."] = None,  # noqa: E501
    include_fields: Annotated[str | None, "A comma-separated list of fields to include in the response, using dot notation for sub-objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportsIdAbuseReportsIdId'."]:
    """Retrieve details of an abuse report for a campaign.

    Use this tool to get information about a specific abuse report related to a campaign. It should be called when detailed information about an abuse report is required for analysis or record-keeping."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/reports/{campaign_id}/abuse-reports/{report_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_unique_id, report_id=abuse_report_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": include_fields, "exclude_fields": exclude_fields_list}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_campaign_advice_feedback(
    context: ToolContext,
    campaign_id: Annotated[str, "The unique identifier for the campaign to get advice feedback on."],  # noqa: E501
    exclude_fields_to_return: Annotated[str | None, "A comma-separated list of fields to omit in the response. Use dot notation for sub-objects."] = None,  # noqa: E501
    include_fields: Annotated[str | None, "Comma-separated fields to include in the response. Use dot notation for sub-objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportsIdAdvice'."]:
    """Get feedback based on a campaign's performance data.

    This tool provides advice and feedback derived from various campaign statistics, such as open rates, click-through rates, unsubscribes, and bounces. Use it to gain insights into campaign effectiveness and areas for improvement."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/reports/{campaign_id}/advice".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": include_fields, "exclude_fields": exclude_fields_to_return}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_campaign_click_details(
    context: ToolContext,
    campaign_unique_id: Annotated[str, "The unique identifier for a specific Mailchimp campaign. Required to fetch corresponding click details."],  # noqa: E501
    fields_to_exclude: Annotated[str | None, "Comma-separated list of fields to exclude using dot notation for sub-objects."] = None,  # noqa: E501
    number_of_records_to_return: Annotated[str | None, "Specify the number of click records to return. The default is 10, and the maximum is 1000."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "Number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
    return_fields: Annotated[str | None, "A comma-separated list of fields to include in the response. Use dot notation for sub-objects."] = None,  # noqa: E501
    sort_by_field: Annotated[str | None, "Specify the field to sort click reports by, such as 'clicks', 'unique_clicks', or 'link_name'."] = None,  # noqa: E501
    sort_direction: Annotated[str | None, "Determines the order direction for sorted results, such as ascending or descending."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportsIdClickDetails'."]:
    """Get details about link clicks in Mailchimp campaigns.

    Use this tool to obtain detailed information about clicks on specific links in your Mailchimp marketing campaigns. It helps analyze the engagement by providing insights into which links were clicked and how often."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/reports/{campaign_id}/click-details".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_unique_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": return_fields, "exclude_fields": fields_to_exclude, "count": number_of_records_to_return, "offset": pagination_offset, "sort_field": sort_by_field, "sort_dir": sort_direction}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_campaign_link_click_details(
    context: ToolContext,
    campaign_unique_id: Annotated[str, "The unique identifier for the Mailchimp campaign to fetch link click details."],  # noqa: E501
    link_identifier: Annotated[str, "The unique identifier for the link whose click details are to be retrieved in the campaign report."],  # noqa: E501
    excluded_fields_list: Annotated[str | None, "A comma-separated list of fields to exclude from the response, using dot notation for sub-objects."] = None,  # noqa: E501
    include_fields: Annotated[str | None, "A comma-separated list of fields to return. Use dot notation for sub-objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportsIdClickDetailsId'."]:
    """Get click details for a specific campaign link.

    Fetch detailed click information for a specific link within a Mailchimp campaign report. Useful for analyzing link engagement."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/reports/{campaign_id}/click-details/{link_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_unique_id, link_id=link_identifier),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": include_fields, "exclude_fields": excluded_fields_list}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def fetch_click_details_for_campaign(
    context: ToolContext,
    campaign_id: Annotated[str, "A unique identifier for the email marketing campaign to retrieve click details."],  # noqa: E501
    link_identifier: Annotated[str, "The unique identifier for the specific link in the campaign. This ID is used to retrieve details of list members who clicked the link."],  # noqa: E501
    exclude_fields_list: Annotated[str | None, "A comma-separated list of fields to exclude from the response. Use dot notation for sub-object parameters."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to include in the response. Use dot notation for nested fields."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "The number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
    record_count: Annotated[str | None, "The number of member records to return. Default is 10 and the maximum is 1000."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportsIdClickDetailsIdMembers'."]:  # noqa: E501
    """Retrieve details on members who clicked a specific campaign link.

    This tool retrieves information about list members who clicked on a specific link in an email marketing campaign. It should be called when you need insights into which members interacted with a particular link within a campaign."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/reports/{campaign_id}/click-details/{link_id}/members".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_id, link_id=link_identifier),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields_list, "count": record_count, "offset": pagination_offset}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_subscriber_click_details(
    context: ToolContext,
    campaign_id: Annotated[str, "The unique identifier for the campaign to get subscriber click details."],  # noqa: E501
    link_identifier: Annotated[str, "The unique ID for the link clicked within a campaign. Use to specify which link's click details to retrieve."],  # noqa: E501
    subscriber_email_hash: Annotated[str, "The MD5 hash of the lowercase version of the subscriber's email address."],  # noqa: E501
    exclude_fields_list: Annotated[str | None, "Comma-separated list of fields to exclude from the result, using dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of specific fields to include in the response. Use dot notation for nested objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportsIdClickDetailsIdMembersId'."]:  # noqa: E501
    """Retrieve details of a subscriber's link click in a campaign.

    This tool fetches information about a specific subscriber who clicked a link within a specific campaign in Mailchimp. It should be called when you need to analyze subscriber engagement by retrieving who clicked on which links in a campaign."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/reports/{campaign_id}/click-details/{link_id}/members/{subscriber_hash}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_id, link_id=link_identifier, subscriber_hash=subscriber_email_hash),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields_list}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_campaign_open_details(
    context: ToolContext,
    campaign_unique_id: Annotated[str, "The unique identifier for the campaign. Required to retrieve open details for specific campaign emails."],  # noqa: E501
    exclude_fields_to_return: Annotated[str | None, "Comma-separated fields to exclude from the response. Use dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to return, using dot notation for sub-objects."] = None,  # noqa: E501
    number_of_records_to_return: Annotated[str | None, "Specify the number of records to return. Default is 10, maximum is 1000."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "The number of records from the collection to skip for pagination. Default is 0."] = None,  # noqa: E501
    sort_by_field: Annotated[str | None, "Specify the field by which to sort the open reports. Choose from available fields to determine the order of results."] = None,  # noqa: E501
    sort_order_direction: Annotated[str | None, "Specify the order direction for sorted results. Use 'asc' for ascending or 'desc' for descending."] = None,  # noqa: E501
    start_date_time_for_campaign_open_events: Annotated[str | None, "Restrict results to campaign open events that occur after this date and time in ISO 8601 format (e.g., 2015-10-21T15:41:36+00:00)."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportsIdOpenDetails'."]:
    """Get details on opened campaign emails by list members.

    Use this tool to retrieve detailed information about emails from a specific campaign that were opened by list members. Ideal for understanding engagement and assessing campaign performance."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/reports/{campaign_id}/open-details".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_unique_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields_to_return, "count": number_of_records_to_return, "offset": pagination_offset, "since": start_date_time_for_campaign_open_events, "sort_field": sort_by_field, "sort_dir": sort_order_direction}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_campaign_subscriber_open_details(
    context: ToolContext,
    campaign_unique_id: Annotated[str, "The unique identifier for the campaign to retrieve subscriber open details."],  # noqa: E501
    subscriber_email_hash: Annotated[str, "The MD5 hash of the lowercase version of the subscriber's email address."],  # noqa: E501
    exclude_fields_from_response: Annotated[str | None, "A comma-separated list of fields to exclude from the response, using dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to return for the subscriber's open details. Use dot notation for sub-object fields."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportsIdOpenDetailsIdMembersId'."]:  # noqa: E501
    """Retrieve details of a subscriber who opened a campaign.

    This tool fetches information about a specific subscriber who opened a given email campaign. It is useful for tracking engagement and understanding subscriber behavior in email marketing campaigns."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/reports/{campaign_id}/open-details/{subscriber_hash}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_unique_id, subscriber_hash=subscriber_email_hash),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields_from_response}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_campaign_domain_performance(
    context: ToolContext,
    campaign_unique_id: Annotated[str, "The unique identifier for the email campaign to retrieve domain performance statistics."],  # noqa: E501
    exclude_fields_from_report: Annotated[str | None, "Comma-separated list of fields to exclude from the report, using dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to return in the response. Use dot notation for sub-object parameters."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportsIdDomainPerformance'."]:
    """Get top domain performance for an email campaign.

    Retrieve statistics on how email domains have performed in a specific campaign using the campaign ID."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/reports/{campaign_id}/domain-performance".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_unique_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields_from_report}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_campaign_social_activity(
    context: ToolContext,
    campaign_unique_id: Annotated[str, "The unique id for the campaign to retrieve its social activity summary."],  # noqa: E501
    fields_to_exclude: Annotated[str | None, "Comma-separated list of fields to exclude from the response. Use dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to include in the response, using dot notation for sub-object parameters."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportsIdEepurl'."]:
    """Get social activity summary for a campaign using EepURL.

    Use this tool to retrieve a summary of social activity tracked by EepURL for a specific campaign in Mailchimp."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/reports/{campaign_id}/eepurl".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_unique_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": fields_to_exclude}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def retrieve_campaign_subscriber_activity(
    context: ToolContext,
    campaign_unique_id: Annotated[str, "The unique identifier for a specific email campaign."],
    activity_since_timestamp: Annotated[str | None, "Restrict results to email activity events occurring after this timestamp, using ISO 8601 format."] = None,  # noqa: E501
    fields_to_exclude: Annotated[str | None, "Comma-separated list of fields to exclude from the response. Use dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to include in the response. Use dot notation for sub-object fields."] = None,  # noqa: E501
    number_of_records_to_return: Annotated[str | None, "Specifies how many records to return. The default is 10, with a maximum of 1000."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "The number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportsIdEmailActivity'."]:
    """Retrieve subscriber activity for a specific campaign.

    Use this tool to get a list of subscriber activities for a particular email campaign in Mailchimp. It provides information on how subscribers interacted with the campaign emails."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/reports/{campaign_id}/email-activity".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_unique_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": fields_to_exclude, "count": number_of_records_to_return, "offset": pagination_offset, "since": activity_since_timestamp}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_campaign_email_activity(
    context: ToolContext,
    campaign_unique_id: Annotated[str, "The unique identifier for the campaign whose member activity is being retrieved."],  # noqa: E501
    subscriber_hash: Annotated[str, "The MD5 hash of the lowercase version of the list member's email address for which you want to retrieve activity."],  # noqa: E501
    fields_to_exclude: Annotated[str | None, "A comma-separated list of fields to exclude from the response using dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "Comma-separated list of fields to return, using dot notation for sub-objects."] = None,  # noqa: E501
    restrict_activity_since: Annotated[str | None, "Restrict results to email activity events occurring after this time (ISO 8601 format)."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportsIdEmailActivityId'."]:
    """Retrieve specific list member's activity in a campaign.

    Get detailed information on a list member's activity in a campaign, including opens, clicks, and bounces, by providing the campaign ID and subscriber hash."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/reports/{campaign_id}/email-activity/{subscriber_hash}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_unique_id, subscriber_hash=subscriber_hash),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": fields_to_exclude, "since": restrict_activity_since}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def fetch_campaign_open_locations(
    context: ToolContext,
    campaign_unique_id: Annotated[str, "The unique identifier for the specific marketing campaign."],  # noqa: E501
    fields_to_exclude: Annotated[str | None, "A comma-separated list of fields to exclude. Use dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to include in the response. Use dot notation for sub-objects."] = None,  # noqa: E501
    number_of_records: Annotated[str | None, "Specify the number of location records to return. Default is 10, maximum is 1000."] = None,  # noqa: E501
    records_to_skip: Annotated[str | None, "Number of records to skip for pagination purposes. Default is 0."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportsIdLocations'."]:
    """Retrieve top open locations for a specific campaign.

    Use this tool to obtain the top geographical locations where a marketing campaign was opened. This can help in analyzing the reach and engagement of the campaign in different regions."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/reports/{campaign_id}/locations".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_unique_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": fields_to_exclude, "count": number_of_records, "offset": records_to_skip}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_campaign_recipients(
    context: ToolContext,
    campaign_unique_identifier: Annotated[str, "The unique identifier for the specific campaign whose recipients you want to retrieve."],  # noqa: E501
    fields_to_exclude: Annotated[str | None, "A comma-separated list of fields to exclude, using dot notation for sub-objects."] = None,  # noqa: E501
    include_fields: Annotated[str | None, "Comma-separated list of fields to return, using dot notation for sub-objects."] = None,  # noqa: E501
    number_of_records_to_return: Annotated[str | None, "Specify the number of recipient records to return, between 1 and 1000. Default is 10."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "Number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportsIdSentTo'."]:
    """Retrieve information about campaign recipients.

    Use this tool to obtain detailed information about recipients of a specific marketing campaign. It provides insights into who received the campaign."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/reports/{campaign_id}/sent-to".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_unique_identifier),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": include_fields, "exclude_fields": fields_to_exclude, "count": number_of_records_to_return, "offset": pagination_offset}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_campaign_recipient_info(
    context: ToolContext,
    campaign_unique_id: Annotated[str, "The unique ID for the campaign for which recipient information is requested. It should be in string format and is required to identify the specific campaign."],  # noqa: E501
    recipient_subscriber_hash: Annotated[str, "MD5 hash of the lowercase version of the recipient's email address."],  # noqa: E501
    excluded_fields: Annotated[str | None, "A comma-separated list of fields to exclude. Use dot notation for sub-object parameters."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "Comma-separated fields to include in the response, using dot notation for sub-objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportsIdSentToId'."]:
    """Get information about a specific campaign recipient.

    Use this tool to retrieve details about a particular recipient of a Mailchimp marketing campaign. Provide the campaign ID and subscriber hash to access the information."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/reports/{campaign_id}/sent-to/{subscriber_hash}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_unique_id, subscriber_hash=recipient_subscriber_hash),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": excluded_fields}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_campaign_sub_reports(
    context: ToolContext,
    campaign_unique_id: Annotated[str, "The unique ID of the parent campaign to retrieve sub-reports for."],  # noqa: E501
    fields_to_exclude: Annotated[str | None, "A comma-separated list of fields to exclude. Use dot notation for sub-object parameters."] = None,  # noqa: E501
    return_fields: Annotated[str | None, "Comma-separated list of fields to return, using dot notation for sub-objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportsIdSubReportsId'."]:
    """Retrieve sub-reports of a specific parent campaign.

    Use this tool to get the reports of child campaigns associated with a particular parent campaign in Mailchimp. Useful for analyzing the performance of linked campaigns."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/reports/{campaign_id}/sub-reports".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_unique_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": return_fields, "exclude_fields": fields_to_exclude}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_unsubscribed_campaign_members(
    context: ToolContext,
    campaign_unique_id: Annotated[str, "The unique identifier for the marketing campaign to retrieve unsubscribed members information."],  # noqa: E501
    exclude_fields_list: Annotated[str | None, "Comma-separated list of fields to exclude using dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to include in the response, using dot notation for sub-objects."] = None,  # noqa: E501
    number_of_records_to_return: Annotated[str | None, "Specify the number of records to return. Default is 10 and maximum is 1000."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "The number of records to skip for pagination, with a default value of 0."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportsIdUnsubscribed'."]:
    """Get details of members unsubscribed from a specific campaign.

    Use this tool to retrieve detailed information about members who have unsubscribed from a specified marketing campaign."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/reports/{campaign_id}/unsubscribed".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_unique_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields_list, "count": number_of_records_to_return, "offset": pagination_offset}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_unsubscribed_member_info(
    context: ToolContext,
    campaign_unique_id: Annotated[str, "The unique identifier for the Mailchimp campaign."],
    subscriber_email_hash: Annotated[str, "The MD5 hash of the lowercase version of the list member's email address for identification."],  # noqa: E501
    exclude_fields_list: Annotated[str | None, "A list of fields to exclude, using dot notation for sub-objects."] = None,  # noqa: E501
    include_fields: Annotated[str | None, "Specify which fields to return, using a comma-separated list with dot notation for sub-objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportsIdUnsubscribedId'."]:
    """Retrieve info on an unsubscribed list member from a campaign.

    Use this tool to get information about a specific list member who has unsubscribed from a campaign in Mailchimp."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/reports/{campaign_id}/unsubscribed/{subscriber_hash}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_unique_id, subscriber_hash=subscriber_email_hash),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": include_fields, "exclude_fields": exclude_fields_list}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_campaign_product_activity(
    context: ToolContext,
    campaign_unique_id: Annotated[str, "The unique identifier for the campaign whose product activity is being retrieved."],  # noqa: E501
    exclude_fields_from_response: Annotated[str | None, "A comma-separated list of fields to exclude from the response. Use dot notation for sub-objects."] = None,  # noqa: E501
    include_fields: Annotated[str | None, "Comma-separated list of fields to return, using dot notation for sub-objects."] = None,  # noqa: E501
    number_of_records_to_return: Annotated[str | None, "The number of records to return, between 1 and 1000. Defaults to 10."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "Number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
    sort_results_by_field: Annotated[str | None, "Specify the field by which to sort the product activity results. Use dot notation for sub-object fields."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportsIdEcommerceProductActivity'."]:  # noqa: E501
    """Get breakdown of product activity for a campaign.

    This tool retrieves the breakdown of product activity related to a specific marketing campaign from Mailchimp. It should be called when detailed ecommerce product performance data for a campaign is needed."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/reports/{campaign_id}/ecommerce-product-activity".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), campaign_id=campaign_unique_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": include_fields, "exclude_fields": exclude_fields_from_response, "count": number_of_records_to_return, "offset": pagination_offset, "sort_field": sort_results_by_field}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_available_templates(
    context: ToolContext,
    created_after_date: Annotated[str | None, "Retrieve templates created after a specific date. Use ISO 8601 format (e.g., 2015-10-21T15:41:36+00:00)."] = None,  # noqa: E501
    exclude_fields_list: Annotated[str | None, "Comma-separated fields to exclude from the response, using dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "Comma-separated list of fields to include in the response, using dot notation for sub-objects."] = None,  # noqa: E501
    filter_by_category: Annotated[str | None, "Limit the results to templates that match a specific category."] = None,  # noqa: E501
    number_of_records_to_return: Annotated[str | None, "Specify the number of template records to return (1-1000). Default is 10."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "Number of records to skip for pagination. Default is 0. Use for paginated responses."] = None,  # noqa: E501
    restrict_before_date_created: Annotated[str | None, "Restrict the response to templates created before the specified date in ISO 8601 format. For example: 2015-10-21T15:41:36+00:00."] = None,  # noqa: E501
    sort_order_direction: Annotated[str | None, "Specify the order direction for sorted results ('asc' for ascending, 'desc' for descending)."] = None,  # noqa: E501
    sort_templates_by_field: Annotated[str | None, "Specify the field to sort templates by. Determines the sorting order of returned templates."] = None,  # noqa: E501
    template_content_type: Annotated[str | None, "Filter templates based on content structure. Use 'template' for legacy, 'multichannel' for new editor, or 'html' for code your own."] = None,  # noqa: E501
    template_creator_user: Annotated[str | None, "Specify the Mailchimp account user who created the template to filter results."] = None,  # noqa: E501
    template_folder_id: Annotated[str | None, "The unique ID for the folder containing templates to retrieve."] = None,  # noqa: E501
    template_type: Annotated[str | None, "Specify the template type to limit the results. This filters the email templates based on their type."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getTemplates'."]:
    """Retrieve a list of available email templates.

    Fetches and returns a list of all the email templates available in a Mailchimp account. Useful for managing and selecting templates for campaigns."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/templates".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields_list, "count": number_of_records_to_return, "offset": pagination_offset, "created_by": template_creator_user, "since_date_created": created_after_date, "before_date_created": restrict_before_date_created, "type": template_type, "category": filter_by_category, "folder_id": template_folder_id, "sort_field": sort_templates_by_field, "content_type": template_content_type, "sort_dir": sort_order_direction}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def create_mailchimp_template(
    context: ToolContext,
    template_html_content: Annotated[str, "The raw HTML content for the template, supporting Mailchimp Template Language."],  # noqa: E501
    template_name: Annotated[str, "The name assigned to the new template. It should be descriptive for easy identification."],  # noqa: E501
    template_folder_id: Annotated[str | None, "The ID of the folder where the template will be stored. Ensure the folder exists in the Mailchimp account."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postTemplates'."]:
    """Create a new Classic template in Mailchimp.

    This tool is used to create a new Classic template in a Mailchimp account. It should be called when a user wants to add a new email template for marketing purposes."""  # noqa: E501
    request_data: Any = {"name": template_name, "folder_id": template_folder_id, "html": template_html_content}  # noqa: E501
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/templates".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_mailchimp_template_info(
    context: ToolContext,
    template_id: Annotated[str, "The unique identifier for the Mailchimp template to retrieve information about."],  # noqa: E501
    fields_to_exclude: Annotated[str | None, "Comma-separated list of fields to exclude from the response. Use dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "Specify a comma-separated list of fields to include in the response. Use dot notation for sub-object parameters."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getTemplatesId'."]:
    """Retrieves detailed information about a specific Mailchimp template.

    Use this tool to obtain information about a particular template in Mailchimp by providing the template ID. It is useful for retrieving template details when managing email marketing campaigns."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/templates/{template_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), template_id=template_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": fields_to_exclude}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def update_email_template(
    context: ToolContext,
    template_html_content: Annotated[str, "The raw HTML for the template using Mailchimp's Template Language."],  # noqa: E501
    template_name: Annotated[str, "The name of the email template to update."],
    template_unique_id: Annotated[str, "The unique identifier for the email template to be updated."],  # noqa: E501
    destination_folder_id: Annotated[str | None, "The ID of the folder where the template is currently located."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'patchTemplatesId'."]:
    """Update the details of an existing email template.

    Use this tool to update the name, HTML content, or folder ID of an existing email template in Mailchimp."""  # noqa: E501
    request_data: Any = {"name": template_name, "folder_id": destination_folder_id, "html": template_html_content}  # noqa: E501
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/templates/{template_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), template_id=template_unique_id),  # noqa: E501  # noqa: UP032
        method="PATCH",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def delete_email_template(
    context: ToolContext,
    template_unique_id: Annotated[str, "The unique identifier for the email template to be deleted in Mailchimp."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteTemplatesId'."]:
    """Delete a specific email template in Mailchimp.

"""
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/templates/{template_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), template_id=template_unique_id),  # noqa: E501  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_template_editable_sections(
    context: ToolContext,
    template_unique_id: Annotated[str, "The unique identifier for the Mailchimp template to retrieve editable sections."],  # noqa: E501
    exclude_fields_list: Annotated[str | None, "A comma-separated list of fields to exclude, using dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "Comma-separated list of fields to include in the response. Use dot notation for sub-objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getTemplatesIdDefaultContent'."]:
    """Retrieve editable sections and default content of a template.

    Use this tool to get the sections you can edit in a Mailchimp template, along with each section's default content. It is helpful for understanding which parts of a template can be customized."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/templates/{template_id}/default-content".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), template_id=template_unique_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields_list}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_account_orders(
    context: ToolContext,
    exclude_order_fields: Annotated[str | None, "Comma-separated list of fields to exclude, using dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "Comma-separated list of fields to return. Use dot notation for sub-object parameters."] = None,  # noqa: E501
    filter_by_outreach_id: Annotated[str | None, "Return orders associated with the specified outreach_id."] = None,  # noqa: E501
    number_of_records_to_return: Annotated[str | None, "Specify the number of order records to return. Default is 10, maximum is 1000."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "The number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
    restrict_to_campaign_id: Annotated[str | None, "Restrict results to orders with a specific campaign ID value."] = None,  # noqa: E501
    restrict_to_outreach_orders: Annotated[str | None, "Restrict results to orders that have an outreach attached, such as an email campaign or Facebook ad."] = None,  # noqa: E501
    specific_customer_id: Annotated[str | None, "Restrict results to orders made by a specific customer using their unique customer ID."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getEcommerceOrders'."]:
    """Retrieve information about an account's ecommerce orders.

    Get details on all orders associated with a specific account, including order history and status."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/orders".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_order_fields, "count": number_of_records_to_return, "offset": pagination_offset, "campaign_id": restrict_to_campaign_id, "outreach_id": filter_by_outreach_id, "customer_id": specific_customer_id, "has_outreach": restrict_to_outreach_orders}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_ecommerce_stores_info(
    context: ToolContext,
    exclude_fields_list: Annotated[str | None, "A comma-separated list of fields to exclude from the response, using dot notation for nested objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "Comma-separated list of fields to return using dot notation for sub-objects."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "The number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
    records_to_return: Annotated[str | None, "Specify the number of store records to return (10 to 1000)."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getEcommerceStores'."]:
    """Retrieve information about all ecommerce stores in the account.

    This tool fetches details of all ecommerce stores linked to the account, enabling insights into store data."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields_list, "count": records_to_return, "offset": pagination_offset}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def add_new_ecommerce_store(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postEcommerceStores'."]:
    """Add a new e-commerce store to your Mailchimp account.

    Use this tool to add a new store to your Mailchimp account for managing e-commerce activities. Call this tool when you need to integrate a new store with Mailchimp.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["ADDNEWECOMMERCESTORE"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters

    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["ADDNEWECOMMERCESTORE"] + "\n```"
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["ADDNEWECOMMERCESTORE"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/ecommerce/stores".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: E501  # noqa: UP032
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["ADDNEWECOMMERCESTORE"],
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_ecommerce_store_info(
    context: ToolContext,
    store_id: Annotated[str, "A unique identifier for the store to retrieve information about."],
    excluded_fields_list: Annotated[str | None, "Comma-separated list of fields to exclude from the response, using dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to return. Use dot notation for sub-object parameters."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getEcommerceStoresId'."]:
    """Retrieve detailed information about a specific eCommerce store.

    Use this tool to get detailed information about a specific store in Mailchimp's eCommerce service. Call this when you need to access store data, such as name, domain, or other relevant attributes."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": excluded_fields_list}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def update_ecommerce_store(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    store_identifier: Annotated[str | None, "The unique identifier for the store you want to update.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'patchEcommerceStoresId'."]:
    """Update an e-commerce store's details.

    This tool is used to update the information of an existing e-commerce store in Mailchimp. Call this when you need to modify store details, such as the store name or other attributes.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires path parameters.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.\n      Note: You must also provide the required path parameters when executing.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["UPDATEECOMMERCESTORE"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter along with the required path parameters. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters
    # Validate required parameters
    missing_params = []
    if not store_identifier:
        missing_params.append(("store_identifier", "path"))

    if missing_params:
        param_names = [p[0] for p in missing_params]
        param_details = ", ".join(
            [f"{p[0]} ({p[1]})" for p in missing_params]
        )
        raise RetryableToolError(
            message=f"Missing required parameters: {param_names}",
            developer_message=(
                f"Required parameters validation failed: {param_details}"
            ),
            additional_prompt_content=(
                f"The following required parameters are missing: "
                f"{param_details}. Please call this tool again with all "
                "required parameters."
            ),
        )


    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["UPDATEECOMMERCESTORE"] + "\n```"
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["UPDATEECOMMERCESTORE"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/ecommerce/stores/{store_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier),  # noqa: E501  # noqa: UP032
        method="PATCH",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEECOMMERCESTORE"],
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def delete_ecommerce_store(
    context: ToolContext,
    store_identifier: Annotated[str, "The unique identifier for the store to be deleted."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteEcommerceStoresId'."]:
    """Delete a store and its associated subresources.

    Use this tool to delete an ecommerce store from Mailchimp Marketing. This action will remove the store along with any related Customers, Orders, Products, and Carts. Invoke this when a store needs to be completely removed from the system."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier),  # noqa: E501  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_store_carts_info(
    context: ToolContext,
    store_identifier: Annotated[str, "The unique identifier for the store to retrieve cart information."],  # noqa: E501
    exclude_fields: Annotated[str | None, "Comma-separated list of fields to exclude from the response. Use dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to include in the response, using dot notation for nested objects."] = None,  # noqa: E501
    number_of_records_to_return: Annotated[str | None, "Specify the number of records to return, up to a maximum of 1000. Default is 10."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "The number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getEcommerceStoresIdCarts'."]:
    """Retrieve information about a store's ecommerce carts.

    Use this tool to get detailed information about carts within a specific store in the ecommerce system. Ideal for understanding cart statuses, contents, and customer interactions."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}/carts".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields, "count": number_of_records_to_return, "offset": pagination_offset}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def add_cart_to_store(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    store_identifier: Annotated[str | None, "The unique identifier for the ecommerce store where the new cart will be added. This is essential to specify the target store.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postEcommerceStoresIdCarts'."]:
    """Add a new cart to an ecommerce store.

    This tool adds a new cart to a specified ecommerce store using Mailchimp Marketing. It should be called when a user needs to create a new cart for a store.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires path parameters.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.\n      Note: You must also provide the required path parameters when executing.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["ADDCARTTOSTORE"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter along with the required path parameters. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters
    # Validate required parameters
    missing_params = []
    if not store_identifier:
        missing_params.append(("store_identifier", "path"))

    if missing_params:
        param_names = [p[0] for p in missing_params]
        param_details = ", ".join(
            [f"{p[0]} ({p[1]})" for p in missing_params]
        )
        raise RetryableToolError(
            message=f"Missing required parameters: {param_names}",
            developer_message=(
                f"Required parameters validation failed: {param_details}"
            ),
            additional_prompt_content=(
                f"The following required parameters are missing: "
                f"{param_details}. Please call this tool again with all "
                "required parameters."
            ),
        )


    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["ADDCARTTOSTORE"] + "\n```"
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["ADDCARTTOSTORE"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/ecommerce/stores/{store_id}/carts".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier),  # noqa: E501  # noqa: UP032
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["ADDCARTTOSTORE"],
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_cart_info(
    context: ToolContext,
    cart_identifier: Annotated[str, "The unique identifier for the cart in the ecommerce store."],
    store_identifier: Annotated[str, "The unique identifier for the store. Use this to specify which store's cart information to retrieve."],  # noqa: E501
    fields_to_exclude: Annotated[str | None, "Comma-separated list of fields to exclude using dot notation for nested objects."] = None,  # noqa: E501
    include_fields: Annotated[str | None, "Specify a comma-separated list of fields to return, using dot notation for sub-objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getEcommerceStoresIdCartsId'."]:
    """Fetch information about a specific ecommerce cart.

    Use this tool to retrieve detailed information about a specific cart in an ecommerce store. It's useful for scenarios where you need to understand the contents or status of a cart identified by store and cart IDs."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}/carts/{cart_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier, cart_id=cart_identifier),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": include_fields, "exclude_fields": fields_to_exclude}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def update_cart(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    store_id: Annotated[str | None, "The unique identifier for the store where the cart is located.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    cart_identifier: Annotated[str | None, "The unique identifier for the cart. Used to specify which cart to update in the e-commerce store.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'patchEcommerceStoresIdCartsId'."]:
    """Update a specific cart in an e-commerce store.

    This tool updates a specified cart within a given e-commerce store using the Mailchimp Marketing API. Use it to modify cart details like items, quantities, or any other attributes available. Ideal for scenarios involving cart adjustments before customer checkout.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires path parameters.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.\n      Note: You must also provide the required path parameters when executing.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["UPDATECART"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter along with the required path parameters. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters
    # Validate required parameters
    missing_params = []
    if not store_id:
        missing_params.append(("store_id", "path"))
    if not cart_identifier:
        missing_params.append(("cart_identifier", "path"))

    if missing_params:
        param_names = [p[0] for p in missing_params]
        param_details = ", ".join(
            [f"{p[0]} ({p[1]})" for p in missing_params]
        )
        raise RetryableToolError(
            message=f"Missing required parameters: {param_names}",
            developer_message=(
                f"Required parameters validation failed: {param_details}"
            ),
            additional_prompt_content=(
                f"The following required parameters are missing: "
                f"{param_details}. Please call this tool again with all "
                "required parameters."
            ),
        )


    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["UPDATECART"] + "\n```"
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["UPDATECART"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/ecommerce/stores/{store_id}/carts/{cart_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_id, cart_id=cart_identifier),  # noqa: E501  # noqa: UP032
        method="PATCH",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATECART"],
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def delete_cart(
    context: ToolContext,
    cart_id: Annotated[str, "The ID for the cart to be deleted from the store."],
    store_identifier: Annotated[str, "The unique identifier for the ecommerce store from which the cart will be deleted."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteEcommerceStoresIdCartsId'."]:
    """Deletes a specific cart from an ecommerce store.

    Use this tool to delete a cart from a specified store in the ecommerce system. It should be called when you need to remove a cart by providing a specific store and cart ID."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}/carts/{cart_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier, cart_id=cart_id),  # noqa: E501  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_cart_line_items_info(
    context: ToolContext,
    cart_id: Annotated[str, "The unique identifier for the cart to retrieve line items for."],
    store_identifier: Annotated[str, "The unique identifier for the store containing the cart."],
    exclude_fields: Annotated[str | None, "Specify fields to exclude from the response. Use a comma-separated list with dot notation for sub-object parameters."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to return in the response. Use dot notation for sub-object parameters."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "Number of records to skip for pagination. Defaults to 0."] = None,  # noqa: E501
    records_to_return: Annotated[str | None, "The number of cart line items to return, from 1 to 1000. Default is 10."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getEcommerceStoresIdCartsIdLines'."]:  # noqa: E501
    """Retrieve information about a cart's line items.

    Use this tool to get details about the items in a specific cart within an ecommerce store. It provides insights into products added to a cart."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}/carts/{cart_id}/lines".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier, cart_id=cart_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields, "count": records_to_return, "offset": pagination_offset}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def add_line_item_to_cart(
    context: ToolContext,
    cart_identifier: Annotated[str, "The unique identifier for the cart to which the line item will be added."],  # noqa: E501
    cart_line_item_identifier: Annotated[str, "A unique identifier for the cart line item."],
    line_item_price: Annotated[float, "The monetary price for the line item being added to the cart. Must be a numeric value."],  # noqa: E501
    line_item_quantity: Annotated[int, "The number of units for the specified product variant in the cart."],  # noqa: E501
    product_id: Annotated[str, "A unique identifier for the product to be added to the cart line item."],  # noqa: E501
    product_variant_id: Annotated[str, "A unique identifier for the product variant to be added to the cart. This is necessary to specify which variant of the product is being added."],  # noqa: E501
    store_identifier: Annotated[str, "The unique identifier for the store. This is necessary to specify which store's cart will be updated."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postEcommerceStoresIdCartsIdLines'."]:  # noqa: E501
    """Add a new line item to an existing shopping cart.

    Use this tool to add a product to a specific cart by specifying the store and cart IDs. This enables updating shopping carts with new items in an e-commerce context."""  # noqa: E501
    request_data: Any = {"id": cart_line_item_identifier, "product_id": product_id, "product_variant_id": product_variant_id, "quantity": line_item_quantity, "price": line_item_price}  # noqa: E501
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}/carts/{cart_id}/lines".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier, cart_id=cart_identifier),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def retrieve_cart_line_item_info(
    context: ToolContext,
    cart_identifier: Annotated[str, "The unique identifier for the cart. Required to retrieve specific cart line item information."],  # noqa: E501
    cart_line_item_id: Annotated[str, "The ID for the line item in a specific cart. Used to identify which item details to retrieve."],  # noqa: E501
    store_identifier: Annotated[str, "Unique identifier for the store. Use this to specify which store's cart line item you want to retrieve."],  # noqa: E501
    exclude_fields: Annotated[str | None, "Comma-separated list of fields to exclude from the response. Use dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to return for the cart line item. Use dot notation for sub-objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getEcommerceStoresIdCartsIdLinesId'."]:  # noqa: E501
    """Get information about a specific cart line item.

    Call this tool to obtain details about a specific item in an e-commerce cart, such as product details and quantity."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}/carts/{cart_id}/lines/{line_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier, cart_id=cart_identifier, line_id=cart_line_item_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def update_cart_line_item(
    context: ToolContext,
    cart_id: Annotated[str, "The unique identifier for the cart."],
    cart_line_item_id: Annotated[str, "The unique identifier for the line item within the cart to be updated."],  # noqa: E501
    store_identifier: Annotated[str, "The unique identifier for the e-commerce store. Essential for specifying which store's cart line item to update."],  # noqa: E501
    cart_line_item_price: Annotated[float | None, "The price of a cart line item to be updated."] = None,  # noqa: E501
    cart_line_item_quantity: Annotated[int | None, "The quantity of the cart line item to update."] = None,  # noqa: E501
    product_identifier: Annotated[str | None, "A unique identifier for the product associated with the cart line item."] = None,  # noqa: E501
    product_variant_identifier: Annotated[str | None, "A unique identifier for the product variant associated with the cart line item. Required to specify which variant to update."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'patchEcommerceStoresIdCartsIdLinesId'."]:  # noqa: E501
    """Update a specific cart line item in Mailchimp.

    Use this tool to modify an existing cart line item in a specified e-commerce store within Mailchimp. This can be used to adjust item details such as quantity or other attributes."""  # noqa: E501
    request_data: Any = {"product_id": product_identifier, "product_variant_id": product_variant_identifier, "quantity": cart_line_item_quantity, "price": cart_line_item_price}  # noqa: E501
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}/carts/{cart_id}/lines/{line_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier, cart_id=cart_id, line_id=cart_line_item_id),  # noqa: E501  # noqa: UP032
        method="PATCH",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def delete_cart_line_item(
    context: ToolContext,
    cart_identifier: Annotated[str, "The unique identifier for the cart in the eCommerce store."],
    line_item_id: Annotated[str, "ID for the line item in the cart to be deleted."],
    store_identifier: Annotated[str, "The unique identifier for the store from which the cart line item will be deleted."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteEcommerceStoresIdCartsLinesId'."]:  # noqa: E501
    """Delete a specific cart line item.

    Use this tool to delete a particular line item from a cart in an eCommerce store. Call this tool when you need to remove an item from a customer's shopping cart."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}/carts/{cart_id}/lines/{line_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier, cart_id=cart_identifier, line_id=line_item_id),  # noqa: E501  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_store_customers_info(
    context: ToolContext,
    store_identifier: Annotated[str, "The unique identifier for the e-commerce store to retrieve customer information."],  # noqa: E501
    fields_to_exclude: Annotated[str | None, "Comma-separated fields to exclude in the response, using dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to return, using dot notation for sub-objects."] = None,  # noqa: E501
    filter_by_email_address: Annotated[str | None, "Restrict the response to customers matching the specified email address."] = None,  # noqa: E501
    number_of_records_to_return: Annotated[str | None, "The number of customer records to return. Default is 10, maximum is 1000."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "Number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getEcommerceStoresIdCustomers'."]:
    """Retrieve information about a store's customers.

    Use this tool to get detailed information about the customers of a specific e-commerce store. Ideal for accessing customer data to analyze or manage store interactions."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}/customers".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": fields_to_exclude, "count": number_of_records_to_return, "offset": pagination_offset, "email_address": filter_by_email_address}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def add_customer_to_store(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    store_identifier: Annotated[str | None, "The unique identifier for the ecommerce store where the customer will be added.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postEcommerceStoresIdCustomers'."]:
    """Add a new customer to an ecommerce store.

    This tool adds a new customer to a specified ecommerce store. It should be called when a new customer needs to be registered in the store's system.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires path parameters.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.\n      Note: You must also provide the required path parameters when executing.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["ADDCUSTOMERTOSTORE"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter along with the required path parameters. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters
    # Validate required parameters
    missing_params = []
    if not store_identifier:
        missing_params.append(("store_identifier", "path"))

    if missing_params:
        param_names = [p[0] for p in missing_params]
        param_details = ", ".join(
            [f"{p[0]} ({p[1]})" for p in missing_params]
        )
        raise RetryableToolError(
            message=f"Missing required parameters: {param_names}",
            developer_message=(
                f"Required parameters validation failed: {param_details}"
            ),
            additional_prompt_content=(
                f"The following required parameters are missing: "
                f"{param_details}. Please call this tool again with all "
                "required parameters."
            ),
        )


    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["ADDCUSTOMERTOSTORE"] + "\n```"
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["ADDCUSTOMERTOSTORE"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/ecommerce/stores/{store_id}/customers".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier),  # noqa: E501  # noqa: UP032
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["ADDCUSTOMERTOSTORE"],
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_customer_info(
    context: ToolContext,
    customer_id: Annotated[str, "The unique identifier for a customer in a specific store. Required to fetch customer details."],  # noqa: E501
    store_id: Annotated[str, "The unique identifier for the eCommerce store."],
    fields_to_exclude: Annotated[str | None, "Comma-separated list of fields to exclude using dot notation for sub-objects."] = None,  # noqa: E501
    return_fields: Annotated[str | None, "A comma-separated list of fields to return for the customer data. Use dot notation for sub-objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getEcommerceStoresIdCustomersId'."]:
    """Retrieve specific customer information from an eCommerce store.

    Use this tool to get detailed information about a specific customer from an eCommerce store using their customer ID and store ID. Ideal for checking customer profiles, transaction histories, and personal information tied to their account."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}/customers/{customer_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_id, customer_id=customer_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": return_fields, "exclude_fields": fields_to_exclude}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def add_or_update_customer_in_store(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    store_identifier: Annotated[str | None, "The unique identifier for the eCommerce store where the customer will be added or updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    customer_identifier: Annotated[str | None, "The unique identifier for the customer in the specified store. This ID is necessary for adding or updating customer details.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'putEcommerceStoresIdCustomersId'."]:
    """Add or update a customer in an eCommerce store.

    Use this tool to add a new customer or update an existing customer's information in a specific eCommerce store using Mailchimp Marketing.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires path parameters.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.\n      Note: You must also provide the required path parameters when executing.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["ADDORUPDATECUSTOMERINSTORE"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter along with the required path parameters. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters
    # Validate required parameters
    missing_params = []
    if not store_identifier:
        missing_params.append(("store_identifier", "path"))
    if not customer_identifier:
        missing_params.append(("customer_identifier", "path"))

    if missing_params:
        param_names = [p[0] for p in missing_params]
        param_details = ", ".join(
            [f"{p[0]} ({p[1]})" for p in missing_params]
        )
        raise RetryableToolError(
            message=f"Missing required parameters: {param_names}",
            developer_message=(
                f"Required parameters validation failed: {param_details}"
            ),
            additional_prompt_content=(
                f"The following required parameters are missing: "
                f"{param_details}. Please call this tool again with all "
                "required parameters."
            ),
        )


    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["ADDORUPDATECUSTOMERINSTORE"] + "\n```"  # noqa: E501
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["ADDORUPDATECUSTOMERINSTORE"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/ecommerce/stores/{store_id}/customers/{customer_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier, customer_id=customer_identifier),  # noqa: E501  # noqa: UP032
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["ADDORUPDATECUSTOMERINSTORE"],
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def update_customer_info(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    store_identifier: Annotated[str | None, "The unique identifier for the ecommerce store where the customer resides.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    customer_identifier: Annotated[str | None, "The unique identifier for a customer in a specific store. Required to update customer information.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'patchEcommerceStoresIdCustomersId'."]:  # noqa: E501
    """Update a customer's information in an ecommerce store.

    Use this tool to update the information of a customer within a specific ecommerce store. Ideal for changes in customer details such as address, contact info, or other personal data.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires path parameters.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.\n      Note: You must also provide the required path parameters when executing.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["UPDATECUSTOMERINFO"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter along with the required path parameters. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters
    # Validate required parameters
    missing_params = []
    if not store_identifier:
        missing_params.append(("store_identifier", "path"))
    if not customer_identifier:
        missing_params.append(("customer_identifier", "path"))

    if missing_params:
        param_names = [p[0] for p in missing_params]
        param_details = ", ".join(
            [f"{p[0]} ({p[1]})" for p in missing_params]
        )
        raise RetryableToolError(
            message=f"Missing required parameters: {param_names}",
            developer_message=(
                f"Required parameters validation failed: {param_details}"
            ),
            additional_prompt_content=(
                f"The following required parameters are missing: "
                f"{param_details}. Please call this tool again with all "
                "required parameters."
            ),
        )


    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["UPDATECUSTOMERINFO"] + "\n```"
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["UPDATECUSTOMERINFO"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/ecommerce/stores/{store_id}/customers/{customer_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier, customer_id=customer_identifier),  # noqa: E501  # noqa: UP032
        method="PATCH",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATECUSTOMERINFO"],
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def delete_store_customer(
    context: ToolContext,
    customer_identifier: Annotated[str, "The unique identifier for the customer to be deleted from the store. This ID is used to specify which customer's records should be removed."],  # noqa: E501
    store_identifier: Annotated[str, "The unique identifier for the ecommerce store from which the customer will be deleted."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteEcommerceStoresIdCustomersId'."]:  # noqa: E501
    """Delete a customer from an ecommerce store.

    Call this tool to remove a specific customer from a given ecommerce store. Use when you need to manage customer records by deleting them from a store's database."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}/customers/{customer_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier, customer_id=customer_identifier),  # noqa: E501  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_store_promo_rules(
    context: ToolContext,
    store_identifier: Annotated[str, "The unique identifier for the store to retrieve promo rules from."],  # noqa: E501
    exclude_fields_list: Annotated[str | None, "Comma-separated list of fields to exclude from the response. Use dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to return, using dot notation for sub-objects."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "The number of records to skip for pagination, with a default value of 0."] = None,  # noqa: E501
    records_to_return: Annotated[str | None, "Specify the number of promo rule records to return. Default is 10, maximum is 1000."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getEcommerceStoresIdPromorules'."]:
    """Retrieve promo rules for a specified store.

    Use this tool to get detailed information about the promotional rules set up for a specific e-commerce store using its ID."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}/promo-rules".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields_list, "count": records_to_return, "offset": pagination_offset}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def add_store_promo_rule(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    store_id: Annotated[str | None, "The unique identifier for the store where the promo rule will be added.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postEcommerceStoresIdPromorules'."]:
    """Add a new promo rule to an e-commerce store on Mailchimp.

    This tool is used to add a new promotional rule to a specific e-commerce store within Mailchimp. It is ideal for automating the management of store promotions.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires path parameters.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.\n      Note: You must also provide the required path parameters when executing.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["ADDSTOREPROMORULE"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter along with the required path parameters. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters
    # Validate required parameters
    missing_params = []
    if not store_id:
        missing_params.append(("store_id", "path"))

    if missing_params:
        param_names = [p[0] for p in missing_params]
        param_details = ", ".join(
            [f"{p[0]} ({p[1]})" for p in missing_params]
        )
        raise RetryableToolError(
            message=f"Missing required parameters: {param_names}",
            developer_message=(
                f"Required parameters validation failed: {param_details}"
            ),
            additional_prompt_content=(
                f"The following required parameters are missing: "
                f"{param_details}. Please call this tool again with all "
                "required parameters."
            ),
        )


    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["ADDSTOREPROMORULE"] + "\n```"
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["ADDSTOREPROMORULE"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/ecommerce/stores/{store_id}/promo-rules".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_id),  # noqa: E501  # noqa: UP032
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["ADDSTOREPROMORULE"],
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_promo_rule_info(
    context: ToolContext,
    promo_rule_id: Annotated[str, "The unique identifier for the promo rule in the store. Required to fetch specific rule details."],  # noqa: E501
    store_id: Annotated[str, "The unique identifier for the ecommerce store. Required to fetch promo rule details."],  # noqa: E501
    exclude_fields: Annotated[str | None, "A comma-separated list of fields to exclude from the promo rule data. Use dot notation to reference sub-objects."] = None,  # noqa: E501
    include_fields: Annotated[str | None, "A comma-separated list of specific fields to return using dot notation for sub-objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getEcommerceStoresIdPromorulesId'."]:  # noqa: E501
    """Retrieve information about a specific promo rule in an ecommerce store.

"""
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}/promo-rules/{promo_rule_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_id, promo_rule_id=promo_rule_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": include_fields, "exclude_fields": exclude_fields}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def update_promo_rule(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    store_identifier: Annotated[str | None, "Specify the unique identifier of the e-commerce store where the promo rule will be updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    promo_rule_identifier: Annotated[str | None, "The unique identifier for the promotional rule within the store. This is required to specify which promo rule to update.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'patchEcommerceStoresIdPromorulesId'."]:  # noqa: E501
    """Update a promotional rule in an e-commerce store.

    Use this tool to modify details of an existing promotional rule in a specified e-commerce store. It should be called when you need to update the conditions or discounts associated with a promo rule.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires path parameters.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.\n      Note: You must also provide the required path parameters when executing.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["UPDATEPROMORULE"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter along with the required path parameters. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters
    # Validate required parameters
    missing_params = []
    if not store_identifier:
        missing_params.append(("store_identifier", "path"))
    if not promo_rule_identifier:
        missing_params.append(("promo_rule_identifier", "path"))

    if missing_params:
        param_names = [p[0] for p in missing_params]
        param_details = ", ".join(
            [f"{p[0]} ({p[1]})" for p in missing_params]
        )
        raise RetryableToolError(
            message=f"Missing required parameters: {param_names}",
            developer_message=(
                f"Required parameters validation failed: {param_details}"
            ),
            additional_prompt_content=(
                f"The following required parameters are missing: "
                f"{param_details}. Please call this tool again with all "
                "required parameters."
            ),
        )


    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["UPDATEPROMORULE"] + "\n```"
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["UPDATEPROMORULE"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/ecommerce/stores/{store_id}/promo-rules/{promo_rule_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier, promo_rule_id=promo_rule_identifier),  # noqa: E501  # noqa: UP032
        method="PATCH",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEPROMORULE"],
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def delete_promo_rule_from_store(
    context: ToolContext,
    promo_rule_id: Annotated[str, "The unique identifier for the promo rule to be deleted from the store."],  # noqa: E501
    store_id: Annotated[str, "The unique identifier for the ecommerce store from which the promo rule will be deleted."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteEcommerceStoresIdPromorulesId'."]:  # noqa: E501
    """Delete a promo rule from a specified ecommerce store.

    Use this tool to remove a promotional rule from an ecommerce store on Mailchimp. This action is irreversible and will delete the specified promo rule from the store identified by the store ID."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}/promo-rules/{promo_rule_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_id, promo_rule_id=promo_rule_id),  # noqa: E501  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_store_promo_codes(
    context: ToolContext,
    promo_rule_id: Annotated[str, "The unique identifier for the promotion rule of a store to fetch promo codes."],  # noqa: E501
    store_identifier: Annotated[str, "The unique identifier for the store to get promo codes from. Required to specify which store's promo codes to retrieve."],  # noqa: E501
    exclude_fields_list: Annotated[str | None, "Specify a comma-separated list of fields to exclude from the returned data. Use dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "Comma-separated list of specific fields to include in the response, using dot notation for sub-objects."] = None,  # noqa: E501
    number_of_records_to_return: Annotated[str | None, "The number of promo code records to return. Default is 10, with a maximum of 1000."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "The number of records to skip for pagination purposes. Default is 0."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getEcommerceStoresIdPromocodes'."]:
    """Retrieve information about promo codes for a specific store.

    Use this tool to get detailed information about promo codes for a given store, which can help in managing promotions and discounts."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}/promo-rules/{promo_rule_id}/promo-codes".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), promo_rule_id=promo_rule_id, store_id=store_identifier),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields_list, "count": number_of_records_to_return, "offset": pagination_offset}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def add_promo_code_to_store(
    context: ToolContext,
    promo_code: Annotated[str, "The discount code for the promotion. It must be a UTF-8 string, with a maximum length of 50 characters."],  # noqa: E501
    promo_code_identifier: Annotated[str, "A unique identifier for the promo code. Must be UTF-8, max length 50."],  # noqa: E501
    promo_rule_identifier: Annotated[str, "The ID for the promotional rule associated with the store."],  # noqa: E501
    promotion_redemption_url: Annotated[str, "The URL used in the promotion campaign. Must be UTF-8, max length 2000 characters."],  # noqa: E501
    store_identifier: Annotated[str, "The unique identifier for the ecommerce store where the promo code will be added."],  # noqa: E501
    is_promo_code_enabled: Annotated[bool | None, "Specifies if the promo code is enabled. Use true to enable, false to disable."] = None,  # noqa: E501
    promo_code_usage_count: Annotated[int | None, "Number of times the promo code has been used. This integer value helps track the utilization of the promo code."] = None,  # noqa: E501
    promotion_creation_datetime: Annotated[str | None, "The date and time the promotion was created, in ISO 8601 format."] = None,  # noqa: E501
    promotion_updated_datetime: Annotated[str | None, "The date and time the promotion was last updated, in ISO 8601 format."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postEcommerceStoresIdPromocodes'."]:
    """Add a new promo code to an ecommerce store.

    Use this tool to add a new promotional code to a specific store in the ecommerce platform. This is useful for managing discounts and promotions within the store."""  # noqa: E501
    request_data: Any = {"id": promo_code_identifier, "code": promo_code, "redemption_url": promotion_redemption_url, "usage_count": promo_code_usage_count, "enabled": is_promo_code_enabled, "created_at_foreign": promotion_creation_datetime, "updated_at_foreign": promotion_updated_datetime}  # noqa: E501
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}/promo-rules/{promo_rule_id}/promo-codes".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier, promo_rule_id=promo_rule_identifier),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_promo_code_info(
    context: ToolContext,
    promo_code_id: Annotated[str, "The unique identifier for the promo code associated with a store."],  # noqa: E501
    promo_rule_id: Annotated[str, "The unique identifier for the promo rule of a store. This is required to fetch specific promo code information."],  # noqa: E501
    store_id: Annotated[str, "The unique identifier for the store. Required to specify which store's promo code information to retrieve."],  # noqa: E501
    exclude_fields: Annotated[str | None, "Comma-separated list of fields to exclude using dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to return, using dot notation for sub-objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getEcommerceStoresIdPromocodesId'."]:  # noqa: E501
    """Retrieve details of a specific promo code.

    Use this tool to get detailed information about a specific promo code associated with a particular store in the Mailchimp Marketing service."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}/promo-rules/{promo_rule_id}/promo-codes/{promo_code_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_id, promo_rule_id=promo_rule_id, promo_code_id=promo_code_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def update_promo_code(
    context: ToolContext,
    promo_code_identifier: Annotated[str, "The unique identifier for the promo code of a store."],
    promo_rule_identifier: Annotated[str, "The identifier for the promo rule in a store. Used to specify which promotional rule to update."],  # noqa: E501
    store_identifier: Annotated[str, "The unique identifier for the eCommerce store in Mailchimp."],
    discount_code: Annotated[str | None, "The discount code for the promo. Must be UTF-8 and up to 50 characters."] = None,  # noqa: E501
    is_promo_code_enabled: Annotated[bool | None, "Set to true to enable the promo code, or false to disable it."] = None,  # noqa: E501
    promo_code_usage_count: Annotated[int | None, "Specifies how many times the promo code has been used. Accepts an integer value."] = None,  # noqa: E501
    promotion_created_at: Annotated[str | None, "The promotion creation date and time in ISO 8601 format."] = None,  # noqa: E501
    promotion_redemption_url: Annotated[str | None, "The URL for the promotion campaign. Must be UTF-8, max 2000 characters."] = None,  # noqa: E501
    promotion_update_timestamp: Annotated[str | None, "The timestamp when the promotion was updated, in ISO 8601 format. This indicates the last update time of the promo code details."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'patchEcommerceStoresIdPromocodesId'."]:  # noqa: E501
    """Update details of a specific promo code.

    Use this tool to update the details of a specific promo code in an eCommerce store using Mailchimp. It should be called when you need to modify existing promotional codes, such as changing the discount or expiration date."""  # noqa: E501
    request_data: Any = {"code": discount_code, "redemption_url": promotion_redemption_url, "usage_count": promo_code_usage_count, "enabled": is_promo_code_enabled, "created_at_foreign": promotion_created_at, "updated_at_foreign": promotion_update_timestamp}  # noqa: E501
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}/promo-rules/{promo_rule_id}/promo-codes/{promo_code_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier, promo_rule_id=promo_rule_identifier, promo_code_id=promo_code_identifier),  # noqa: E501  # noqa: UP032
        method="PATCH",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def delete_store_promo_code(
    context: ToolContext,
    promo_code_id: Annotated[str, "The ID of the promo code to be deleted from the store."],
    promo_rule_id: Annotated[str, "The unique identifier for the promo rule of a store, used to specify which promo rule the code belongs to."],  # noqa: E501
    store_identifier: Annotated[str, "The unique identifier for the store from which the promo code will be deleted."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteEcommerceStoresIdPromocodesId'."]:  # noqa: E501
    """Delete a promo code from an e-commerce store.

    Use this tool to delete a specific promo code from a designated e-commerce store in Mailchimp Marketing. It is useful when you want to manage or clean up promotional offers by removing existing promo codes."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}/promo-rules/{promo_rule_id}/promo-codes/{promo_code_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier, promo_rule_id=promo_rule_id, promo_code_id=promo_code_id),  # noqa: E501  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_store_orders_info(
    context: ToolContext,
    store_identifier: Annotated[str, "The unique identifier for the store whose orders information is to be retrieved."],  # noqa: E501
    exclude_order_fields: Annotated[str | None, "Comma-separated list of order fields to exclude, using dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to return. Use dot notation for sub-objects."] = None,  # noqa: E501
    filter_by_customer_id: Annotated[str | None, "Restrict results to orders made by a specific customer using their unique customer ID."] = None,  # noqa: E501
    number_of_records_to_return: Annotated[str | None, "Specify the number of records to return, between 1 and 1000, with a default of 10."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "Number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
    restrict_to_campaign_id: Annotated[str | None, "Restrict results to orders with the specified `campaign_id`."] = None,  # noqa: E501
    restrict_to_outreach_orders: Annotated[str | None, "Indicate whether to restrict results to orders with an outreach attached, such as an email campaign or Facebook ad. Accepts 'true' or 'false'."] = None,  # noqa: E501
    specific_outreach_id: Annotated[str | None, "Restrict results to orders with a specific outreach ID."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getEcommerceStoresIdOrders'."]:
    """Retrieve information about a store's orders via Mailchimp.

    Use this tool to get detailed information about the orders of a specified store from Mailchimp's ecommerce platform."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}/orders".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_order_fields, "count": number_of_records_to_return, "offset": pagination_offset, "customer_id": filter_by_customer_id, "has_outreach": restrict_to_outreach_orders, "campaign_id": restrict_to_campaign_id, "outreach_id": specific_outreach_id}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def add_order_to_store(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    store_identifier: Annotated[str | None, "The unique identifier for the store where the order will be added. This should be a string value that accurately corresponds to an existing store in the system.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postEcommerceStoresIdOrders'."]:
    """Add a new order to an ecommerce store.

    This tool adds a new order to a specified store using the store's ID. It should be called when you need to record a new purchase or transaction in your ecommerce system.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires path parameters.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.\n      Note: You must also provide the required path parameters when executing.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["ADDORDERTOSTORE"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter along with the required path parameters. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters
    # Validate required parameters
    missing_params = []
    if not store_identifier:
        missing_params.append(("store_identifier", "path"))

    if missing_params:
        param_names = [p[0] for p in missing_params]
        param_details = ", ".join(
            [f"{p[0]} ({p[1]})" for p in missing_params]
        )
        raise RetryableToolError(
            message=f"Missing required parameters: {param_names}",
            developer_message=(
                f"Required parameters validation failed: {param_details}"
            ),
            additional_prompt_content=(
                f"The following required parameters are missing: "
                f"{param_details}. Please call this tool again with all "
                "required parameters."
            ),
        )


    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["ADDORDERTOSTORE"] + "\n```"
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["ADDORDERTOSTORE"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/ecommerce/stores/{store_id}/orders".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier),  # noqa: E501  # noqa: UP032
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["ADDORDERTOSTORE"],
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_specific_order_info(
    context: ToolContext,
    order_id: Annotated[str, "The unique identifier for the order in a store. It is required to retrieve specific order details."],  # noqa: E501
    store_identifier: Annotated[str, "The unique identifier for the store. Required to fetch order information."],  # noqa: E501
    exclude_fields_list: Annotated[str | None, "Comma-separated list of fields to exclude from the response. Use dot notation for sub-object parameters."] = None,  # noqa: E501
    include_fields: Annotated[str | None, "Comma-separated list of fields to return, using dot notation for sub-objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getEcommerceStoresIdOrdersId'."]:
    """Retrieve information about a specific order in a store.

    Use this tool to obtain details about a specific order from an e-commerce store. It should be called when needing to access order information using the order ID and store ID."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}/orders/{order_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier, order_id=order_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": include_fields, "exclude_fields": exclude_fields_list}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def update_ecommerce_order(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    store_identifier: Annotated[str | None, "The unique identifier for the store in which the order is being added or updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    order_identifier: Annotated[str | None, "The unique identifier for the order in the store. Used to specify which order to update or add.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'putEcommerceStoresIdOrdersId'."]:
    """Add or update an order in an ecommerce store.

    Use this tool to either add a new order or update an existing order within an ecommerce store in Mailchimp Marketing. This tool is suitable when order details need to be adjusted or fresh orders are being added.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires path parameters.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.\n      Note: You must also provide the required path parameters when executing.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["UPDATEECOMMERCEORDER"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter along with the required path parameters. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters
    # Validate required parameters
    missing_params = []
    if not store_identifier:
        missing_params.append(("store_identifier", "path"))
    if not order_identifier:
        missing_params.append(("order_identifier", "path"))

    if missing_params:
        param_names = [p[0] for p in missing_params]
        param_details = ", ".join(
            [f"{p[0]} ({p[1]})" for p in missing_params]
        )
        raise RetryableToolError(
            message=f"Missing required parameters: {param_names}",
            developer_message=(
                f"Required parameters validation failed: {param_details}"
            ),
            additional_prompt_content=(
                f"The following required parameters are missing: "
                f"{param_details}. Please call this tool again with all "
                "required parameters."
            ),
        )


    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["UPDATEECOMMERCEORDER"] + "\n```"
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["UPDATEECOMMERCEORDER"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/ecommerce/stores/{store_id}/orders/{order_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier, order_id=order_identifier),  # noqa: E501  # noqa: UP032
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEECOMMERCEORDER"],
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def update_order_mailchimp(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    store_identifier: Annotated[str | None, "The unique identifier for the store in which the order is being updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    order_id: Annotated[str | None, "The unique identifier for the order in the store that needs to be updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'patchEcommerceStoresIdOrdersId'."]:
    """Update a specific order in Mailchimp's e-commerce store.

    Use this tool to modify order details in a specified Mailchimp e-commerce store. It updates the order data based on provided criteria and returns the updated order status.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires path parameters.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.\n      Note: You must also provide the required path parameters when executing.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["UPDATEORDERMAILCHIMP"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter along with the required path parameters. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters
    # Validate required parameters
    missing_params = []
    if not store_identifier:
        missing_params.append(("store_identifier", "path"))
    if not order_id:
        missing_params.append(("order_id", "path"))

    if missing_params:
        param_names = [p[0] for p in missing_params]
        param_details = ", ".join(
            [f"{p[0]} ({p[1]})" for p in missing_params]
        )
        raise RetryableToolError(
            message=f"Missing required parameters: {param_names}",
            developer_message=(
                f"Required parameters validation failed: {param_details}"
            ),
            additional_prompt_content=(
                f"The following required parameters are missing: "
                f"{param_details}. Please call this tool again with all "
                "required parameters."
            ),
        )


    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["UPDATEORDERMAILCHIMP"] + "\n```"
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["UPDATEORDERMAILCHIMP"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/ecommerce/stores/{store_id}/orders/{order_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier, order_id=order_id),  # noqa: E501  # noqa: UP032
        method="PATCH",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEORDERMAILCHIMP"],
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def delete_order_in_ecommerce_store(
    context: ToolContext,
    ecommerce_store_id: Annotated[str, "The unique identifier for the eCommerce store from which the order will be deleted."],  # noqa: E501
    order_id: Annotated[str, "The unique identifier for the order to delete within the store."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteEcommerceStoresIdOrdersId'."]:
    """Delete an order from an eCommerce store.

    Use this tool to delete a specific order from an eCommerce store in Mailchimp by providing the store ID and order ID."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}/orders/{order_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=ecommerce_store_id, order_id=order_id),  # noqa: E501  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_order_line_items(
    context: ToolContext,
    order_id: Annotated[str, "The unique identifier for the order within the store. Required to specify which order's line items to retrieve."],  # noqa: E501
    store_id: Annotated[str, "The unique identifier for the store. Used to specify which store's order line items to retrieve."],  # noqa: E501
    exclude_fields: Annotated[str | None, "Comma-separated list of fields to exclude, using dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to return, using dot notation for sub-objects."] = None,  # noqa: E501
    number_of_records_to_return: Annotated[str | None, "Specify the number of line item records to return, between 1 and 1000. Default is 10."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "Number of records to skip for pagination, default is 0."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getEcommerceStoresIdOrdersIdLines'."]:  # noqa: E501
    """Retrieve information about order line items.

    Use this tool to get detailed information about line items in a specific order from an e-commerce store linked to Mailchimp."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}/orders/{order_id}/lines".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_id, order_id=order_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields, "count": number_of_records_to_return, "offset": pagination_offset}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def add_order_line_item(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    store_identifier: Annotated[str | None, "The unique identifier for the store where the order is placed.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    order_id: Annotated[str | None, "The unique identifier for the order in the store, used to specify which order to update.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postEcommerceStoresIdOrdersIdLines'."]:  # noqa: E501
    """Add a new line item to an existing order.

    Use this tool to add a new product line to an existing order in an ecommerce store. Ideal for updating orders with additional items, changing quantities, or modifying product details.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires path parameters.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.\n      Note: You must also provide the required path parameters when executing.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["ADDORDERLINEITEM"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter along with the required path parameters. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters
    # Validate required parameters
    missing_params = []
    if not store_identifier:
        missing_params.append(("store_identifier", "path"))
    if not order_id:
        missing_params.append(("order_id", "path"))

    if missing_params:
        param_names = [p[0] for p in missing_params]
        param_details = ", ".join(
            [f"{p[0]} ({p[1]})" for p in missing_params]
        )
        raise RetryableToolError(
            message=f"Missing required parameters: {param_names}",
            developer_message=(
                f"Required parameters validation failed: {param_details}"
            ),
            additional_prompt_content=(
                f"The following required parameters are missing: "
                f"{param_details}. Please call this tool again with all "
                "required parameters."
            ),
        )


    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["ADDORDERLINEITEM"] + "\n```"
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["ADDORDERLINEITEM"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/ecommerce/stores/{store_id}/orders/{order_id}/lines".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier, order_id=order_id),  # noqa: E501  # noqa: UP032
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["ADDORDERLINEITEM"],
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_specific_order_line_item_info(
    context: ToolContext,
    order_id: Annotated[str, "The unique identifier for the order within a store. Required to fetch details of the specific order line item."],  # noqa: E501
    order_line_item_id: Annotated[str, "The unique identifier for the line item in the order."],
    store_identifier: Annotated[str, "The unique identifier for the store. This is required to specify which store's data to retrieve."],  # noqa: E501
    exclude_fields: Annotated[str | None, "A comma-separated list of specific fields to exclude from the response. Use dot notation for sub-object fields."] = None,  # noqa: E501
    return_fields: Annotated[str | None, "Comma-separated list of fields to return. Use dot notation for sub-objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getEcommerceStoresIdOrdersIdLinesId'."]:  # noqa: E501
    """Get details about a specific order line item.

    Use this tool to retrieve information about a specific order line item from an e-commerce store in Mailchimp. Useful for obtaining order details such as product name, quantity, price, etc., for a particular order line."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}/orders/{order_id}/lines/{line_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier, order_id=order_id, line_id=order_line_item_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": return_fields, "exclude_fields": exclude_fields}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def update_order_line_item(
    context: ToolContext,
    line_item_id: Annotated[str, "The unique identifier for the line item within an order in a store."],  # noqa: E501
    order_id: Annotated[str, "The unique identifier for the order within the store. Required to specify which order is being updated."],  # noqa: E501
    store_identifier: Annotated[str, "Unique identifier for the store where the order was placed."],
    line_item_discount_amount: Annotated[float | None, "The total discount amount applied to this line item in the order. Provide as a numerical value."] = None,  # noqa: E501
    order_line_item_price: Annotated[float | None, "Specify the updated price for the order line item. This should be a numerical value reflecting the new cost of the item."] = None,  # noqa: E501
    order_line_item_quantity: Annotated[int | None, "Specify the quantity of the order line item to be updated."] = None,  # noqa: E501
    product_identifier: Annotated[str | None, "A unique identifier for the product associated with the order line item."] = None,  # noqa: E501
    product_variant_id: Annotated[str | None, "A unique identifier for the product variant associated with the order line item. This is required to specify the variant of the product being referenced."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'patchEcommerceStoresIdOrdersIdLinesId'."]:  # noqa: E501
    """Update a specific order line item.

    Use this tool to update details of a specific order line item in an e-commerce store. Useful for modifying existing order line items with new information or adjustments."""  # noqa: E501
    request_data: Any = {"product_id": product_identifier, "product_variant_id": product_variant_id, "quantity": order_line_item_quantity, "price": order_line_item_price, "discount": line_item_discount_amount}  # noqa: E501
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}/orders/{order_id}/lines/{line_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier, order_id=order_id, line_id=line_item_id),  # noqa: E501  # noqa: UP032
        method="PATCH",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def delete_order_line_item(
    context: ToolContext,
    order_id: Annotated[str, "The unique identifier for the order within a store. This is required to delete a line item from the specified order."],  # noqa: E501
    order_line_item_id: Annotated[str, "The unique identifier for the line item of an order to be deleted."],  # noqa: E501
    store_id: Annotated[str, "Unique identifier for the store from which the order line item will be deleted."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteEcommerceStoresIdOrdersIdLinesId'."]:  # noqa: E501
    """Delete a specific order line item.

    Call this tool to delete a specific line item from an order within an e-commerce store in Mailchimp. The tool should be used when a user needs to remove an item from an order completely."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}/orders/{order_id}/lines/{line_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_id, order_id=order_id, line_id=order_line_item_id),  # noqa: E501  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_store_products_info(
    context: ToolContext,
    store_identifier: Annotated[str, "The unique identifier for the store whose product information is being retrieved."],  # noqa: E501
    exclude_fields_list: Annotated[str | None, "Comma-separated list of fields to exclude from the response. Use dot notation for sub-object parameters."] = None,  # noqa: E501
    number_of_records_to_return: Annotated[str | None, "Specify the number of product records to return, from 1 to 1000. The default value is 10."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "The number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
    return_fields_list: Annotated[str | None, "A comma-separated list of specific fields to return. Use dot notation for sub-objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getEcommerceStoresIdProducts'."]:
    """Get information about a store's products from Mailchimp.

    This tool retrieves detailed information about products in a specified ecommerce store using Mailchimp's marketing API. It should be called when information about a store's inventory is needed."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}/products".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": return_fields_list, "exclude_fields": exclude_fields_list, "count": number_of_records_to_return, "offset": pagination_offset}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def add_product_to_store(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    store_id: Annotated[str | None, "The unique identifier of the store where the product will be added. This is required to specify the target store.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postEcommerceStoresIdProducts'."]:
    """Add a new product to a Mailchimp store.

    Use this tool to add a new product to a specific store in Mailchimp. This is useful for updating store inventories or launching new products.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires path parameters.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.\n      Note: You must also provide the required path parameters when executing.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["ADDPRODUCTTOSTORE"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter along with the required path parameters. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters
    # Validate required parameters
    missing_params = []
    if not store_id:
        missing_params.append(("store_id", "path"))

    if missing_params:
        param_names = [p[0] for p in missing_params]
        param_details = ", ".join(
            [f"{p[0]} ({p[1]})" for p in missing_params]
        )
        raise RetryableToolError(
            message=f"Missing required parameters: {param_names}",
            developer_message=(
                f"Required parameters validation failed: {param_details}"
            ),
            additional_prompt_content=(
                f"The following required parameters are missing: "
                f"{param_details}. Please call this tool again with all "
                "required parameters."
            ),
        )


    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["ADDPRODUCTTOSTORE"] + "\n```"
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["ADDPRODUCTTOSTORE"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/ecommerce/stores/{store_id}/products".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_id),  # noqa: E501  # noqa: UP032
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["ADDPRODUCTTOSTORE"],
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_product_info(
    context: ToolContext,
    product_id: Annotated[str, "The unique identifier for the product within a store. This ID is required to fetch specific product details."],  # noqa: E501
    store_identifier: Annotated[str, "The unique identifier for the store from which to retrieve the product information."],  # noqa: E501
    fields_to_exclude: Annotated[str | None, "Comma-separated fields to exclude in the response, using dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to return, using dot notation for sub-objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getEcommerceStoresIdProductsId'."]:
    """Get information about a specific product from an ecommerce store.

    Use this tool to retrieve detailed information on a specific product from a specified ecommerce store, identified by store and product IDs."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}/products/{product_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier, product_id=product_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": fields_to_exclude}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def update_product_info(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    store_identifier: Annotated[str | None, "The identifier for the specific store whose product details are being updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    product_identifier: Annotated[str | None, "The unique identifier for the product within a store. Required for updating product details.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'patchEcommerceStoresIdProductsId'."]:  # noqa: E501
    """Update details of a specific product in a store.

    This tool updates information for a specific product in an e-commerce store. Call this tool when you need to modify product details, such as name, description, or price, for a particular store.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires path parameters.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.\n      Note: You must also provide the required path parameters when executing.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["UPDATEPRODUCTINFO"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter along with the required path parameters. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters
    # Validate required parameters
    missing_params = []
    if not store_identifier:
        missing_params.append(("store_identifier", "path"))
    if not product_identifier:
        missing_params.append(("product_identifier", "path"))

    if missing_params:
        param_names = [p[0] for p in missing_params]
        param_details = ", ".join(
            [f"{p[0]} ({p[1]})" for p in missing_params]
        )
        raise RetryableToolError(
            message=f"Missing required parameters: {param_names}",
            developer_message=(
                f"Required parameters validation failed: {param_details}"
            ),
            additional_prompt_content=(
                f"The following required parameters are missing: "
                f"{param_details}. Please call this tool again with all "
                "required parameters."
            ),
        )


    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["UPDATEPRODUCTINFO"] + "\n```"
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["UPDATEPRODUCTINFO"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/ecommerce/stores/{store_id}/products/{product_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier, product_id=product_identifier),  # noqa: E501  # noqa: UP032
        method="PATCH",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEPRODUCTINFO"],
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def update_ecommerce_product(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    store_identifier: Annotated[str | None, "The unique identifier of the store to update the product in.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    product_id: Annotated[str | None, "The unique identifier for the product within a store. This is used to specify which product needs to be updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'putEcommerceStoresIdProductsId'."]:
    """Update a specific product in an ecommerce store.

    Use this tool to update details of a specific product in an ecommerce store. It is useful when you need to modify product information such as pricing, inventory, or descriptions.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires path parameters.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.\n      Note: You must also provide the required path parameters when executing.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["UPDATEECOMMERCEPRODUCT"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter along with the required path parameters. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters
    # Validate required parameters
    missing_params = []
    if not store_identifier:
        missing_params.append(("store_identifier", "path"))
    if not product_id:
        missing_params.append(("product_id", "path"))

    if missing_params:
        param_names = [p[0] for p in missing_params]
        param_details = ", ".join(
            [f"{p[0]} ({p[1]})" for p in missing_params]
        )
        raise RetryableToolError(
            message=f"Missing required parameters: {param_names}",
            developer_message=(
                f"Required parameters validation failed: {param_details}"
            ),
            additional_prompt_content=(
                f"The following required parameters are missing: "
                f"{param_details}. Please call this tool again with all "
                "required parameters."
            ),
        )


    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["UPDATEECOMMERCEPRODUCT"] + "\n```"
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["UPDATEECOMMERCEPRODUCT"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/ecommerce/stores/{store_id}/products/{product_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier, product_id=product_id),  # noqa: E501  # noqa: UP032
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEECOMMERCEPRODUCT"],
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def delete_ecommerce_product(
    context: ToolContext,
    product_id: Annotated[str, "The unique identifier for the product to delete from a store."],
    store_id: Annotated[str, "The unique identifier of the eCommerce store from which the product will be deleted."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteEcommerceStoresIdProductsId'."]:  # noqa: E501
    """Delete a product from an eCommerce store.

    Use this tool to delete a specific product from a given eCommerce store in Mailchimp. It should be called when you want to remove a product based on its store and product ID."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}/products/{product_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_id, product_id=product_id),  # noqa: E501  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_product_variants_info(
    context: ToolContext,
    product_identifier: Annotated[str, "The unique identifier for the product within the store."],
    store_id: Annotated[str, "The unique identifier for the store. Required to fetch product variant data."],  # noqa: E501
    exclude_fields_list: Annotated[str | None, "Specify fields to exclude using a comma-separated list. Use dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "Comma-separated list of fields to return, using dot notation for sub-objects."] = None,  # noqa: E501
    number_of_records_to_return: Annotated[str | None, "Specify the number of product variant records to return, default is 10, max is 1000."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "Number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getEcommerceStoresIdProductsIdVariants'."]:  # noqa: E501
    """Retrieve information on product variants from a store.

    Use this tool to obtain detailed information about the variants of a specific product in an e-commerce store. Ideal for cases where users need to know different versions or options available for a product."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}/products/{product_id}/variants".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_id, product_id=product_identifier),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields_list, "count": number_of_records_to_return, "offset": pagination_offset}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def add_product_variant_mailchimp(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    store_identifier: Annotated[str | None, "The unique identifier for the store where the product variant will be added.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    product_id: Annotated[str | None, "The ID for the product within a store to which a new variant will be added.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postEcommerceStoresIdProductsIdVariants'."]:  # noqa: E501
    """Add a new variant to an existing product in Mailchimp.

    This tool is used to add a new variant to an existing product within a specific store on Mailchimp. Use this when you need to add, update, or expand product options such as sizes or colors within your Mailchimp store.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires path parameters.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.\n      Note: You must also provide the required path parameters when executing.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["ADDPRODUCTVARIANTMAILCHIMP"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter along with the required path parameters. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters
    # Validate required parameters
    missing_params = []
    if not store_identifier:
        missing_params.append(("store_identifier", "path"))
    if not product_id:
        missing_params.append(("product_id", "path"))

    if missing_params:
        param_names = [p[0] for p in missing_params]
        param_details = ", ".join(
            [f"{p[0]} ({p[1]})" for p in missing_params]
        )
        raise RetryableToolError(
            message=f"Missing required parameters: {param_names}",
            developer_message=(
                f"Required parameters validation failed: {param_details}"
            ),
            additional_prompt_content=(
                f"The following required parameters are missing: "
                f"{param_details}. Please call this tool again with all "
                "required parameters."
            ),
        )


    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["ADDPRODUCTVARIANTMAILCHIMP"] + "\n```"  # noqa: E501
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["ADDPRODUCTVARIANTMAILCHIMP"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/ecommerce/stores/{store_id}/products/{product_id}/variants".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier, product_id=product_id),  # noqa: E501  # noqa: UP032
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["ADDPRODUCTVARIANTMAILCHIMP"],
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_product_variant_info(
    context: ToolContext,
    product_id: Annotated[str, "The ID of the product in the specified store. Required to retrieve variant details."],  # noqa: E501
    product_variant_id: Annotated[str, "The unique identifier for the product variant in the store."],  # noqa: E501
    store_id: Annotated[str, "The unique identifier for the store to query the product variant details."],  # noqa: E501
    exclude_fields: Annotated[str | None, "Comma-separated list of fields to exclude in the response. Use dot notation for sub-object parameters."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of product variant fields to return, using dot notation for sub-objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getEcommerceStoresIdProductsIdVariantsId'."]:  # noqa: E501
    """Retrieve information on a specific product variant.

    Call this tool to get detailed information about a specific product variant in an e-commerce store. Useful for fetching variant details such as size, color, price, or stock status from a specified store's product."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}/products/{product_id}/variants/{variant_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_id, product_id=product_id, variant_id=product_variant_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def update_product_variant(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    store_identifier: Annotated[str | None, "The unique identifier for the ecommerce store.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    product_identifier: Annotated[str | None, "The unique identifier for the product in the store. This ID is used to specify which product's variant is being added or updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    product_variant_id: Annotated[str | None, "The unique identifier for the product variant to be updated or added.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'putEcommerceStoresIdProductsIdVariantsId'."]:  # noqa: E501
    """Add or update a product variant in an ecommerce store.

    Use this tool to add a new product variant or update an existing one in a specified ecommerce store.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires path parameters.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.\n      Note: You must also provide the required path parameters when executing.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["UPDATEPRODUCTVARIANT"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter along with the required path parameters. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters
    # Validate required parameters
    missing_params = []
    if not store_identifier:
        missing_params.append(("store_identifier", "path"))
    if not product_identifier:
        missing_params.append(("product_identifier", "path"))
    if not product_variant_id:
        missing_params.append(("product_variant_id", "path"))

    if missing_params:
        param_names = [p[0] for p in missing_params]
        param_details = ", ".join(
            [f"{p[0]} ({p[1]})" for p in missing_params]
        )
        raise RetryableToolError(
            message=f"Missing required parameters: {param_names}",
            developer_message=(
                f"Required parameters validation failed: {param_details}"
            ),
            additional_prompt_content=(
                f"The following required parameters are missing: "
                f"{param_details}. Please call this tool again with all "
                "required parameters."
            ),
        )


    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["UPDATEPRODUCTVARIANT"] + "\n```"
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["UPDATEPRODUCTVARIANT"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/ecommerce/stores/{store_id}/products/{product_id}/variants/{variant_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier, product_id=product_identifier, variant_id=product_variant_id),  # noqa: E501  # noqa: UP032
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEPRODUCTVARIANT"],
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def modify_product_variant(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    store_identifier: Annotated[str | None, "A unique identifier for the store where the product variant will be updated. Must be a string.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    product_identifier: Annotated[str | None, "The unique identifier for a product in a store.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    product_variant_id: Annotated[str | None, "The ID for the product variant to be updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'."] = None,  # noqa: E501

    request_body: Annotated[
        str | None,
        "Stringified JSON representing the request body. Required when "
        "mode is 'execute', ignored when mode is 'get_request_schema'",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'patchEcommerceStoresIdProductsIdVariantsId'."]:  # noqa: E501
    """Update a product variant in an e-commerce store.

    Use this tool to update the details of a specific product variant in a designated e-commerce store. This is useful for changing attributes of a variant, such as pricing, stock level, or other details.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires path parameters.

    Modes:
    - GET_REQUEST_SCHEMA: Returns the schema. Only call if you don't
      already have it. Do NOT call repeatedly if you already received
      the schema.
    - EXECUTE: Performs the operation with the provided request body
      JSON.\n      Note: You must also provide the required path parameters when executing.

    If you need the schema, call with mode='get_request_schema' ONCE, then execute.
    """  # noqa: E501
    if mode == ToolMode.GET_REQUEST_SCHEMA:
        return {
            "request_body_schema": REQUEST_BODY_SCHEMAS["MODIFYPRODUCTVARIANT"],
            "instructions": (
                "Use the request_body_schema to construct a valid JSON object. "
                "Once you have populated the object following the schema "
                "structure and requirements, call this tool again with "
                "mode='execute' and the stringified JSON as the "
                "request_body parameter along with the required path parameters. "
                "Do NOT call the schema mode again - you already have "
                "the schema now."
            ),
        }

    # Mode is EXECUTE - validate parameters
    # Validate required parameters
    missing_params = []
    if not store_identifier:
        missing_params.append(("store_identifier", "path"))
    if not product_identifier:
        missing_params.append(("product_identifier", "path"))
    if not product_variant_id:
        missing_params.append(("product_variant_id", "path"))

    if missing_params:
        param_names = [p[0] for p in missing_params]
        param_details = ", ".join(
            [f"{p[0]} ({p[1]})" for p in missing_params]
        )
        raise RetryableToolError(
            message=f"Missing required parameters: {param_names}",
            developer_message=(
                f"Required parameters validation failed: {param_details}"
            ),
            additional_prompt_content=(
                f"The following required parameters are missing: "
                f"{param_details}. Please call this tool again with all "
                "required parameters."
            ),
        )


    # Validate request body is provided (not None or empty string)
    # Note: Empty objects like {} are allowed - schema validation will check if valid
    if request_body is None or request_body.strip() == "":
        raise RetryableToolError(
            message="Request body is required when mode is 'execute'",
            developer_message="The request_body parameter was null or empty string",
            additional_prompt_content=(
                "The request body is required to perform this operation. "
                "Use the schema below to construct a valid JSON object, "
                "then call this tool again in execute mode with the "
                "stringified JSON as the request_body parameter.\n\n"
                "Schema:\n\n```json\n" + REQUEST_BODY_SCHEMAS["MODIFYPRODUCTVARIANT"] + "\n```"
            ),
        )

    # Parse JSON
    try:
        request_data = json.loads(request_body)
    except json.JSONDecodeError as e:
        raise RetryableToolError(
            message=f"Invalid JSON in request body: {e!s}",
            developer_message=f"JSON parsing failed: {e!s}",
            additional_prompt_content=(
                f"The request body contains invalid JSON. Error: {e!s}\n\n"
                "Please provide a valid JSON string that matches the schema "
                "below, then call this tool again in execute mode.\n\n"
                "Schema:\n\n```json\n"+ REQUEST_BODY_SCHEMAS["MODIFYPRODUCTVARIANT"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="{base_url}/ecommerce/stores/{store_id}/products/{product_id}/variants/{variant_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier, product_id=product_identifier, variant_id=product_variant_id),  # noqa: E501  # noqa: UP032
        method="PATCH",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["MODIFYPRODUCTVARIANT"],
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def delete_product_variant(
    context: ToolContext,
    product_id: Annotated[str, "The unique identifier for the product within a store to which the variant belongs."],  # noqa: E501
    product_variant_id: Annotated[str, "The identifier for the product variant to be deleted from the store."],  # noqa: E501
    store_identifier: Annotated[str, "The unique identifier for the store from which the product variant will be deleted."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteEcommerceStoresIdProductsIdVariantsId'."]:  # noqa: E501
    """Delete a product variant from an ecommerce store.

    Use this tool to delete a specific product variant in an ecommerce store on Mailchimp. Ideal for managing product inventories by removing obsolete or discontinued variants."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}/products/{product_id}/variants/{variant_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier, product_id=product_id, variant_id=product_variant_id),  # noqa: E501  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_product_images(
    context: ToolContext,
    product_identifier: Annotated[str, "The unique identifier for a product in a specific store. Required to retrieve product image details."],  # noqa: E501
    store_id: Annotated[str, "The unique identifier for the e-commerce store."],
    exclude_fields: Annotated[str | None, "A comma-separated list of fields to exclude from the response using dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to return. Use dot notation for sub-objects."] = None,  # noqa: E501
    number_of_records_to_return: Annotated[str | None, "Specify the number of product image records to return, ranging from 1 to 1000. Defaults to 10 if not provided."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "The number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getEcommerceStoresIdProductsIdImages'."]:  # noqa: E501
    """Retrieve information about a product's images.

    Call this tool to obtain details about images associated with a specific product in an e-commerce store."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}/products/{product_id}/images".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_id, product_id=product_identifier),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields, "count": number_of_records_to_return, "offset": pagination_offset}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def add_product_image(
    context: ToolContext,
    product_id: Annotated[str, "The unique identifier for the product in the store. Required to specify which product the image will be added to."],  # noqa: E501
    product_image_id: Annotated[str, "A unique identifier for the product image to be added."],
    product_image_url: Annotated[str, "The URL of the image to be added to the product."],
    store_id: Annotated[str, "The unique identifier for the store where the product is hosted. Required to specify which store's catalog you are updating."],  # noqa: E501
    product_variant_ids: Annotated[list[str] | None, "List of product variant IDs using the image."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'postEcommerceStoresIdProductsIdImages'."]:  # noqa: E501
    """Add a new image to a specific product.

    This tool is used to add a new image to an existing product in a store's e-commerce catalog. It should be called when you need to update the product's visual information by uploading an additional image."""  # noqa: E501
    request_data: Any = {"id": product_image_id, "url": product_image_url, "variant_ids": product_variant_ids}  # noqa: E501
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}/products/{product_id}/images".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_id, product_id=product_id),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_product_image_info(
    context: ToolContext,
    product_identifier: Annotated[str, "The unique identifier for the product in the store."],
    product_image_id: Annotated[str, "The unique identifier for the product image to retrieve details about."],  # noqa: E501
    store_identifier: Annotated[str, "The unique identifier of the store. Used to specify the store whose product image information is to be retrieved."],  # noqa: E501
    exclude_fields_list: Annotated[str | None, "A comma-separated list of fields to exclude, using dot notation for sub-object parameters."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to return. Use dot notation for sub-object fields."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getEcommerceStoresIdProductsIdImagesId'."]:  # noqa: E501
    """Retrieve details of a specific product image in an eCommerce store.

    Use this tool to get information about a specific image associated with a product in an eCommerce store. Ideal for obtaining image metadata or details for display or analysis purposes."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}/products/{product_id}/images/{image_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier, product_id=product_identifier, image_id=product_image_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields_list}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def update_product_image_mailchimp(
    context: ToolContext,
    product_identifier: Annotated[str, "The unique identifier for a product in the store. Used to specify which product's image should be updated."],  # noqa: E501
    product_image_id: Annotated[str, "The unique identifier for the product image to update."],
    store_id: Annotated[str, "The unique identifier for the e-commerce store."],
    product_image_unique_id: Annotated[str | None, "A unique identifier for a specific product image to be updated in the store."] = None,  # noqa: E501
    product_image_url: Annotated[str | None, "The URL of the product image to be updated."] = None,
    variant_ids: Annotated[list[str] | None, "A list of product variant IDs associated with the image. Each variant ID should be a string."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'patchEcommerceStoresIdProductsIdImagesId'."]:  # noqa: E501
    """Update a product image in an e-commerce store.

    This tool updates a specific product image within a Mailchimp e-commerce store. Use it when you need to modify an image associated with a product in a store managed by Mailchimp."""  # noqa: E501
    request_data: Any = {"id": product_image_unique_id, "url": product_image_url, "variant_ids": variant_ids}  # noqa: E501
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}/products/{product_id}/images/{image_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_id, product_id=product_identifier, image_id=product_image_id),  # noqa: E501  # noqa: UP032
        method="PATCH",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def delete_product_image(
    context: ToolContext,
    product_id: Annotated[str, "The unique ID for the product in the store from which the image will be deleted."],  # noqa: E501
    product_image_id: Annotated[str, "The unique identifier for the product image to be deleted from the store's inventory."],  # noqa: E501
    store_identifier: Annotated[str, "The unique identifier for the e-commerce store."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteEcommerceStoresIdProductsIdImagesId'."]:  # noqa: E501
    """Delete an image from a product in an e-commerce store.

    This tool deletes a specified image from a product within an e-commerce store, identified by store, product, and image IDs. It should be called when a product image needs to be removed from a store's inventory."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ecommerce/stores/{store_id}/products/{product_id}/images/{image_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), store_id=store_identifier, product_id=product_id, image_id=product_image_id),  # noqa: E501  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def search_mailchimp_campaigns(
    context: ToolContext,
    search_query: Annotated[str, "The terms used to filter and search Mailchimp campaigns."],
    exclude_campaign_fields: Annotated[str | None, "Comma-separated list of fields to exclude from the search results. Use dot notation for sub-objects."] = None,  # noqa: E501
    included_fields: Annotated[str | None, "Specify the fields to return as a comma-separated list. Use dot notation for sub-object parameters."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getSearchCampaigns'."]:
    """Search for email campaigns using query terms.

    Use this tool to search all Mailchimp email campaigns that match specific query terms. This can help find campaigns based on certain criteria or keywords."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/search-campaigns".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": included_fields, "exclude_fields": exclude_campaign_fields, "query": search_query}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def search_mailchimp_members(
    context: ToolContext,
    search_query: Annotated[str, "The search query to filter list members by email, first name, or last name."],  # noqa: E501
    fields_to_exclude: Annotated[str | None, "A comma-separated list specifying which fields to exclude from results. Use dot notation for sub-object references."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "Comma-separated list of fields to return, using dot notation for sub-objects."] = None,  # noqa: E501
    list_unique_id: Annotated[str | None, "The unique identifier for a Mailchimp list to restrict the search. Use this to specify a particular list."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getSearchMembers'."]:
    """Search for Mailchimp list members across lists.

    Search for list members in Mailchimp. This can be restricted to a specific list or used to search across all lists in an account."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/search-members".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": fields_to_exclude, "query": search_query, "list_id": list_unique_id}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def check_mailchimp_api_health(
    context: ToolContext,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getPing'."]:
    """Checks the health status of the Mailchimp API.

    Use this tool to verify the operational status of the Mailchimp Marketing API and ensure it's running without issues. This check does not return account-specific data."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/ping".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_facebook_ads_list(
    context: ToolContext,
    exclude_fields: Annotated[str | None, "A comma-separated list of fields to exclude. Utilize dot notation for sub-object fields."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of specific fields to return in the response. Use dot notation for sub-object parameters."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "The number of records to skip for pagination, with a default of 0."] = None,  # noqa: E501
    records_count: Annotated[str | None, "Specify the number of Facebook ad records to return. Default is 10, maximum is 1000."] = None,  # noqa: E501
    sort_by_field: Annotated[str | None, "Specify the field by which to sort the Facebook ads."] = None,  # noqa: E501
    sort_direction: Annotated[str | None, "Specifies the sorting order: 'asc' for ascending or 'desc' for descending."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getAllFacebookAds'."]:
    """Retrieve a list of Facebook ads from Mailchimp.

    Use this tool to obtain a list of Facebook ads managed within Mailchimp. Ideal for getting an overview of current ad campaigns."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/facebook-ads".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields, "count": records_count, "offset": pagination_offset, "sort_field": sort_by_field, "sort_dir": sort_direction}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_facebook_ad_details(
    context: ToolContext,
    facebook_ad_outreach_id: Annotated[str, "The unique outreach ID of the Facebook ad to retrieve details for."],  # noqa: E501
    exclude_fields_list: Annotated[str | None, "A comma-separated list of fields to exclude using dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "Comma-separated list of fields to return; use dot notation for sub-object parameters."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getFacebookAdsId'."]:
    """Retrieve details of a specific Facebook ad campaign.

    Use this tool to fetch detailed information about a specific Facebook ad by providing its outreach ID. This can be helpful for tracking ad performance or reviewing campaign specifics."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/facebook-ads/{outreach_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), outreach_id=facebook_ad_outreach_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields_list}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_facebook_ads_reports(
    context: ToolContext,
    exclude_fields: Annotated[str | None, "A comma-separated list of fields to exclude in the report. Use dot notation for sub-objects if needed."] = None,  # noqa: E501
    include_fields: Annotated[str | None, "Comma-separated list of fields to return. Use dot notation for sub-object parameters."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "The number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
    record_count: Annotated[str | None, "Specify the number of Facebook ads records to return. Default is 10, maximum is 1000."] = None,  # noqa: E501
    sort_order_direction: Annotated[str | None, "Specifies the order direction for sorting results. Use 'asc' for ascending and 'desc' for descending."] = None,  # noqa: E501
    sorting_field_for_results: Annotated[str | None, "Specifies the field by which to sort the Facebook ads report results."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportingFacebookAds'."]:
    """Get reports of Facebook ads for marketing analysis.

    Use this tool to retrieve detailed reports of Facebook ads data, which can be essential for analyzing marketing campaigns and performance metrics."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/reporting/facebook-ads".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": include_fields, "exclude_fields": exclude_fields, "count": record_count, "offset": pagination_offset, "sort_field": sorting_field_for_results, "sort_dir": sort_order_direction}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_facebook_ad_report(
    context: ToolContext,
    outreach_id: Annotated[str, "The unique identifier for the Facebook ad campaign to retrieve the report for."],  # noqa: E501
    fields_to_exclude: Annotated[str | None, "List of fields to exclude from the report, using comma-separated values. Use dot notation for sub-object parameters."] = None,  # noqa: E501
    include_fields: Annotated[str | None, "A comma-separated list of fields to return. Use dot notation for sub-object parameters."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportingFacebookAdsId'."]:
    """Get report details of a Facebook ad campaign.

    Use this tool to retrieve detailed reports of a specific Facebook advertisement managed through Mailchimp. This is useful for analyzing ad performance and outreach impact."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/reporting/facebook-ads/{outreach_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), outreach_id=outreach_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": include_fields, "exclude_fields": fields_to_exclude}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_facebook_ads_product_activity(
    context: ToolContext,
    outreach_id: Annotated[str, "The unique identifier for the Facebook ads outreach campaign to retrieve the product activity breakdown."],  # noqa: E501
    exclude_fields: Annotated[str | None, "Comma-separated list of fields to exclude using dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to include in the response, using dot notation for sub-objects."] = None,  # noqa: E501
    number_of_records_to_return: Annotated[str | None, "The number of records to return. Default is 10. Maximum is 1000."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "Number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
    sort_by_field: Annotated[str | None, "Specify the field to sort the returned records by, using the field name."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportingFacebookAdsIdEcommerceProductActivity'."]:  # noqa: E501
    """Retrieve product activity breakdown for a Facebook ads outreach.

    This tool provides a breakdown of ecommerce product activity for a specific Facebook ads outreach campaign. It should be called when detailed analytics of product performance related to a Facebook ad outreach is needed."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/reporting/facebook-ads/{outreach_id}/ecommerce-product-activity".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), outreach_id=outreach_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields, "count": number_of_records_to_return, "offset": pagination_offset, "sort_field": sort_by_field}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_landing_page_report(
    context: ToolContext,
    landing_page_outreach_id: Annotated[str, "The outreach ID for the landing page you want to retrieve the report for."],  # noqa: E501
    exclude_report_fields: Annotated[str | None, "A comma-separated list of fields to exclude from the landing page report. Use dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to return, using dot notation for sub-objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportingLandingPagesId'."]:
    """Retrieve the report for a specific landing page.

    Use this tool to get detailed reports on specific landing pages via their ID. Useful for analyzing landing page performance and metrics."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/reporting/landing-pages/{outreach_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), outreach_id=landing_page_outreach_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_report_fields}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_landing_page_reports(
    context: ToolContext,
    fields_to_exclude: Annotated[str | None, "A comma-separated list of fields to exclude from the report. Use dot notation for sub-objects."] = None,  # noqa: E501
    include_fields: Annotated[str | None, "A comma-separated list of fields to include in the response, using dot notation for sub-objects."] = None,  # noqa: E501
    number_of_records_to_return: Annotated[str | None, "Specify the number of records to return, from 1 to 1000. Defaults to 10 if not provided."] = None,  # noqa: E501
    records_to_skip: Annotated[str | None, "The number of records to skip for pagination. Default is 0."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportingLandingPages'."]:
    """Retrieve reports of landing pages from Mailchimp.

    Use this tool to get detailed analytics and reports on landing pages set up in Mailchimp. Ideal for understanding performance metrics and engagement data."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/reporting/landing-pages".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": include_fields, "exclude_fields": fields_to_exclude, "count": number_of_records_to_return, "offset": records_to_skip}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_survey_reports(
    context: ToolContext,
    fields_to_exclude: Annotated[str | None, "A comma-separated list of fields to exclude from survey reports. Use dot notation for sub-object fields."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to return. Use dot notation for sub-objects."] = None,  # noqa: E501
    number_of_records: Annotated[str | None, "The number of survey report records to return. Defaults to 10. Max value is 1000."] = None,  # noqa: E501
    pagination_offset: Annotated[str | None, "Number of records to skip for pagination, default is 0."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportingSurveys'."]:
    """Retrieve detailed reports for marketing surveys.

    Use this tool to obtain detailed reports and insights from marketing surveys. Ideal for analyzing survey results and performance metrics."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/reporting/surveys".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": fields_to_exclude, "count": number_of_records, "offset": pagination_offset}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_survey_report(
    context: ToolContext,
    survey_id: Annotated[str, "The unique ID of the survey to retrieve the report for."],
    exclude_fields_list: Annotated[str | None, "A comma-separated list of fields to exclude from the survey report. Use dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "A comma-separated list of fields to include in the survey report. Use dot notation for sub-objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportingSurveysId'."]:
    """Retrieve report details for a specific survey.

    Call this tool to get comprehensive report details for a specified survey. Use this to analyze survey responses and results."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/reporting/surveys/{survey_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), survey_id=survey_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields_list}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_survey_question_reports(
    context: ToolContext,
    survey_identifier: Annotated[str, "The unique identifier for the survey to retrieve question reports."],  # noqa: E501
    exclude_fields_from_report: Annotated[str | None, "A comma-separated list of fields to exclude from the survey report. Use dot notation for nested fields."] = None,  # noqa: E501
    include_fields: Annotated[str | None, "Comma-separated list of fields to return for survey questions. Use dot notation for sub-object parameters."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportingSurveysIdQuestions'."]:
    """Retrieve reports for survey questions by survey ID.

    Use this tool to obtain data regarding the responses to each question within a specific survey. Ideal for analyzing survey results and gaining insights."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/reporting/surveys/{survey_id}/questions".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), survey_id=survey_identifier),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": include_fields, "exclude_fields": exclude_fields_from_report}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_survey_question_report(
    context: ToolContext,
    survey_id: Annotated[str, "The unique identifier for the survey. Required to retrieve specific survey question reports."],  # noqa: E501
    survey_question_id: Annotated[str, "The unique ID of the survey question to get the report for."],  # noqa: E501
    fields_to_exclude: Annotated[str | None, "A comma-separated list of fields to exclude from the survey question report, using dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "Comma-separated list of fields to return using dot notation for sub-objects."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportingSurveysIdQuestionsId'."]:  # noqa: E501
    """Get report data for a specific survey question.

    Use this tool to retrieve detailed report information for a specific question in a survey. Useful for analyzing responses and performance of survey questions."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/reporting/surveys/{survey_id}/questions/{question_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), survey_id=survey_id, question_id=survey_question_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": fields_to_exclude}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_survey_question_answers(
    context: ToolContext,
    survey_identifier: Annotated[str, "The unique identifier for the survey whose question answers are being retrieved."],  # noqa: E501
    survey_question_id: Annotated[str, "The unique identifier for the survey question to retrieve answers from."],  # noqa: E501
    exclude_fields: Annotated[str | None, "Specify fields to exclude from the response using a comma-separated list. Use dot notation for sub-objects."] = None,  # noqa: E501
    fields_to_return: Annotated[str | None, "Comma-separated list of fields to return, using dot notation for sub-objects."] = None,  # noqa: E501
    filter_by_respondent_familiarity: Annotated[str | None, "Filter survey responses based on the familiarity level of the respondents. Accepts a string value."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportingSurveysIdQuestionsIdAnswers'."]:  # noqa: E501
    """Retrieve answers for a specific survey question.

    Use this tool to get answers for a particular question in a given survey. Useful for analyzing survey responses to specific questions within Mailchimp."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/reporting/surveys/{survey_id}/questions/{question_id}/answers".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), survey_id=survey_identifier, question_id=survey_question_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": fields_to_return, "exclude_fields": exclude_fields, "respondent_familiarity_is": filter_by_respondent_familiarity}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_survey_responses(
    context: ToolContext,
    survey_id: Annotated[str, "The unique identifier for the survey to retrieve responses for."],
    chosen_answer_id: Annotated[str | None, "The ID of the selected answer option to filter survey responses."] = None,  # noqa: E501
    exclude_survey_fields: Annotated[str | None, "A comma-separated list of fields to exclude from survey responses. Use dot notation for sub-objects."] = None,  # noqa: E501
    filter_by_respondent_familiarity: Annotated[str | None, "Filter survey responses by respondents' familiarity level. Provide a familiarity string to narrow down results."] = None,  # noqa: E501
    included_fields: Annotated[str | None, "A comma-separated list of fields to return in the response. Use dot notation for sub-objects."] = None,  # noqa: E501
    question_id: Annotated[str | None, "The ID of the question that was answered to filter responses."] = None,  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportingSurveysIdResponses'."]:
    """Retrieve responses to a specific survey.

    Use this tool to obtain responses from a specific survey when you have the survey ID."""
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/reporting/surveys/{survey_id}/responses".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), survey_id=survey_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({"fields": included_fields, "exclude_fields": exclude_survey_fields, "answered_question": question_id, "chose_answer": chosen_answer_id, "respondent_familiarity_is": filter_by_respondent_familiarity}),  # noqa: E501
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_survey_response(
    context: ToolContext,
    survey_id: Annotated[str, "The ID of the survey to retrieve the response from."],
    survey_response_id: Annotated[str, "The ID of the specific survey response to retrieve."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getReportingSurveysIdResponsesId'."]:  # noqa: E501
    """Retrieve details of a specific survey response.

    Call this tool to get detailed information of a particular survey response using its survey and response IDs."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/reporting/surveys/{survey_id}/responses/{response_id}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), survey_id=survey_id, response_id=survey_response_id),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_domain_details(
    context: ToolContext,
    domain_name: Annotated[str, "The domain name to retrieve details for. Must be a verified domain on the account."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getVerifiedDomain'."]:
    """Retrieve details for a specific verified domain.

    Use this tool to get the details of a single verified domain on your Mailchimp account. Useful for accessing domain-specific information."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/verified-domains/{domain_name}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), domain_name=domain_name),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def delete_verified_domain(
    context: ToolContext,
    domain_name: Annotated[str, "The domain name to be deleted from your Mailchimp account."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteVerifiedDomain'."]:
    """Deletes a verified domain from your Mailchimp account.

    Use this tool to remove a domain that has been previously verified in your Mailchimp account. Ideal for situations where a domain is no longer needed or has ownership changes."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/verified-domains/{domain_name}".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), domain_name=domain_name),  # noqa: E501  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def verify_sending_domain(
    context: ToolContext,
    domain_name_to_verify: Annotated[str, "The domain name you wish to verify for sending emails through Mailchimp."],  # noqa: E501
    verification_code: Annotated[str, "The code sent to the provided email address for domain verification."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'verifyDomain'."]:
    """Verify if a domain is authorized for sending emails.

    Use this tool to verify whether a specific domain is authorized for sending emails through Mailchimp. It should be called when you need to confirm the sending capabilities of a domain."""  # noqa: E501
    request_data: Any = {"code": verification_code}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/verified-domains/{domain_name}/actions/verify".format(base_url=await utils.get_base_url(context, HTTP_CLIENT), domain_name=domain_name_to_verify),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def get_verified_mailchimp_domains(
    context: ToolContext,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getVerifiedDomains'."]:
    """Retrieve all verified sending domains for a Mailchimp account.

    This tool retrieves the list of all sending domains verified on a Mailchimp account. It should be called when users want to view their registered sending domains."""  # noqa: E501
    request_data: Any = {}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/verified-domains".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: E501  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({"Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-mailchimp"))
async def add_verified_domain(
    context: ToolContext,
    verification_email_address: Annotated[str, "The email address at the domain to verify, which will receive a two-factor challenge for verification."],  # noqa: E501
) -> Annotated[dict[str, Any], "Response from the API endpoint 'createVerifiedDomain'."]:
    """Add a verified domain to your Mailchimp account.

    Use this tool to add a verified domain to your Mailchimp account. This is useful for managing communication and ensuring trust with your recipients."""  # noqa: E501
    request_data: Any = {"verification_email": verification_email_address}
    if isinstance(request_data, dict):
        request_data = remove_none_values(request_data)
    content = json.dumps(request_data) if request_data else None
    response = await make_request(
        url="{base_url}/verified-domains".format(base_url=await utils.get_base_url(context, HTTP_CLIENT)),  # noqa: E501  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({"Content-Type": "application/json", "Authorization": "Bearer {authorization}".format(authorization=context.get_auth_token_or_empty())}),  # noqa: E501  # noqa: UP032
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}
