"""Arcade Starter Tools for Airtable

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
from typing import Annotated, Any

import httpx
from arcade_tdk import ToolContext, tool
from arcade_tdk.auth import OAuth2

# 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,
)


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,
    data: dict[str, Any] | 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,
                method=method,
                params=params,
                headers=headers,
                data=data,
            )
            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:
            # 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


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["enterprise.scim.usersAndGroups:manage"]))
async def list_scim_groups(
    context: ToolContext,
    maximum_results: Annotated[
        float | None,
        "Specifies the maximum number of SCIM group objects to return. Must be a positive integer.",
    ] = None,
    group_filter: Annotated[
        str | None, "A SCIM filter expression to narrow down group results based on attributes."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'list-scim-groups'."]:
    """Retrieve a list of SCIM groups from Airtable.

    This tool calls the Airtable API to list groups in the form of SCIM Group objects, following the SCIM specification for list responses. Use it when you need to access or manage groups in the SCIM format."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/scim/v2/Groups",
        method="GET",
        params=remove_none_values({"count": maximum_results, "filter": group_filter}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["enterprise.scim.usersAndGroups:manage"]))
async def delete_scim_group(
    context: ToolContext,
    scim_group_id: Annotated[
        str,
        "The unique identifier for the SCIM group to be deleted. This ID specifies which group you intend to delete and must match an existing group.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'delete-scim-group'."]:
    """Delete a specific SCIM group by ID.

    Use this tool to delete a SCIM group specified by its group ID. Ideal for removing outdated or unnecessary groups."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/scim/v2/Groups/{groupId}".format(groupId=scim_group_id),  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["enterprise.scim.usersAndGroups:manage"]))
async def get_scim_group_info(
    context: ToolContext,
    scim_group_id: Annotated[str, "The unique ID of the SCIM Group to retrieve details for."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'get-scim-group'."]:
    """Retrieve details of a SCIM Group object by ID.

    Use this tool to get detailed information about a SCIM Group object using its unique ID. It is useful when you need group metadata and attributes compliant with SCIM standards."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/scim/v2/Groups/{groupId}".format(groupId=scim_group_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["enterprise.scim.usersAndGroups:manage"]))
async def list_scim_users(
    context: ToolContext,
    start_index: Annotated[
        float | None, "The starting index for listing SCIM users. Must be a positive integer."
    ] = None,
    max_number_of_users: Annotated[
        float | None,
        "Specifies the maximum number of SCIM users to retrieve. This number determines how many user objects will be returned in the response.",  # noqa: E501
    ] = None,
    user_filter_query: Annotated[
        str | None,
        "A string query to filter SCIM users based on specific attributes, following SCIM filtering syntax.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'list-scim-users'."]:
    """Retrieve a list of SCIM user objects.

    This tool retrieves a list of users in the SCIM User format, following the SCIM specification. It's useful for managing user directories and data synchronization."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/scim/v2/Users",
        method="GET",
        params=remove_none_values({
            "startIndex": start_index,
            "count": max_number_of_users,
            "filter": user_filter_query,
        }),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["enterprise.scim.usersAndGroups:manage"]))
async def delete_scim_user(
    context: ToolContext,
    user_id: Annotated[
        str,
        "The unique identifier of the SCIM user to be deleted. Ensure it is not the admin using the auth token or the sole owner of a multi-collaborator workspace.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'delete-scim-user'."]:
    """Delete a single SCIM user from Airtable.

    Use this tool to delete a SCIM user from Airtable, except for the admin owning the authentication token or the sole owner of a workspace with multiple collaborators."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/scim/v2/Users/{userId}".format(userId=user_id),  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["enterprise.scim.usersAndGroups:manage"]))
async def fetch_scim_user(
    context: ToolContext,
    user_id: Annotated[
        str,
        "The unique identifier of the SCIM user to be retrieved. Provide the user ID to fetch the user's SCIM object.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'get-scim-user'."]:
    """Fetches a SCIM User object by user ID.

    Call this tool to get detailed information about a specific user in the SCIM format by providing the user's ID."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/scim/v2/Users/{userId}".format(userId=user_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["webhook:manage"]))
async def list_webhooks_for_base(
    context: ToolContext,
    base_id: Annotated[
        str,
        "The unique identifier for the Airtable base to list webhooks for. Requires read permissions.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'list-webhooks'."]:
    """List all webhooks for a specified base.

    Fetches and lists all registered webhooks for a given base in Airtable, including their statuses. Requires read permissions."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/bases/{baseId}/webhooks".format(baseId=base_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["webhook:manage"]))
async def delete_airtable_webhook(
    context: ToolContext,
    airtable_base_id: Annotated[
        str,
        "The unique identifier for the Airtable base. Required to specify which base contains the webhook to delete.",  # noqa: E501
    ],
    webhook_id: Annotated[
        str, "The unique identifier for the webhook you wish to delete. This is required."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'delete-a-webhook'."]:
    """Deletes an Airtable webhook.

    Use this tool to delete an existing webhook in Airtable. Creator level permissions are required."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/bases/{baseId}/webhooks/{webhookId}".format(  # noqa: UP032
            baseId=airtable_base_id, webhookId=webhook_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable"))
async def retrieve_webhook_payloads(
    context: ToolContext,
    airtable_base_id: Annotated[
        str,
        "The unique identifier for the Airtable base from which to retrieve webhook update messages.",  # noqa: E501
    ],
    webhook_identifier: Annotated[
        str,
        "The unique identifier for the Airtable webhook whose payloads are to be retrieved. This is necessary to specify which webhook's updates need to be listed.",  # noqa: E501
    ],
    pagination_cursor: Annotated[
        float | None,
        "Numeric cursor for paginating through webhook payloads. Useful for retrieving additional pages of data.",  # noqa: E501
    ] = None,
    max_payload_entries: Annotated[
        float | None,
        "The maximum number of payload entries to retrieve. This helps manage the volume of data returned by the endpoint.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'list-webhook-payloads'."]:
    """Retrieve update messages for Airtable webhooks.

    This tool retrieves the update messages from an Airtable webhook to ensure clients receive them after a ping event. It also extends the webhook's expiration time to 7 days from the call, ensuring continued activation if the webhook remains active."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/bases/{baseId}/webhooks/{webhookId}/payloads".format(  # noqa: UP032
            baseId=airtable_base_id, webhookId=webhook_identifier
        ),
        method="GET",
        params=remove_none_values({"cursor": pagination_cursor, "limit": max_payload_entries}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["webhook:manage"]))
async def extend_webhook_expiration(
    context: ToolContext,
    airtable_base_id: Annotated[
        str,
        "The unique identifier for the Airtable base. Required to specify which base contains the webhook.",  # noqa: E501
    ],
    webhook_identifier: Annotated[
        str,
        "The unique identifier for the webhook to be refreshed. This is required to specify which webhook's expiration time you wish to extend.",  # noqa: E501
    ],
    webhook_refresh_request: Annotated[
        dict[str, str] | None,
        "A JSON object containing specifics for the webhook refresh request. This includes relevant details needed for processing the expiration extension.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'refresh-a-webhook'."]:
    """Extend the expiration time of an Airtable webhook.

    Use this tool to extend the life of an active Airtable webhook by 7 days from the refresh time. Requires creator level permissions."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/bases/{baseId}/webhooks/{webhookId}/refresh".format(  # noqa: UP032
            baseId=airtable_base_id, webhookId=webhook_identifier
        ),
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({"requestBody": webhook_refresh_request}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["schema.bases:read"]))
async def get_accessible_airtable_bases(
    context: ToolContext,
    pagination_offset: Annotated[
        str | None,
        "The offset token for paginating through results. Use it to retrieve the next set of Airtable bases.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'list-bases'."]:
    """Retrieve the list of accessible Airtable bases.

    Use this tool to get a list of the bases that the provided token can access. This is useful for managing or displaying base information in Airtable."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/meta/bases",
        method="GET",
        params=remove_none_values({"offset": pagination_offset}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["workspacesAndBases:manage"]))
async def delete_airtable_base(
    context: ToolContext,
    airtable_base_id: Annotated[
        str, "The unique identifier of the Airtable base to delete. It should be a string."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'delete-base'."]:
    """Delete a specified Airtable base.

    Use this tool to delete an Airtable base when it is no longer needed. Deleted bases can be restored by workspace owners from the Trash UI, subject to the workspace's billing plan retention period."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/meta/bases/{baseId}".format(baseId=airtable_base_id),  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["workspacesAndBases:read"]))
async def get_base_collaborators(
    context: ToolContext,
    base_id: Annotated[
        str,
        "The unique identifier for the Airtable base from which you want to retrieve collaborator information.",  # noqa: E501
    ],
    fields_to_include: Annotated[
        list[str] | None,
        "A list of fields to return for each collaborator. Example: ['name', 'email'].",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'get-base-collaborators'."]:
    """Retrieve basic information about base collaborators.

    Use this tool to get details on collaborators associated with a specific base, excluding any deleted collaborators and including outstanding invites."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/meta/bases/{baseId}".format(baseId=base_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({"include": fields_to_include}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["workspacesAndBases:read"]))
async def list_base_block_installations(
    context: ToolContext,
    base_identifier: Annotated[
        str, "Unique identifier for the Airtable base to list block installations from."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'list-block-installations'."]:
    """Lists basic information of base block installations.

    Use this tool to retrieve details about block installations in a specific Airtable base. It provides an overview of the blocks attached to the base, useful for managing or reviewing installed blocks."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/meta/bases/{baseId}/blockInstallations".format(  # noqa: UP032
            baseId=base_identifier
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["workspacesAndBases:write"]))
async def delete_airtable_block_installation(
    context: ToolContext,
    airtable_base_id: Annotated[
        str,
        "The unique identifier for the Airtable base from which the block installation will be deleted. This ID specifies the particular base in question.",  # noqa: E501
    ],
    block_installation_id: Annotated[
        str,
        "The unique identifier of the block installation to delete. This ID is required to specify which block installation to remove.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'delete-block-installation'."]:
    """Delete a block installation from an Airtable base.

    Use this tool to delete a block installation from an Airtable base. The deleted block installation can be recovered if needed."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/meta/bases/{baseId}/blockInstallations/{blockInstallationId}".format(  # noqa: UP032
            baseId=airtable_base_id, blockInstallationId=block_installation_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["workspacesAndBases:write"]))
async def remove_base_collaborator(
    context: ToolContext,
    base_identifier: Annotated[
        str,
        "The unique identifier of the Airtable base from which the collaborator will be removed. It is expected to be a string.",  # noqa: E501
    ],
    collaborator_id: Annotated[
        str, "The ID of the user or group to be removed from the Airtable base."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'delete-base-collaborator'."]:
    """Remove a collaborator from a specific Airtable base.

    Use this tool to remove a user or group from collaboration on an Airtable base. It should be called when you need to manage access and permissions of collaborators."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/meta/bases/{baseId}/collaborators/{userOrGroupId}".format(  # noqa: UP032
            baseId=base_identifier, userOrGroupId=collaborator_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["workspacesAndBases:read"]))
async def get_airtable_interface_info(
    context: ToolContext,
    airtable_base_id: Annotated[
        str, "The unique identifier for the Airtable base to retrieve interface information from."
    ],
    interface_id: Annotated[
        str,
        "The ID of the Airtable interface to retrieve information for, found in the interfaces object.",  # noqa: E501
    ],
    include_fields: Annotated[
        list[str] | None,
        "A list of fields to include in the response. Provide field names as strings.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'get-interface'."]:
    """Retrieve general information about an Airtable interface.

    This tool retrieves general information about a specified Airtable interface, excluding deleted collaborators and including outstanding invites."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/meta/bases/{baseId}/interfaces/{pageBundleId}".format(  # noqa: UP032
            baseId=airtable_base_id, pageBundleId=interface_id
        ),
        method="GET",
        params=remove_none_values({"include": include_fields}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["workspacesAndBases:write"]))
async def delete_interface_collaborator(
    context: ToolContext,
    base_id: Annotated[
        str,
        "The unique identifier of the Airtable base from which the collaborator will be removed. This ID is essential to specify the correct base for the operation.",  # noqa: E501
    ],
    page_bundle_identifier: Annotated[
        str, "The unique identifier for the page bundle from which to delete the collaborator."
    ],
    user_or_group_id: Annotated[
        str,
        "The unique identifier of the user or group to be removed from the interface. This ID specifies which collaborator is to be deleted.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'delete-interface-collaborator'."]:
    """Delete a collaborator from an Airtable interface.

    This tool removes an interface collaborator in Airtable. It requires base collaborator access to remove others but can be used to remove oneself, even with interface-only access."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/meta/bases/{baseId}/interfaces/{pageBundleId}/collaborators/{userOrGroupId}".format(  # noqa: UP032
            baseId=base_id, pageBundleId=page_bundle_identifier, userOrGroupId=user_or_group_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["workspacesAndBases:write"]))
async def delete_interface_invite(
    context: ToolContext,
    base_identifier: Annotated[
        str,
        "The unique identifier of the Airtable base from which the interface invite will be deleted. Required to specify which base contains the invite.",  # noqa: E501
    ],
    page_bundle_id: Annotated[
        str, "The ID of the page bundle containing the interface invite to be deleted."
    ],
    invite_id: Annotated[
        str, "The unique identifier for the invite to be deleted. Must be an outstanding invite."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'delete-interface-invite'."]:
    """Delete an outstanding interface invite in Airtable.

    Use this tool to delete an outstanding invitation for an interface in Airtable. The invite must be outstanding to be deleted."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/meta/bases/{baseId}/interfaces/{pageBundleId}/invites/{inviteId}".format(  # noqa: UP032
            baseId=base_identifier, pageBundleId=page_bundle_id, inviteId=invite_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["workspacesAndBases:write"]))
async def delete_base_invite(
    context: ToolContext,
    base_id: Annotated[
        str, "The unique identifier of the Airtable base from which the invite will be deleted."
    ],
    invite_identifier: Annotated[
        str, "The unique identifier of the outstanding base invite to be deleted."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'delete-base-invite'."]:
    """Delete an outstanding base invite in Airtable.

    Use this tool to delete an outstanding base invite in Airtable when you no longer need it or want to revoke access. The invite must be outstanding to be deleted."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/meta/bases/{baseId}/invites/{inviteId}".format(  # noqa: UP032
            baseId=base_id, inviteId=invite_identifier
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["workspacesAndBases.shares:manage"]))
async def list_base_shares(
    context: ToolContext,
    base_id: Annotated[str, "The unique identifier for the Airtable base to retrieve shares for."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'list-shares'."]:
    """Retrieve basic information about Airtable base shares.

    Call this tool to get information on shared Airtable bases, including details like base names and sharing status."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/meta/bases/{baseId}/shares".format(baseId=base_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["workspacesAndBases.shares:manage"]))
async def delete_airtable_share(
    context: ToolContext,
    airtable_base_id: Annotated[
        str, "The unique identifier for the Airtable base from which the share will be deleted."
    ],
    share_id_to_delete: Annotated[
        str,
        "The unique identifier of the Airtable share to be deleted. Ensure the ID is correct as this action is irreversible.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'delete-share'."]:
    """Delete a share from Airtable irreversibly.

    Use this tool to permanently delete a share from Airtable. This action cannot be undone, so ensure that deletion is intended."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/meta/bases/{baseId}/shares/{shareId}".format(  # noqa: UP032
            baseId=airtable_base_id, shareId=share_id_to_delete
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["schema.bases:read"]))
async def get_airtable_base_schema(
    context: ToolContext,
    airtable_base_id: Annotated[
        str,
        "The unique identifier for the Airtable base for which you want to retrieve the schema.",
    ],
    fields_to_include: Annotated[
        list[str] | None,
        "Specifies which fields of the tables to include in the schema response. Provide an array of field names as strings.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'get-base-schema'."]:
    """Retrieve the schema of tables in a specified Airtable base.

    Use this tool to get detailed information about the structure of tables within a specific Airtable base by providing the base ID."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/meta/bases/{baseId}/tables".format(  # noqa: UP032
            baseId=airtable_base_id
        ),
        method="GET",
        params=remove_none_values({"include": fields_to_include}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["workspacesAndBases:read"]))
async def list_airtable_views(
    context: ToolContext,
    airtable_base_id: Annotated[
        str,
        "The unique identifier of the Airtable base for which views information is to be listed.",
    ],
    fields_to_include: Annotated[
        list[str] | None,
        "Specify which fields to include in the response (e.g., view names, types).",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'list-views'."]:
    """Lists basic information of Airtable base views.

    Use this tool to obtain a list of basic information about views within a specific Airtable base. This can be useful for understanding the structure and available views in a base."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/meta/bases/{baseId}/views".format(baseId=airtable_base_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({"include": fields_to_include}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["workspacesAndBases:write"]))
async def delete_airtable_view(
    context: ToolContext,
    airtable_base_id: Annotated[
        str,
        "The unique identifier for the Airtable base from which the view is to be deleted. This is required to locate the specific base within Airtable.",  # noqa: E501
    ],
    view_id_for_deletion: Annotated[
        str,
        "The ID of the view to be deleted from Airtable. Required for specifying which view to remove.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'delete-view'."]:
    """Deletes a specified view in Airtable.

    Use this tool to delete a specific view from an Airtable base. Ideal when views are no longer needed and need to be removed from the database."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/meta/bases/{baseId}/views/{viewId}".format(  # noqa: UP032
            baseId=airtable_base_id, viewId=view_id_for_deletion
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["workspacesAndBases:read"]))
async def get_base_view_info(
    context: ToolContext,
    base_identifier: Annotated[
        str,
        "The unique identifier of the Airtable base. This ID is required to specify which base's view metadata should be retrieved.",  # noqa: E501
    ],
    view_id: Annotated[str, "The unique identifier of the view within a specific Airtable base."],
    fields_to_include: Annotated[
        list[str] | None,
        "Specify an array of field names or properties to include in the metadata response. This allows for filtering the metadata output to only include specified fields.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'get-view-metadata'."]:
    """Retrieve basic information of a base view in Airtable.

    This tool is used to obtain metadata of a specific view within a base on Airtable. It should be called when information about a particular view's configuration or properties is needed."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/meta/bases/{baseId}/views/{viewId}".format(  # noqa: UP032
            baseId=base_identifier, viewId=view_id
        ),
        method="GET",
        params=remove_none_values({"include": fields_to_include}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["enterprise.account:read"]))
async def get_enterprise_info(
    context: ToolContext,
    enterprise_account_id: Annotated[
        str, "The unique identifier for the enterprise account to retrieve information for."
    ],
    fields_to_include: Annotated[
        list[str] | None,
        "Specify which fields to include in the enterprise account information. Provide a list of field names as strings.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'get-enterprise'."]:
    """Retrieve basic enterprise account information from Airtable."""
    response = await make_request(
        url="https://api.airtable.com/v0/meta/enterpriseAccounts/{enterpriseAccountId}".format(  # noqa: UP032
            enterpriseAccountId=enterprise_account_id
        ),
        method="GET",
        params=remove_none_values({"include": fields_to_include}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["enterprise.auditLogs:read"]))
async def retrieve_audit_log_events(
    context: ToolContext,
    enterprise_account_id: Annotated[
        str,
        "The unique ID of the enterprise account for which audit log events are being retrieved. This should be a string.",  # noqa: E501
    ],
    start_time: Annotated[
        str | None,
        "Specify the start time for retrieving audit log events. Use ISO 8601 format (e.g., '2023-01-01T00:00:00Z').",  # noqa: E501
    ] = None,
    end_time: Annotated[
        str | None,
        "The ISO 8601 formatted date and time to end retrieving audit log events. Leave empty to continue into the future.",  # noqa: E501
    ] = None,
    originating_user_id: Annotated[
        str | None,
        "The ID of the user who initiated the event. Used to filter events by their originating user.",  # noqa: E501
    ] = None,
    event_type: Annotated[
        str | None, "Specify the type of event to filter audit logs (e.g., 'login', 'data_change')."
    ] = None,
    model_id: Annotated[
        str | None,
        "The ID of the model to filter audit log events. Use this to specify a particular model if needed.",  # noqa: E501
    ] = None,
    page_size: Annotated[float | None, "Number of audit log events to retrieve per page."] = None,
    sort_order: Annotated[
        str | None, "Specify the order of the audit log results: 'ascending' or 'descending'."
    ] = None,
    previous_page_cursor: Annotated[
        str | None, "A cursor string to navigate to the previous page of results in paginated data."
    ] = None,
    next_page_token: Annotated[
        str | None,
        "A token to retrieve the next page of results in pagination. Use the token from the previous response if available.",  # noqa: E501
    ] = None,
    event_category: Annotated[
        str | None,
        "Specifies the category of events to filter the audit log. Use to narrow down results to specific types of audit events.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'audit-log-events'."]:
    """Retrieve audit log events for an enterprise.

    Use this tool to access audit log events for a specific enterprise. It retrieves all current stored data and continues to update with future events."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/meta/enterpriseAccounts/{enterpriseAccountId}/auditLogEvents".format(  # noqa: UP032
            enterpriseAccountId=enterprise_account_id
        ),
        method="GET",
        params=remove_none_values({
            "startTime": start_time,
            "endTime": end_time,
            "originatingUserId": originating_user_id,
            "eventType": event_type,
            "modelId": model_id,
            "pageSize": page_size,
            "sortOrder": sort_order,
            "previous": previous_page_cursor,
            "next": next_page_token,
            "category": event_category,
        }),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["enterprise.auditLogs:read"]))
async def get_audit_log_requests(
    context: ToolContext,
    enterprise_account_id: Annotated[
        str,
        "The unique ID of the enterprise account for which audit log requests need to be retrieved.",  # noqa: E501
    ],
    page_size: Annotated[
        float | None,
        "Specify the number of audit log requests to return in one call. It helps in paginating large data sets. Typically a number.",  # noqa: E501
    ] = None,
    pagination_offset: Annotated[
        float | None,
        "The starting point for retrieving the audit log requests, used for pagination.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'list-audit-log-requests'."]:
    """Retrieve all audit log requests for an enterprise account.

    This tool retrieves all audit log requests for a specified enterprise account. It should be used to access historical logs for auditing purposes."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/meta/enterpriseAccounts/{enterpriseAccountId}/auditLogs".format(  # noqa: UP032
            enterpriseAccountId=enterprise_account_id
        ),
        method="GET",
        params=remove_none_values({"pageSize": page_size, "offset": pagination_offset}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["enterprise.auditLogs:read"]))
async def retrieve_audit_log_request(
    context: ToolContext,
    enterprise_account_id: Annotated[
        str,
        "The unique identifier for the enterprise account in Airtable. Used to specify which account's audit log is being retrieved.",  # noqa: E501
    ],
    enterprise_audit_log_task_id: Annotated[
        str, "The ID of the specific audit log task to retrieve from Airtable."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'get-audit-log-request'."]:
    """Retrieve a specific audit log request by task ID.

    Use this tool to get details about a specific audit log request from Airtable using the provided enterprise account ID and audit log task ID."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/meta/enterpriseAccounts/{enterpriseAccountId}/auditLogs/{enterpriseAuditLogTaskId}".format(  # noqa: UP032
            enterpriseAccountId=enterprise_account_id,
            enterpriseAuditLogTaskId=enterprise_audit_log_task_id,
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["enterprise.changeEvents:read"]))
async def retrieve_airtable_change_events(
    context: ToolContext,
    enterprise_account_id: Annotated[
        str, "Specify the ID of the enterprise account for which to retrieve change events."
    ],
    start_time: Annotated[
        str | None, "The beginning ISO 8601 timestamp for retrieving change events."
    ] = None,
    end_time: Annotated[
        str | None,
        "The end timestamp to filter change events, formatted as ISO 8601 date-time string.",
    ] = None,
    page_size: Annotated[
        float | None,
        "Specifies the number of change events to return per page. This controls pagination and helps in managing the amount of data received in a single request.",  # noqa: E501
    ] = None,
    pagination_offset: Annotated[
        str | None,
        "Specifies the starting point for retrieving change events, used for pagination.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'change-events'."]:
    """Fetch Airtable change events for enterprise bases.

    Retrieve change events for enterprise bases from Airtable. This tool should be called when you need to access change events within a 14-day window. Ensure change events are enabled in your admin panel before using."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/meta/enterpriseAccounts/{enterpriseAccountId}/changeEvents".format(  # noqa: UP032
            enterpriseAccountId=enterprise_account_id
        ),
        method="GET",
        params=remove_none_values({
            "startTime": start_time,
            "endTime": end_time,
            "pageSize": page_size,
            "offset": pagination_offset,
        }),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["enterprise.exports:manage"]))
async def get_ediscovery_export_status(
    context: ToolContext,
    enterprise_account_id: Annotated[
        str, "The unique identifier for the enterprise account to retrieve eDiscovery exports for."
    ],
    ediscovery_export_state: Annotated[
        str | None,
        "The state of the eDiscovery export. Possible values are 'pending', 'processing', 'error', and 'done'.",  # noqa: E501
    ] = None,
    page_size: Annotated[
        float | None,
        "Specifies the number of export results to display per page. Useful for pagination.",
    ] = None,
    result_offset: Annotated[
        float | None,
        "Specifies the starting point within the list of eDiscovery exports for retrieval.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'list-ediscovery-export'."]:
    """Retrieve status and results of all eDiscovery exports.

    Use this tool to get the current status and results of eDiscovery exports for a specific enterprise account."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/meta/enterpriseAccounts/{enterpriseAccountId}/exports".format(  # noqa: UP032
            enterpriseAccountId=enterprise_account_id
        ),
        method="GET",
        params=remove_none_values({
            "state": ediscovery_export_state,
            "pageSize": page_size,
            "offset": result_offset,
        }),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["enterprise.exports:manage"]))
async def fetch_ediscovery_export(
    context: ToolContext,
    enterprise_account_id: Annotated[
        str,
        "The ID of the enterprise account for the eDiscovery export. Must be a valid string identifier.",  # noqa: E501
    ],
    enterprise_task_id: Annotated[
        str,
        "The unique identifier for the specific eDiscovery export task. Use this to specify which task's status and result you want to retrieve.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'get-ediscovery-export'."]:
    """Retrieve the status and result of an eDiscovery export from Airtable.

    Call this tool to obtain the current status and outcome of a specific eDiscovery export identified by enterpriseAccountId and enterpriseTaskId."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/meta/enterpriseAccounts/{enterpriseAccountId}/exports/{enterpriseTaskId}".format(  # noqa: UP032
            enterpriseAccountId=enterprise_account_id, enterpriseTaskId=enterprise_task_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["enterprise.user:write"]))
async def delete_users_by_email(
    context: ToolContext,
    enterprise_account_id: Annotated[
        str,
        "The unique identifier for the Airtable enterprise account from which users will be deleted.",  # noqa: E501
    ],
    user_emails: Annotated[
        list[str] | None,
        "An array of user email addresses to delete from the Airtable enterprise account.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'delete-users-by-email'."]:
    """Delete multiple users from an Airtable enterprise account by email.

    Use this tool to remove multiple users from a specified Airtable enterprise account by their email addresses. This action is useful for managing user access efficiently."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/meta/enterpriseAccounts/{enterpriseAccountId}/users".format(  # noqa: UP032
            enterpriseAccountId=enterprise_account_id
        ),
        method="DELETE",
        params=remove_none_values({"email": user_emails}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["enterprise.user:read"]))
async def get_user_info_by_id_or_email(
    context: ToolContext,
    enterprise_account_id: Annotated[
        str,
        "Specifies the enterprise account ID associated with the user. Use to filter users within a specific enterprise account.",  # noqa: E501
    ],
    user_email_addresses: Annotated[
        list[str] | None,
        "An array of user email addresses to retrieve information for. Each email should be a string.",  # noqa: E501
    ] = None,
    user_ids: Annotated[
        list[str] | None,
        "A list of user IDs for which to retrieve information. Include each ID as a string.",
    ] = None,
    include_additional_fields: Annotated[
        list[str] | None,
        "List of extra user attributes to include in the response. Provide attribute names as strings within an array.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'get-users-by-id-or-email'."]:
    """Retrieve user details by ID or email.

    Use this tool to obtain basic information about both internal and external users by providing their ID or email."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/meta/enterpriseAccounts/{enterpriseAccountId}/users".format(  # noqa: UP032
            enterpriseAccountId=enterprise_account_id
        ),
        method="GET",
        params=remove_none_values({
            "email": user_email_addresses,
            "id": user_ids,
            "include": include_additional_fields,
        }),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["enterprise.user:write"]))
async def delete_enterprise_user(
    context: ToolContext,
    enterprise_account_id: Annotated[
        str,
        "The ID of the enterprise account from which the user will be deleted. This is required to identify the specific account.",  # noqa: E501
    ],
    user_id: Annotated[
        str,
        "The unique identifier for the user to be deleted from the enterprise account. This should be a string value that corresponds to the user's ID in Airtable.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'delete-user-by-id'."]:
    """Deletes an enterprise account user by ID.

    Use this tool to delete ELA enterprise account users or managed users by specifying their enterprise account ID and user ID. It should be called when you need to remove a user from an enterprise account in Airtable."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/meta/enterpriseAccounts/{enterpriseAccountId}/users/{userId}".format(  # noqa: UP032
            enterpriseAccountId=enterprise_account_id, userId=user_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["enterprise.user:read"]))
async def fetch_user_info(
    context: ToolContext,
    enterprise_account_id: Annotated[
        str, "The ID of the enterprise account associated with the user to retrieve."
    ],
    user_id: Annotated[
        str,
        "The unique identifier for the user whose information is to be fetched. This ID corresponds to an internal or external user within an enterprise account on Airtable.",  # noqa: E501
    ],
    include_fields: Annotated[
        list[str] | None,
        "Specify additional fields to include in the response. Provide an array of field names as strings.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'get-user-by-id'."]:
    """Fetch user information by ID.

    Use this tool to retrieve basic information about a user, identified by their user ID, within an enterprise account on Airtable. It is suitable for accessing both internal and external user data."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/meta/enterpriseAccounts/{enterpriseAccountId}/users/{userId}".format(  # noqa: UP032
            enterpriseAccountId=enterprise_account_id, userId=user_id
        ),
        method="GET",
        params=remove_none_values({"include": include_fields}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["enterprise.user:write"]))
async def logout_enterprise_user(
    context: ToolContext,
    enterprise_account_id: Annotated[
        str, "The unique identifier for the enterprise account. Required for logging out the user."
    ],
    user_id: Annotated[
        str,
        "The unique identifier for the user to be logged out. This value is required to terminate their session.",  # noqa: E501
    ],
    logout_request_body: Annotated[
        dict[str, str] | None, "JSON object containing the logout details for the user session."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'logout-user'."]:
    """Log out an enterprise account user.

    This tool logs out a user from an enterprise account, specifically for ELA and FLA enterprise accounts or managed claiming users. It should be used when there's a need to terminate an active session for such users."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/meta/enterpriseAccounts/{enterpriseAccountId}/users/{userId}/logout".format(  # noqa: UP032
            enterpriseAccountId=enterprise_account_id, userId=user_id
        ),
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({"requestBody": logout_request_body}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["enterprise.groups:read"]))
async def get_user_group_info(
    context: ToolContext,
    group_id: Annotated[
        str,
        "The unique identifier for the user group you want to retrieve information about. This should be provided as a string.",  # noqa: E501
    ],
    include_additional_fields: Annotated[
        list[str] | None,
        "An array specifying which additional fields to include in the response. Each entry should be a string representing a field name.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'get-user-group'."]:
    """Retrieve basic information about a specific user group.

    This tool is used to obtain fundamental details regarding a specific user group by providing the group ID. It is useful when you need to access metadata related to user groups in Airtable."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/meta/groups/{groupId}".format(groupId=group_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({"include": include_additional_fields}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable"))
async def retrieve_user_details(
    context: ToolContext,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'get-user-id-scopes'."]:
    """Retrieve user's ID, scopes, and optionally email details.

    Use this tool to get the user's ID and the scopes associated with their OAuth tokens. If the token has the `user.email:read` scope, the user's email will also be provided."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/meta/whoami",
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["workspacesAndBases:manage"]))
async def delete_airtable_workspace(
    context: ToolContext,
    workspace_id: Annotated[
        str,
        "The unique identifier for the Airtable workspace you wish to delete. Ensure this ID is correct to avoid unintended deletions.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'delete-workspace'."]:
    """Deletes a specified workspace in Airtable.

    Use this tool to delete a workspace in Airtable. Ensure you have checked for any actively used bases before deleting, as access will be lost unless transferred. Deleted workspaces can be restored within the billing plan retention period."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/meta/workspaces/{workspaceId}".format(  # noqa: UP032
            workspaceId=workspace_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["workspacesAndBases:read"]))
async def get_workspace_collaborators(
    context: ToolContext,
    workspace_id: Annotated[
        str, "Unique identifier for the Airtable workspace to fetch collaborators from."
    ],
    fields_to_include: Annotated[
        list[str] | None,
        "List of specific fields to include in the response, such as 'email' or 'role'.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'get-workspace-collaborators'."]:
    """Fetches basic information on workspace collaborators and invites.

    This tool retrieves basic information about collaborators in an Airtable workspace, excluding deleted ones and including only outstanding invites."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/meta/workspaces/{workspaceId}".format(  # noqa: UP032
            workspaceId=workspace_id
        ),
        method="GET",
        params=remove_none_values({"include": fields_to_include}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["workspacesAndBases:write"]))
async def remove_workspace_collaborator(
    context: ToolContext,
    workspace_id: Annotated[
        str, "The unique identifier of the workspace from which the collaborator will be removed."
    ],
    user_or_group_id: Annotated[
        str,
        "The ID of the user or group to remove from the workspace. It must be a valid string identifier.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'delete-workspace-collaborator'."]:
    """Remove a collaborator from a workspace.

    Call this tool to delete a collaborator from an Airtable workspace, identified by workspace and user or group IDs."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/meta/workspaces/{workspaceId}/collaborators/{userOrGroupId}".format(  # noqa: UP032
            workspaceId=workspace_id, userOrGroupId=user_or_group_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["workspacesAndBases:write"]))
async def delete_workspace_invite(
    context: ToolContext,
    workspace_id: Annotated[
        str,
        "The ID of the workspace from which the invite will be deleted. It must be a valid string.",
    ],
    invite_id: Annotated[str, "The ID of the invite to be deleted from the workspace."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'delete-workspace-invite'."]:
    """Deletes a specified workspace invite in Airtable.

    Use this tool to delete an existing workspace invite in Airtable when you have the workspace and invite IDs."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/meta/workspaces/{workspaceId}/invites/{inviteId}".format(  # noqa: UP032
            workspaceId=workspace_id, inviteId=invite_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["data.records:write"]))
async def delete_multiple_records_airtable(
    context: ToolContext,
    base_identifier: Annotated[
        str,
        "The unique identifier of the Airtable base where records will be deleted. This must be provided to specify the target database.",  # noqa: E501
    ],
    table_id_or_name: Annotated[
        str, "The unique ID or name of the Airtable table from which records should be deleted."
    ],
    record_ids_to_delete: Annotated[
        list[str] | None, "An array of record IDs to be deleted from the specified Airtable table."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'delete-multiple-records'."]:
    """Deletes multiple records from an Airtable table.

    Use this tool to delete multiple records from an Airtable table by providing an array of record IDs. Useful for batch deletion of data entries in specified Airtable bases and tables."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/{baseId}/{tableIdOrName}".format(  # noqa: UP032
            baseId=base_identifier, tableIdOrName=table_id_or_name
        ),
        method="DELETE",
        params=remove_none_values({"records": record_ids_to_delete}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["data.records:write"]))
async def delete_airtable_record(
    context: ToolContext,
    airtable_base_id: Annotated[
        str, "The unique identifier for the Airtable base from which the record will be deleted."
    ],
    table_id_or_name: Annotated[
        str, "The ID or name of the table from which to delete the record."
    ],
    record_id_to_delete: Annotated[
        str, "The ID of the record to be deleted from the specified table in Airtable."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'delete-record'."]:
    """Delete a specific record from an Airtable base and table.

    This tool deletes a single record from a specified Airtable base and table. Use it when you need to remove entry data permanently."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/{baseId}/{tableIdOrName}/{recordId}".format(  # noqa: UP032
            baseId=airtable_base_id, tableIdOrName=table_id_or_name, recordId=record_id_to_delete
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["data.records:read"]))
async def retrieve_airtable_record(
    context: ToolContext,
    airtable_base_id: Annotated[
        str, "The unique identifier of the Airtable base from which to retrieve the record."
    ],
    table_identifier_or_name: Annotated[
        str,
        "The ID or name of the table from which to retrieve the record. This identifies the specific table within the base.",  # noqa: E501
    ],
    record_id: Annotated[
        str,
        "The unique identifier for the record to be retrieved from Airtable. This should be the record ID within the specified base and table.",  # noqa: E501
    ],
    cell_format: Annotated[
        str | None,
        "Specify the cell format for the returned data. Options include 'json' or 'string'.",
    ] = None,
    return_fields_by_field_id: Annotated[
        bool | None, "Set to true to return fields using field IDs instead of names."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'get-record'."]:
    """Retrieve a single record from Airtable by record ID.

    This tool retrieves a single record from a specified Airtable base and table using the record ID. Empty fields in the record are not returned. If the record isn't found in the specified table, a base-wide search is conducted."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/{baseId}/{tableIdOrName}/{recordId}".format(  # noqa: UP032
            baseId=airtable_base_id, tableIdOrName=table_identifier_or_name, recordId=record_id
        ),
        method="GET",
        params=remove_none_values({
            "cellFormat": cell_format,
            "returnFieldsByFieldId": return_fields_by_field_id,
        }),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["data.recordComments:read"]))
async def list_record_comments(
    context: ToolContext,
    base_id: Annotated[
        str,
        "The unique identifier for the Airtable base containing the table and record of interest.",
    ],
    table_id_or_name: Annotated[
        str, "The ID or name of the table containing the record whose comments you want to list."
    ],
    record_id: Annotated[
        str, "The unique identifier of the record for which comments need to be fetched."
    ],
    comments_per_page: Annotated[
        float | None,
        "The maximum number of comments to retrieve per page. Determines page size for pagination.",
    ] = None,
    comments_page_offset: Annotated[
        str | None,
        "Used to specify the starting point in a list of comments for pagination purposes.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'list-comments'."]:
    """Retrieve comments for a specific record in a table.

    Use this tool to obtain a list of comments related to a specific record, sorted from newest to oldest. Note that comments replying to another comment may not have the parent comment in the same set of results."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/{baseId}/{tableIdOrName}/{recordId}/comments".format(  # noqa: UP032
            baseId=base_id, tableIdOrName=table_id_or_name, recordId=record_id
        ),
        method="GET",
        params=remove_none_values({"pageSize": comments_per_page, "offset": comments_page_offset}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-airtable", scopes=["data.recordComments:write"]))
async def delete_comment_from_record(
    context: ToolContext,
    base_identifier: Annotated[
        str, "The unique identifier for the Airtable base from which the comment will be deleted."
    ],
    table_id_or_name: Annotated[
        str,
        "The unique ID or name of the table where the record containing the comment exists. Ensure it matches the table's exact name or ID in Airtable.",  # noqa: E501
    ],
    record_id: Annotated[
        str, "The unique identifier for the record from which the comment will be deleted."
    ],
    comment_id_to_delete: Annotated[
        str, "The unique identifier of the comment to be deleted from the record in Airtable."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'delete-comment'."]:
    """Delete a comment from a record in Airtable.

    Use this tool to delete a specific comment from a record in Airtable. Non-admin users can only delete comments they have created, while Enterprise Admins can delete any comment."""  # noqa: E501
    response = await make_request(
        url="https://api.airtable.com/v0/{baseId}/{tableIdOrName}/{recordId}/comments/{rowCommentId}".format(  # noqa: UP032
            baseId=base_identifier,
            tableIdOrName=table_id_or_name,
            recordId=record_id,
            rowCommentId=comment_id_to_delete,
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        data=remove_none_values({}),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}
