"""Arcade Starter Tools for Pagerduty

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

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

from .request_body_schemas import REQUEST_BODY_SCHEMAS

# 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:
            # 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: {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-pagerduty"))
async def assign_tags_to_pagerduty_entity(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    entity_type: Annotated[
        str | None,
        "Specify the entity type to tag. Options: 'users', 'teams', 'escalation_policies'.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    resource_id: Annotated[
        str | None,
        "The unique identifier of the PagerDuty entity to assign tags to.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'createEntityTypeByIdChangeTags'."]:
    """Assign tags to PagerDuty entities like policies, teams, or users.

    Assign or update tags for Escalation Policies, Teams, or Users in PagerDuty to facilitate filtering and organization. Use this tool to manage tags efficiently.

    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["ASSIGNTAGSTOPAGERDUTYENTITY"],
            "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 entity_type:
        missing_params.append(("entity_type", "path"))
    if not resource_id:
        missing_params.append(("resource_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["ASSIGNTAGSTOPAGERDUTYENTITY"]
                + "\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["ASSIGNTAGSTOPAGERDUTYENTITY"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/{entity_type}/{id}/change_tags".format(  # noqa: UP032
            entity_type=entity_type, id=resource_id
        ),
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["ASSIGNTAGSTOPAGERDUTYENTITY"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_tags_by_entity_id(
    context: ToolContext,
    entity_id: Annotated[
        str,
        "The unique identifier of the resource for which to retrieve tags. This ID corresponds to a specific User, Team, or Escalation Policy.",  # noqa: E501
    ],
    entity_type: Annotated[
        str,
        "Specifies the type of entity (users, teams, escalation_policies) to retrieve related tags for.",  # noqa: E501
    ],
    include_total_in_response: Annotated[
        bool | None,
        "Set to true to include the total number of results in the pagination response.",
    ] = False,
    pagination_offset: Annotated[
        int | None,
        "The offset position to start paginating search results. Useful for browsing through large sets of data.",  # noqa: E501
    ] = None,
    results_per_page: Annotated[
        int | None, "The number of results to return per page when retrieving tags."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getEntityTypeByIdTags'."]:
    """Retrieve tags for Users, Teams, or Escalation Policies.

    Use this tool to get tags related to a specific User, Team, or Escalation Policy by their ID. Useful for filtering and organizing entities based on applied tags."""  # 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="https://api.pagerduty.com/{entity_type}/{id}/tags".format(  # noqa: UP032
            entity_type=entity_type, id=entity_id
        ),
        method="GET",
        params=remove_none_values({
            "limit": results_per_page,
            "offset": pagination_offset,
            "total": include_total_in_response,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_account_abilities(
    context: ToolContext,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listAbilities'."]:
    """Retrieve your account's available abilities by feature name.

    Use this tool to get a list of the features or capabilities available on your account, such as 'teams'. The availability of these abilities may depend on factors like your pricing plan or account 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="https://api.pagerduty.com/abilities",
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def check_ability_status(
    context: ToolContext,
    resource_id: Annotated[
        str, "The unique ID of the resource or ability to check on your account."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getAbility'."]:
    """Check if your account has a specific ability.

    Use this tool to test whether your PagerDuty account has a specific ability or feature available. An ability can depend on factors like your pricing plan or account state, and this tool helps determine availability."""  # 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="https://api.pagerduty.com/abilities/{id}".format(id=resource_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_addons(
    context: ToolContext,
    addon_type_filter: Annotated[
        str | None,
        "Filters the results, showing only Add-ons of the specified type, such as 'full_page_addon' or 'incident_show_addon'.",  # noqa: E501
    ] = None,
    filter_by_service_ids: Annotated[
        list[str] | None,
        "An array of service IDs to filter results, showing only Add-ons for these services.",
    ] = None,
    include_additional_models: Annotated[
        str | None, "Specify additional models to include in the response, such as 'services'."
    ] = None,
    include_total_field: Annotated[
        bool | None,
        "Set to true to include the total count of results in the response, which can affect response times.",  # noqa: E501
    ] = False,
    pagination_start_offset: Annotated[
        int | None,
        "Offset to start pagination of search results. This determines where to begin the list of add-ons.",  # noqa: E501
    ] = None,
    results_per_page: Annotated[
        int | None, "Specify the number of results to return per page."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listAddon'."]:
    """Retrieve all installed add-ons on your PagerDuty account.

    Use this tool to list all the add-ons currently installed on your PagerDuty account. Add-ons provide additional functionality by integrating into PagerDuty's UI. This tool is useful for understanding what add-ons are available and active on your account. Requires `addons.read` OAuth scope."""  # 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="https://api.pagerduty.com/addons",
        method="GET",
        params=remove_none_values({
            "limit": results_per_page,
            "offset": pagination_start_offset,
            "total": include_total_field,
            "include[]": include_additional_models,
            "service_ids[]": filter_by_service_ids,
            "filter": addon_type_filter,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def install_pagerduty_addon(
    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 'createAddon'."]:
    """Install an add-on for your PagerDuty account.

    Use this tool to install a new add-on in your PagerDuty account. The add-on is a functional component embedded via an iframe URL provided in the configuration. This allows users to access it from a drop-down menu in PagerDuty's UI. Requires 'addons.write' OAuth scope.

    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["INSTALLPAGERDUTYADDON"],
            "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["INSTALLPAGERDUTYADDON"] + "\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["INSTALLPAGERDUTYADDON"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/addons",
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["INSTALLPAGERDUTYADDON"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_addon_details(
    context: ToolContext,
    addon_id: Annotated[str, "The unique ID of the PagerDuty add-on to retrieve details for."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getAddon'."]:
    """Retrieve detailed information about a PagerDuty add-on.

    This tool retrieves details about a specific add-on within PagerDuty. Add-ons are extensions that add new functionality to PagerDuty's UI. Use this tool when you need information about a particular add-on. Requires `addons.read` OAuth scope."""  # 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="https://api.pagerduty.com/addons/{id}".format(id=addon_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def remove_addon(
    context: ToolContext,
    resource_id: Annotated[str, "The unique identifier for the add-on to be removed."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteAddon'."]:
    """Remove an existing add-on from PagerDuty.

    Use this tool to delete an existing add-on in PagerDuty, which allows developers to integrate new functionality into the UI. This operation requires 'addons.write' OAuth scope."""  # 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="https://api.pagerduty.com/addons/{id}".format(id=resource_id),  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_pagerduty_addon(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The unique identifier for the add-on resource to be updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateAddon'."]:
    """Update an existing add-on in PagerDuty.

    This tool updates a specific add-on in PagerDuty by embedding a given URL in an iframe accessible through the UI. It requires the 'addons.write' OAuth scope.

    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["UPDATEPAGERDUTYADDON"],
            "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 resource_id:
        missing_params.append(("resource_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["UPDATEPAGERDUTYADDON"] + "\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["UPDATEPAGERDUTYADDON"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/addons/{id}".format(id=resource_id),  # noqa: UP032
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEPAGERDUTYADDON"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_alert_grouping_settings(
    context: ToolContext,
    include_total_in_response: Annotated[
        bool | None,
        "Set to true to include the total number of records in the response; default is null for faster responses.",  # noqa: E501
    ] = False,
    pagination_cursor_after: Annotated[
        str | None,
        "Cursor to retrieve the next page of results; used if additional data pages exist.",
    ] = None,
    previous_page_cursor: Annotated[
        str | None, "Cursor to retrieve the previous page; use only if not on the first page."
    ] = None,
    results_per_page: Annotated[
        int | None, "Specify the number of alert grouping settings to display per page."
    ] = None,
    service_id_list: Annotated[
        list[str] | None,
        "An array of service IDs to filter results. Only results for these IDs will be returned.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listAlertGroupingSettings'."]:
    """Retrieve all alert grouping settings.

    This tool retrieves all alert grouping settings, including single service and global content-based configurations. It is useful for managing and reviewing alert grouping configurations in PagerDuty."""  # 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="https://api.pagerduty.com/alert_grouping_settings",
        method="GET",
        params=remove_none_values({
            "after": pagination_cursor_after,
            "before": previous_page_cursor,
            "total": include_total_in_response,
            "limit": results_per_page,
            "service_ids[]": service_id_list,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_alert_grouping_setting(
    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 'postAlertGroupingSettings'."]:
    """Create a new Alert Grouping Setting in PagerDuty.

    This tool allows the creation of new Alert Grouping Settings for one or multiple services within the PagerDuty platform. It is used to define configurations in the Alert Grouper service. Requires 'services.write' OAuth scope.

    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["CREATEALERTGROUPINGSETTING"],
            "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["CREATEALERTGROUPINGSETTING"]
                + "\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["CREATEALERTGROUPINGSETTING"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/alert_grouping_settings",
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATEALERTGROUPINGSETTING"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_alert_grouping_setting(
    context: ToolContext,
    resource_id: Annotated[
        str, "The unique identifier for the alert grouping setting you want to retrieve."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getAlertGroupingSetting'."]:
    """Retrieve an existing alert grouping setting.

    Use this tool to get details of a specific alert grouping setting. It is useful when you need to understand or verify the configuration of alert grouping within the PagerDuty 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="https://api.pagerduty.com/alert_grouping_settings/{id}".format(id=resource_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def delete_alert_grouping_setting(
    context: ToolContext,
    alert_grouping_setting_id: Annotated[
        str,
        "The ID of the alert grouping setting to be deleted. This identifies the specific resource in PagerDuty.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteAlertGroupingSetting'."]:
    """Delete an existing alert grouping setting.

    Use this tool to delete a specific alert grouping setting in the PagerDuty service. This action is utilized when you need to remove configurations used during the grouping of alerts. Requires appropriate OAuth scope."""  # 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="https://api.pagerduty.com/alert_grouping_settings/{id}".format(  # noqa: UP032
            id=alert_grouping_setting_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_alert_grouping_setting(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The ID of the alert grouping setting to update.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'putAlertGroupingSetting'."]:
    """Update an existing alert grouping setting in PagerDuty.

    Use this tool to update an alert grouping setting in PagerDuty. This is particularly useful for managing how alerts are grouped and ensuring the correct configurations are in place. Note that if 'services' are not provided, existing services will remain unchanged. Requires scoped OAuth with `services.write`.

    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["UPDATEALERTGROUPINGSETTING"],
            "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 resource_id:
        missing_params.append(("resource_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["UPDATEALERTGROUPINGSETTING"]
                + "\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["UPDATEALERTGROUPINGSETTING"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/alert_grouping_settings/{id}".format(id=resource_id),  # noqa: UP032
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEALERTGROUPINGSETTING"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_incident_metrics(
    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 'getAnalyticsMetricsIncidentsAll'."]:
    """Retrieve aggregated metrics for PagerDuty incidents.

    This tool provides aggregated enriched metrics for incidents in PagerDuty. It allows aggregation by day, week, or month, or for the entire specified period. A filter with `team_ids` or `service_ids` is required for user-level API keys. Use this tool to analyze incident trends and performance over time.

    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["GETINCIDENTMETRICS"],
            "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["GETINCIDENTMETRICS"] + "\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["GETINCIDENTMETRICS"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/analytics/metrics/incidents/all",
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["GETINCIDENTMETRICS"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_escalation_policy_metrics(
    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 'getAnalyticsMetricsIncidentsEscalationPolicy'."
]:
    """Get aggregated incident metrics by escalation policy.

    This tool provides aggregated metrics for incidents categorized by escalation policy. Example metrics include Seconds to Resolve, Seconds to Engage, Snoozed Seconds, and Sleep Hour Interruptions. It's useful for analyzing response times and interruptions based on policy. Note that data updates can take up to 24 hours.

    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["GETESCALATIONPOLICYMETRICS"],
            "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["GETESCALATIONPOLICYMETRICS"]
                + "\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["GETESCALATIONPOLICYMETRICS"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/analytics/metrics/incidents/escalation_policies",
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["GETESCALATIONPOLICYMETRICS"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def fetch_incident_metrics(
    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 'getAnalyticsMetricsIncidentsEscalationPolicyAll'.",
]:
    """Get aggregated metrics across all escalation policies.

    This tool retrieves aggregated metrics related to escalation policies, including Seconds to Resolve, Seconds to Engage, Snoozed Seconds, and Sleep Hour Interruptions. Metrics are updated periodically and may take up to 24 hours to reflect new incidents.

    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["FETCHINCIDENTMETRICS"],
            "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["FETCHINCIDENTMETRICS"] + "\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["FETCHINCIDENTMETRICS"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/analytics/metrics/incidents/escalation_policies/all",
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["FETCHINCIDENTMETRICS"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_incident_analytics_metrics(
    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 'getAnalyticsMetricsIncidentsService'."
]:
    """Retrieve aggregated incident metrics by service over time.

    This tool provides aggregated metrics for PagerDuty incidents, such as Seconds to Resolve and Sleep Hour Interruptions, aggregated by service and time units like day, week, or month. It helps users analyze incident management performance over specified periods.

    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["GETINCIDENTANALYTICSMETRICS"],
            "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["GETINCIDENTANALYTICSMETRICS"]
                + "\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["GETINCIDENTANALYTICSMETRICS"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/analytics/metrics/incidents/services",
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["GETINCIDENTANALYTICSMETRICS"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_aggregated_incident_metrics(
    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 'getAnalyticsMetricsIncidentsServiceAll'."
]:
    """Retrieve aggregated incident metrics across all services.

    This tool provides aggregated metrics for incidents such as resolution time, engagement time, and more, across all services in PagerDuty. Requires `team_ids` or `service_ids` filter for certain API keys.

    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["GETAGGREGATEDINCIDENTMETRICS"],
            "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["GETAGGREGATEDINCIDENTMETRICS"]
                + "\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["GETAGGREGATEDINCIDENTMETRICS"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/analytics/metrics/incidents/services/all",
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["GETAGGREGATEDINCIDENTMETRICS"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_team_incident_metrics(
    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 'getAnalyticsMetricsIncidentsTeam'."
]:
    """Fetch aggregated incident metrics by team and time unit.

    Use this tool to obtain metrics such as Seconds to Resolve and Sleep Hour Interruptions for incidents, aggregated by team. Data can be grouped by day, week, or month, or summarized for a specific period for each team. A team or service ID filter is required for user-level API keys.

    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["GETTEAMINCIDENTMETRICS"],
            "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["GETTEAMINCIDENTMETRICS"] + "\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["GETTEAMINCIDENTMETRICS"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/analytics/metrics/incidents/teams",
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["GETTEAMINCIDENTMETRICS"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_analytics_metrics_for_all_teams(
    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 'getAnalyticsMetricsIncidentsTeamAll'."
]:
    """Fetches aggregated incident metrics across all teams.

    This tool provides aggregated metrics for incidents across all teams, including metrics like Seconds to Resolve and Sleep Hour Interruptions. Ideal for understanding team performance and incident impacts. Ensure to use team_ids or service_ids filters with user-level API keys unless using account-level keys.

    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["GETANALYTICSMETRICSFORALLTEAMS"],
            "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["GETANALYTICSMETRICSFORALLTEAMS"]
                + "\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["GETANALYTICSMETRICSFORALLTEAMS"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/analytics/metrics/incidents/teams/all",
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["GETANALYTICSMETRICSFORALLTEAMS"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_analytics_metrics_pd_advance_usage(
    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 'getAnalyticsMetricsPdAdvanceUsageFeatures'."
]:
    """Retrieve aggregated metrics for PD Advance usage.

    This tool provides aggregated metrics for the usage of PD Advance. It should be called when you need insights or reports about PD Advance features usage. Note that analytics data is updated periodically and may take up to 24 hours to reflect new incidents.

    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["GETANALYTICSMETRICSPDADVANCEUSAGE"],
            "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["GETANALYTICSMETRICSPDADVANCEUSAGE"]
                + "\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["GETANALYTICSMETRICSPDADVANCEUSAGE"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/analytics/metrics/pd_advance_usage/features",
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["GETANALYTICSMETRICSPDADVANCEUSAGE"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def retrieve_analytics_data(
    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 'getAnalyticsMetricsRespondersAll'."
]:
    """Provides aggregated incident metrics for selected responders.

    This tool retrieves aggregated metrics such as Seconds to Resolve, Seconds to Engage, and Sleep Hour Interruptions for all selected responders. It is called to analyze responder performance and incident handling efficiency. Note that the analytics data may take up to 24 hours to update.

    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["RETRIEVEANALYTICSDATA"],
            "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["RETRIEVEANALYTICSDATA"] + "\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["RETRIEVEANALYTICSDATA"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/analytics/metrics/responders/all",
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["RETRIEVEANALYTICSDATA"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def fetch_responder_team_metrics(
    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 'getAnalyticsMetricsRespondersTeam'."
]:
    """Fetch incident metrics for team responders.

    This tool provides aggregated incident metrics for responders on a team, such as Seconds to Resolve and Sleep Hour Interruptions. It should be called when detailed performance insights are needed for team members handling incidents. Metrics are updated periodically.

    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["FETCHRESPONDERTEAMMETRICS"],
            "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["FETCHRESPONDERTEAMMETRICS"] + "\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["FETCHRESPONDERTEAMMETRICS"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/analytics/metrics/responders/teams",
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["FETCHRESPONDERTEAMMETRICS"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_incident_analytics(
    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 'getAnalyticsIncidents'."]:
    """Fetch enriched incident metrics and data from PagerDuty Analytics.

    Use this tool to retrieve detailed metrics and data for multiple incidents, such as Seconds to Resolve and Sleep Hour Interruptions. A `team_ids` or `service_ids` filter is needed for certain API keys.

    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["GETINCIDENTANALYTICS"],
            "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["GETINCIDENTANALYTICS"] + "\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["GETINCIDENTANALYTICS"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/analytics/raw/incidents",
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["GETINCIDENTANALYTICS"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_enriched_incident_data(
    context: ToolContext,
    incident_id: Annotated[
        str, "The unique identifier for the incident to retrieve analytics for."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getAnalyticsIncidentsById'."]:
    """Retrieve enriched incident metrics for a specific incident.

    This tool provides enriched incident data including metrics like Seconds to Resolve, Seconds to Engage, and Snoozed Seconds. Suitable for analyzing incident performance and response times. Data is updated periodically and may take up to 24 hours to reflect new incidents."""  # 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="https://api.pagerduty.com/analytics/raw/incidents/{id}".format(id=incident_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_incident_response_analytics(
    context: ToolContext,
    incident_id: Annotated[str, "The ID of the incident to retrieve analytics for."],
    display_order: Annotated[
        str | None,
        "Specifies the order to display results: 'asc' for ascending, 'desc' for descending. Defaults to 'desc'.",  # noqa: E501
    ] = None,
    order_results_by_column: Annotated[
        str | None, "Specify the column to use for ordering the results, such as 'requested_at'."
    ] = None,
    results_limit: Annotated[
        int | None,
        "The number of results to include in each batch. Acceptable values range from 1 to 1000.",
    ] = None,
    time_zone_for_results: Annotated[
        str | None, "The time zone to use for displaying the results."
    ] = None,
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'getAnalyticsIncidentResponsesById'."
]:
    """Provides enriched responder data for a single incident.

    Use this tool to obtain detailed analytics on a specific incident's responder data, such as Time to Respond, Responder Type, and Response Status. Note that analytics data is updated daily and may take up to 24 hours to appear."""  # noqa: E501
    request_data: Any = {
        "limit": results_limit,
        "order": display_order,
        "order_by": order_results_by_column,
        "time_zone": time_zone_for_results,
    }
    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="https://api.pagerduty.com/analytics/raw/incidents/{id}/responses".format(  # noqa: UP032
            id=incident_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_responder_incident_analytics(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    responder_id: Annotated[
        str | None,
        "The unique identifier of the responder whose incident metrics are to be retrieved. It is required to specify which responder's data is needed.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'getAnalyticsResponderIncidents'."]:
    """Retrieve enriched incident metrics for a specific responder.

    Provides detailed incident data and metrics such as Mean Resolve Time, Mean Engage Time, and more for a specified responder. Useful for analyzing responder performance. Note: Data updates every 24 hours.

    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["GETRESPONDERINCIDENTANALYTICS"],
            "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 responder_id:
        missing_params.append(("responder_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["GETRESPONDERINCIDENTANALYTICS"]
                + "\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["GETRESPONDERINCIDENTANALYTICS"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/analytics/raw/responders/{responder_id}/incidents".format(  # noqa: UP032
            responder_id=responder_id
        ),
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["GETRESPONDERINCIDENTANALYTICS"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_audit_records(
    context: ToolContext,
    action_filters: Annotated[
        str | None,
        "Filter the audit records by specific actions such as 'create', 'update', or 'delete'.",
    ] = None,
    actor_type_filter: Annotated[
        str | None,
        "Specifies the type of actor to filter the audit records by. Acceptable values are 'user_reference', 'api_key_reference', or 'app_reference'.",  # noqa: E501
    ] = None,
    end_date_range: Annotated[
        str | None,
        "Specifies the end date for the audit record search. Defaults to now if not specified and cannot exceed 31 days after the start date.",  # noqa: E501
    ] = None,
    filter_by_actor_id: Annotated[
        str | None, "Filter audit records by actor ID. Requires `actor_type` to be specified."
    ] = None,
    method_truncated_token: Annotated[
        str | None,
        "Filter records by method truncated token. Requires 'method_type' parameter for qualification.",  # noqa: E501
    ] = None,
    method_type_filter: Annotated[
        str | None,
        "Specify the method type for filtering audit records. Options include 'browser', 'oauth', 'api_token', 'identity_provider', and 'other'.",  # noqa: E501
    ] = None,
    next_result_cursor: Annotated[
        str | None,
        "Use this to fetch the next set of results. Typically acquired from the `next_cursor` of the prior request. If not provided, it starts from the beginning of the result set.",  # noqa: E501
    ] = None,
    record_limit: Annotated[
        int | None,
        "Specifies the maximum number of audit records to return. It is either the requested limit or the API's maximum request size.",  # noqa: E501
    ] = None,
    resource_type_filter: Annotated[
        str | None,
        "Filter records by specified root resource types such as users, teams, or services.",
    ] = None,
    start_date: Annotated[
        str | None,
        "The start date for the search range. Defaults to 24 hours ago if not specified.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listAuditRecords'."]:
    """Retrieve audit trail records from PagerDuty.

    Use this tool to list audit trail records from PagerDuty based on specified query parameters or default criteria. Only accessible by admins, account owners, or authorized tokens on specific pricing plans. Records are sorted by execution time, from newest to oldest. Useful for tracking changes and activities within 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="https://api.pagerduty.com/audit/records",
        method="GET",
        params=remove_none_values({
            "limit": record_limit,
            "cursor": next_result_cursor,
            "since": start_date,
            "until": end_date_range,
            "root_resource_types[]": resource_type_filter,
            "actor_type": actor_type_filter,
            "actor_id": filter_by_actor_id,
            "method_type": method_type_filter,
            "method_truncated_token": method_truncated_token,
            "actions[]": action_filters,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_automation_action(
    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 'createAutomationAction'."]:
    """Create a script, process, or runbook automation action.

    This tool creates an automation action such as a script, process automation, or runbook automation action in PagerDuty. Call this when you need to automate or manage workflows.

    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["CREATEAUTOMATIONACTION"],
            "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["CREATEAUTOMATIONACTION"] + "\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["CREATEAUTOMATIONACTION"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/automation_actions/actions",
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATEAUTOMATIONACTION"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_automation_actions(
    context: ToolContext,
    classification_filter: Annotated[
        str | None,
        "Filters results to include only those matching the specified classification, such as 'diagnostic' or 'remediation'.",  # noqa: E501
    ] = None,
    filter_by_action_type: Annotated[
        str | None,
        "Filter results to include only those matching the specified action type. Accepts 'script' or 'process_automation'.",  # noqa: E501
    ] = None,
    filter_by_name: Annotated[
        str | None,
        "Filters results to include actions matching the specified name using case insensitive substring matching.",  # noqa: E501
    ] = None,
    filter_by_runner_id: Annotated[
        str | None,
        "Filter results to include actions linked to a specific runner. Use 'any' to include only those linked to any runner, excluding unlinked actions.",  # noqa: E501
    ] = None,
    filter_by_service_id: Annotated[
        str | None,
        "Filters results to include only those actions associated with the specified service ID.",
    ] = None,
    filter_by_team_id: Annotated[
        str | None,
        "Filters results to include actions associated with a specified team by providing its ID.",
    ] = None,
    max_results: Annotated[
        int | None,
        "Maximum number of results to return, limited by the API's maximum request size.",
    ] = None,
    next_page_cursor: Annotated[
        str | None,
        "Cursor to request the next set of results, typically obtained from the previous response.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getAllAutomationActions'."]:
    """Retrieve all automation actions with optional query filters.

    Use this tool to list all available automation actions from PagerDuty, filtered by any specified query parameters. Results are sorted alphabetically by action name and can be paginated."""  # 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="https://api.pagerduty.com/automation_actions/actions",
        method="GET",
        params=remove_none_values({
            "limit": max_results,
            "cursor": next_page_cursor,
            "name": filter_by_name,
            "runner_id": filter_by_runner_id,
            "classification": classification_filter,
            "team_id": filter_by_team_id,
            "service_id": filter_by_service_id,
            "action_type": filter_by_action_type,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_automation_action(
    context: ToolContext,
    resource_id: Annotated[str, "The unique identifier for the automation action to retrieve."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getAutomationAction'."]:
    """Retrieve details of a specific automation action.

    This tool is used to get details of a specific automation action by its ID in PagerDuty."""
    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="https://api.pagerduty.com/automation_actions/actions/{id}".format(id=resource_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def delete_automation_action(
    context: ToolContext,
    resource_id: Annotated[
        str,
        "The unique ID of the automation action to be deleted. Required for identifying the specific resource.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteAutomationAction'."]:
    """Delete an automation action by ID.

    This tool deletes a specified automation action in PagerDuty using its unique ID. Use when you need to remove an existing automation action 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="https://api.pagerduty.com/automation_actions/actions/{id}".format(id=resource_id),  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_automation_action(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The unique identifier of the automation action to update.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateAutomationAction'."]:
    """Update an existing automation action.

    Use this tool to update the details of an existing automation action by specifying its ID.

    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["UPDATEAUTOMATIONACTION"],
            "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 resource_id:
        missing_params.append(("resource_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["UPDATEAUTOMATIONACTION"] + "\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["UPDATEAUTOMATIONACTION"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/automation_actions/actions/{id}".format(id=resource_id),  # noqa: UP032
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEAUTOMATIONACTION"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def invoke_automation_action(
    context: ToolContext,
    incident_id: Annotated[
        str,
        "The ID of the incident associated with the automation action invocation. This ties the action to a specific incident.",  # noqa: E501
    ],
    resource_id: Annotated[str, "The unique identifier for the resource to be invoked."],
    alert_id_metadata: Annotated[
        str | None,
        "The alert ID to be used in the invocation metadata for the automation action. This identifier specifies which alert is associated with the action.",  # noqa: E501
    ] = None,
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'createAutomationActionInvocation'."
]:
    """Triggers an automation action in PagerDuty.

    Use this tool to invoke an automation action in PagerDuty by specifying the action ID in the URL path. Ideal for automating processes or triggering predefined workflows."""  # noqa: E501
    request_data: Any = {
        "invocation": {"metadata": {"incident_id": incident_id, "alert_id": alert_id_metadata}}
    }
    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="https://api.pagerduty.com/automation_actions/actions/{id}/invocations".format(  # noqa: UP032
            id=resource_id
        ),
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_service_references_for_automation_action(
    context: ToolContext,
    resource_id: Annotated[str, "The unique identifier for the automation action resource."],
) -> Annotated[
    dict[str, Any],
    "Response from the API endpoint 'getAutomationActionsActionServiceAssociations'.",
]:
    """Retrieve services linked to a specific automation action.

    Use this tool to obtain all service references associated with a given Automation Action. It's useful for understanding which services are connected to a particular action in your PagerDuty setup."""  # 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="https://api.pagerduty.com/automation_actions/actions/{id}/services".format(  # noqa: UP032
            id=resource_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def associate_automation_action_with_service(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The unique identifier of the resource to be associated with the service.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'createAutomationActionServiceAssocation'."
]:
    """Associate an Automation Action with a service.

    This tool is used to associate a specified Automation Action with a service in PagerDuty. Call this tool when you need to link an action to a service for automation purposes.

    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["ASSOCIATEAUTOMATIONACTIONWITHSERVICE"],
            "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 resource_id:
        missing_params.append(("resource_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["ASSOCIATEAUTOMATIONACTIONWITHSERVICE"]
                + "\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["ASSOCIATEAUTOMATIONACTIONWITHSERVICE"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/automation_actions/actions/{id}/services".format(  # noqa: UP032
            id=resource_id
        ),
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["ASSOCIATEAUTOMATIONACTIONWITHSERVICE"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_automation_action_service_association(
    context: ToolContext,
    resource_id: Annotated[
        str,
        "The ID of the resource to retrieve details about. This identifies the specific Automation Action.",  # noqa: E501
    ],
    service_identifier: Annotated[
        str,
        "The unique identifier for the service to retrieve its relation with the Automation Action.",  # noqa: E501
    ],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'getAutomationActionsActionServiceAssociation'."
]:
    """Retrieve details of an Automation Action and service relation.

    Call this tool to get information about the relationship between a specific Automation Action and a service on PagerDuty."""  # 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="https://api.pagerduty.com/automation_actions/actions/{id}/services/{service_id}".format(  # noqa: UP032
            id=resource_id, service_id=service_identifier
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def disassociate_automation_action_from_service(
    context: ToolContext,
    resource_id: Annotated[str, "The unique identifier of the resource to disassociate."],
    service_id: Annotated[
        str,
        "The unique identifier of the service to be disassociated from the automation action. This should be provided as a string.",  # noqa: E501
    ],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'deleteAutomationActionServiceAssociation'."
]:
    """Disassociate an Automation Action from a service.

    Use this tool to remove the association between an Automation Action and a specific service in PagerDuty. Call this tool when you need to unlink an action from a service for organizational or operational 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="https://api.pagerduty.com/automation_actions/actions/{id}/services/{service_id}".format(  # noqa: UP032
            id=resource_id, service_id=service_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def associate_automation_action_with_team(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The unique identifier of the resource to be associated with a team.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'createAutomationActionTeamAssociation'."
]:
    """Associate an Automation Action with a team.

    Use this tool to link a specific automation action to a designated team in PagerDuty. It should be called when there's a need to establish or update the association between an existing action and a team.

    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["ASSOCIATEAUTOMATIONACTIONWITHTEAM"],
            "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 resource_id:
        missing_params.append(("resource_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["ASSOCIATEAUTOMATIONACTIONWITHTEAM"]
                + "\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["ASSOCIATEAUTOMATIONACTIONWITHTEAM"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/automation_actions/actions/{id}/teams".format(  # noqa: UP032
            id=resource_id
        ),
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["ASSOCIATEAUTOMATIONACTIONWITHTEAM"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_team_references_for_automation_action(
    context: ToolContext,
    resource_id: Annotated[
        str, "The ID of the Automation Action resource to retrieve associated teams for."
    ],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'getAutomationActionsActionTeamAssociations'."
]:
    """Retrieve teams associated with a specific automation action.

    This tool retrieves all team references linked to a given Automation Action. It's useful for understanding which teams are involved with or responsible for specific 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="https://api.pagerduty.com/automation_actions/actions/{id}/teams".format(  # noqa: UP032
            id=resource_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def disassociate_automation_action_from_team(
    context: ToolContext,
    resource_id: Annotated[str, "The ID of the automation action to disassociate from the team."],
    team_id: Annotated[
        str, "The unique identifier of the team to be disassociated from an automation action."
    ],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'deleteAutomationActionTeamAssociation'."
]:
    """Disassociate an automation action from a team in PagerDuty.

    Use this tool to disassociate a specified automation action from a specific team in PagerDuty. Useful for removing team associations with automation actions 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="https://api.pagerduty.com/automation_actions/actions/{id}/teams/{team_id}".format(  # noqa: UP032
            id=resource_id, team_id=team_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_automation_action_team_association(
    context: ToolContext,
    resource_id: Annotated[
        str, "The unique ID of the resource (Automation Action) to retrieve details for."
    ],
    team_id: Annotated[
        str, "The unique identifier for the team associated with the Automation Action."
    ],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'getAutomationActionsActionTeamAssociation'."
]:
    """Retrieve details of an Automation Action and team relationship.

    This tool retrieves the details of a relationship between a specific Automation Action and a team within PagerDuty. It should be called when you need to understand or verify the association details between an action and a team."""  # 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="https://api.pagerduty.com/automation_actions/actions/{id}/teams/{team_id}".format(  # noqa: UP032
            id=resource_id, team_id=team_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_automation_action_invocations(
    context: ToolContext,
    action_id: Annotated[
        str | None, "The unique identifier for the action to filter invocations by."
    ] = None,
    exclude_invocation_state: Annotated[
        str | None,
        "Filter out invocations not in the specified state. Supported states: prepared, created, sent, queued, running, aborted, completed, error, unknown.",  # noqa: E501
    ] = None,
    filter_by_invocation_state: Annotated[
        str | None,
        "Filter the invocations by their state. Options include 'prepared', 'created', 'sent', 'queued', 'running', 'aborted', 'completed', 'error', or 'unknown'.",  # noqa: E501
    ] = None,
    incident_id: Annotated[
        str | None,
        "The unique identifier for the incident. Use this to filter invocations related to a specific incident.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listAutomationActionInvocations'."]:
    """Retrieve a list of automation action invocations.

    Call this tool to obtain a list of automation action invocations from PagerDuty. This can be useful for tracking and managing automation actions within your 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="https://api.pagerduty.com/automation_actions/invocations",
        method="GET",
        params=remove_none_values({
            "invocation_state": filter_by_invocation_state,
            "not_invocation_state": exclude_invocation_state,
            "incident_id": incident_id,
            "action_id": action_id,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_automation_action_invocation(
    context: ToolContext,
    resource_id: Annotated[
        str, "The unique identifier of the automation action resource to retrieve."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getAutomationActionsInvocation'."]:
    """Retrieve details of an automation action invocation.

    This tool is used to obtain detailed information about a specific automation action invocation by its ID. Call this tool when you need to track or review an action performed through PagerDuty's automation services."""  # 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="https://api.pagerduty.com/automation_actions/invocations/{id}".format(id=resource_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_automation_runner(
    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 'createAutomationActionsRunner'."]:
    """Create a Process or Runbook Automation runner.

    Use this tool to create a new Process Automation or Runbook Automation runner in PagerDuty.

    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["CREATEAUTOMATIONRUNNER"],
            "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["CREATEAUTOMATIONRUNNER"] + "\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["CREATEAUTOMATIONRUNNER"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/automation_actions/runners",
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATEAUTOMATIONRUNNER"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_automation_action_runners(
    context: ToolContext,
    include_additional_data_elements: Annotated[
        list[str] | None,
        "List of additional data elements to include in the response. Each entry should be a string representing the type of data element to include.",  # noqa: E501
    ] = None,
    next_cursor: Annotated[
        str | None,
        "Optional cursor for requesting the next set of results. Use the value obtained from a previous response's `next_cursor`. If not provided, retrieval starts from the beginning.",  # noqa: E501
    ] = None,
    result_limit: Annotated[
        int | None,
        "Specifies the maximum number of Automation Action runners to return in the response. The actual response will have a minimum of this limit or the maximum allowed by the API.",  # noqa: E501
    ] = None,
    runner_name_filter: Annotated[
        str | None,
        "Filter results to include Automation Action runners with names matching this substring (case insensitive).",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getAutomationActionsRunners'."]:
    """Retrieve a list of Automation Action runners.

    Fetches and lists the Automation Action runners that match provided query parameters, sorted by runner name. Useful for managing and reviewing automation runners on PagerDuty."""  # 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="https://api.pagerduty.com/automation_actions/runners",
        method="GET",
        params=remove_none_values({
            "limit": result_limit,
            "cursor": next_cursor,
            "name": runner_name_filter,
            "include[]": include_additional_data_elements,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_automation_action_runner(
    context: ToolContext,
    resource_id: Annotated[
        str, "The unique identifier for the Automation Action runner to retrieve details."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getAutomationActionsRunner'."]:
    """Retrieve details of an Automation Action runner by ID.

    This tool fetches information about a specific Automation Action runner from PagerDuty based on the provided ID. Use it to get runner details when managing or monitoring automation 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="https://api.pagerduty.com/automation_actions/runners/{id}".format(id=resource_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_automation_action_runner(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The unique identifier of the Automation Action runner to update.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateAutomationActionsRunner'."]:
    """Update an Automation Action runner in PagerDuty.

    This tool updates the configuration of a specific Automation Action runner in PagerDuty. It should be called when you need to modify the settings or details of an existing runner, such as changing the runner's parameters or 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["UPDATEAUTOMATIONACTIONRUNNER"],
            "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 resource_id:
        missing_params.append(("resource_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["UPDATEAUTOMATIONACTIONRUNNER"]
                + "\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["UPDATEAUTOMATIONACTIONRUNNER"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/automation_actions/runners/{id}".format(id=resource_id),  # noqa: UP032
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEAUTOMATIONACTIONRUNNER"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def delete_automation_action_runner(
    context: ToolContext,
    runner_id: Annotated[str, "The unique ID of the Automation Action runner to delete."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteAutomationActionsRunner'."]:
    """Delete an Automation Action runner by ID.

    Use this tool to delete an existing Automation Action runner in PagerDuty by providing its ID. It should be called when you need to remove a runner and no longer require it for automation tasks."""  # 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="https://api.pagerduty.com/automation_actions/runners/{id}".format(id=runner_id),  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def associate_runner_with_team(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "Unique identifier for the resource to associate a runner with a team in PagerDuty.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'createAutomationActionsRunnerTeamAssociation'."
]:
    """Associate a runner with a specified team.

    This tool allows you to associate a specific runner with a team in PagerDuty. Use it when you need to link automation actions runners to teams.

    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["ASSOCIATERUNNERWITHTEAM"],
            "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 resource_id:
        missing_params.append(("resource_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["ASSOCIATERUNNERWITHTEAM"] + "\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["ASSOCIATERUNNERWITHTEAM"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/automation_actions/runners/{id}/teams".format(  # noqa: UP032
            id=resource_id
        ),
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["ASSOCIATERUNNERWITHTEAM"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_runner_team_associations(
    context: ToolContext,
    runner_resource_id: Annotated[
        str, "The ID of the automation actions runner to retrieve associated team references for."
    ],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'getAutomationActionsRunnerTeamAssociations'."
]:
    """Retrieve team references linked to a specific runner.

    Fetches all team references linked to a specified automation actions runner in PagerDuty, helpful for understanding team associations for automation 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="https://api.pagerduty.com/automation_actions/runners/{id}/teams".format(  # noqa: UP032
            id=runner_resource_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def disassociate_runner_from_team(
    context: ToolContext,
    resource_id: Annotated[
        str,
        "The unique ID of the resource to be disassociated from the team. This is required to identify the runner.",  # noqa: E501
    ],
    team_id: Annotated[
        str, "The unique identifier for the team from which the runner will be disassociated."
    ],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'deleteAutomationActionsRunnerTeamAssociation'."
]:
    """Disassociate a runner from a team in PagerDuty.

    Call this tool to remove the association between a runner and a team within the PagerDuty 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="https://api.pagerduty.com/automation_actions/runners/{id}/teams/{team_id}".format(  # noqa: UP032
            id=resource_id, team_id=team_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_runner_team_association(
    context: ToolContext,
    resource_id: Annotated[
        str, "The unique identifier for the resource to fetch runner-team association details."
    ],
    team_identifier: Annotated[
        str, "The unique ID representing the team for which the runner relation details are needed."
    ],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'getAutomationActionsRunnerTeamAssociation'."
]:
    """Retrieve details of a runner and team relationship.

    Call this tool to obtain details about the relationship between a runner and a team within an automation actions context. Useful for understanding team assignments and runner affiliations."""  # 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="https://api.pagerduty.com/automation_actions/runners/{id}/teams/{team_id}".format(  # noqa: UP032
            id=resource_id, team_id=team_identifier
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_business_services(
    context: ToolContext,
    include_total_count: Annotated[
        bool | None, "Set to true to include the total count of results in the pagination response."
    ] = False,
    pagination_offset: Annotated[
        int | None,
        "Offset to start pagination of the search results. Use this to skip a set number of entries.",  # noqa: E501
    ] = None,
    results_per_page: Annotated[
        int | None, "Specify the number of results to display on each page."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listBusinessServices'."]:
    """Retrieve a list of existing business services.

    Use this tool to obtain a comprehensive list of business services, which model capabilities spanning multiple technical services and are often owned by different teams. Beneficial for understanding service inventory and 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="https://api.pagerduty.com/business_services",
        method="GET",
        params=remove_none_values({
            "limit": results_per_page,
            "offset": pagination_offset,
            "total": include_total_count,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_business_service(
    context: ToolContext,
    business_service_description: Annotated[
        str | None,
        "Provide a description for the Business Service. This should clearly outline the service's purpose and scope.",  # noqa: E501
    ] = None,
    business_service_name: Annotated[
        str | None, "The name of the Business Service to be created."
    ] = None,
    business_service_owner: Annotated[
        str | None, "The owner or point of contact for the business service."
    ] = None,
    team_id: Annotated[
        str | None, "The unique identifier for the team associated with the business service."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'createBusinessService'."]:
    """Create a new business service in PagerDuty.

    Use this tool to create a new business service, which represents capabilities spanning multiple technical services, possibly owned by various teams. Make sure not to exceed the account limit of 5,000 business services."""  # noqa: E501
    request_data: Any = {
        "business_service": {
            "name": business_service_name,
            "description": business_service_description,
            "point_of_contact": business_service_owner,
            "team": {"id": team_id},
        }
    }
    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="https://api.pagerduty.com/business_services",
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_business_service_details(
    context: ToolContext,
    business_service_id: Annotated[str, "The ID of the business service to retrieve details for."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getBusinessService'."]:
    """Retrieve details about a specific Business Service.

    This tool retrieves comprehensive details about a Business Service in PagerDuty, which models capabilities across technical services and teams."""  # 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="https://api.pagerduty.com/business_services/{id}".format(id=business_service_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def delete_business_service(
    context: ToolContext,
    business_service_id: Annotated[
        str, "The unique identifier of the Business Service to be deleted."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteBusinessService'."]:
    """Delete an existing Business Service in PagerDuty.

    This tool deletes a specified Business Service in PagerDuty. Once deleted, the service will not be accessible from the web UI, and new incidents cannot be created for it. Call this tool when you need to remove a business service that spans technical services and is owned by multiple teams."""  # 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="https://api.pagerduty.com/business_services/{id}".format(id=business_service_id),  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_business_service(
    context: ToolContext,
    resource_id: Annotated[
        str, "The unique identifier for the business service that needs updating."
    ],
    business_service_description: Annotated[
        str | None, "The description of the Business Service to be updated."
    ] = None,
    business_service_name: Annotated[
        str | None, "The name of the Business Service to be updated."
    ] = None,
    business_service_owner: Annotated[
        str | None,
        "Specify the owner of the Business Service. Typically, this should be the point of contact responsible for the service.",  # noqa: E501
    ] = None,
    team_id: Annotated[
        str | None, "The ID of the team associated with the business service."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'updateBusinessService'."]:
    """Update the details of a business service in PagerDuty.

    Use this tool to update an existing business service, which models capabilities across multiple technical services. This tool is useful when business services require modifications, such as changes in ownership or scope. It requires the `services.write` OAuth scope."""  # noqa: E501
    request_data: Any = {
        "business_service": {
            "name": business_service_name,
            "description": business_service_description,
            "point_of_contact": business_service_owner,
            "team": {"id": team_id},
        }
    }
    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="https://api.pagerduty.com/business_services/{id}".format(id=resource_id),  # noqa: UP032
        method="PUT",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def subscribe_to_business_service(
    context: ToolContext,
    resource_id: Annotated[str, "The ID of the business service resource to subscribe to."],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'createBusinessServiceAccountSubscription'."
]:
    """Subscribe your account to a PagerDuty business service.

    Use this tool to subscribe your account to a specified business service in PagerDuty. Authorization with the 'subscribers.write' scope is required for this action."""  # 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="https://api.pagerduty.com/business_services/{id}/account_subscription".format(  # noqa: UP032
            id=resource_id
        ),
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def unsubscribe_from_business_service(
    context: ToolContext,
    business_service_id: Annotated[
        str, "The unique identifier of the business service to unsubscribe from."
    ],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'removeBusinessServiceAccountSubscription'."
]:
    """Unsubscribe an account from a business service.

    Use this tool to remove your account's subscription from a specified business service. This action requires appropriate OAuth permissions ('subscribers.write')."""  # 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="https://api.pagerduty.com/business_services/{id}/account_subscription".format(  # noqa: UP032
            id=business_service_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_business_service_subscribers(
    context: ToolContext,
    business_service_id: Annotated[
        str, "The unique identifier for the business service to retrieve subscribers."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getBusinessServiceSubscribers'."]:
    """Retrieve notification subscribers of a business service.

    Fetches a list of notification subscribers for a specified business service. Use this tool when you need to find out who is subscribed to notifications for a particular service. Ensure users were added as subscribers via the appropriate POST method."""  # 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="https://api.pagerduty.com/business_services/{id}/subscribers".format(  # noqa: UP032
            id=business_service_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def subscribe_business_service_entities(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The unique identifier of the business service to which entities will be subscribed.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'createBusinessServiceNotificationSubscribers'."
]:
    """Subscribe entities to a specified business service.

    This tool subscribes specified entities to a business service, allowing them to receive notifications. It should be called when you need to add entities to the notification list for a business service.

    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["SUBSCRIBEBUSINESSSERVICEENTITIES"],
            "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 resource_id:
        missing_params.append(("resource_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["SUBSCRIBEBUSINESSSERVICEENTITIES"]
                + "\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["SUBSCRIBEBUSINESSSERVICEENTITIES"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/business_services/{id}/subscribers".format(id=resource_id),  # noqa: UP032
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["SUBSCRIBEBUSINESSSERVICEENTITIES"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def retrieve_impactful_supporting_business_services(
    context: ToolContext,
    service_id: Annotated[
        str,
        "The unique identifier for the business service to retrieve its supporting services by impact.",  # noqa: E501
    ],
    include_additional_fields: Annotated[
        str | None,
        "Specify additional fields to include, such as highest impacting priority or total impacted count. Accepts 'services.highest_impacting_priority' or 'total_impacted_count'.",  # noqa: E501
    ] = None,
    resource_ids: Annotated[
        str | None,
        "List of resource IDs to retrieve their supporting Business Services impacts. Include multiple IDs if needed.",  # noqa: E501
    ] = None,
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'getBusinessServiceSupportingServiceImpacts'."
]:
    """Retrieve top supporting Business Services by impact for a given service.

    This tool retrieves up to 200 supporting Business Services that have the highest impact on a specified Business Service. The services are sorted by impact, recency, and name. Use this tool to analyze service dependencies and impacts efficiently. Requires OAuth with 'services.read' scope."""  # 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="https://api.pagerduty.com/business_services/{id}/supporting_services/impacts".format(  # noqa: UP032
            id=service_id
        ),
        method="GET",
        params=remove_none_values({
            "additional_fields[]": include_additional_fields,
            "ids[]": resource_ids,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def unsubscribe_business_service_notifications(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The unique identifier of the resource to unsubscribe from.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'removeBusinessServiceNotificationSubscriber'."
]:
    """Unsubscribe users from Business Service notifications.

    Use this tool to unsubscribe specific users from receiving notifications for a particular Business Service on PagerDuty.

    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["UNSUBSCRIBEBUSINESSSERVICENOTIFICATIONS"],
            "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 resource_id:
        missing_params.append(("resource_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["UNSUBSCRIBEBUSINESSSERVICENOTIFICATIONS"]
                + "\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["UNSUBSCRIBEBUSINESSSERVICENOTIFICATIONS"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/business_services/{id}/unsubscribe".format(id=resource_id),  # noqa: UP032
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UNSUBSCRIBEBUSINESSSERVICENOTIFICATIONS"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_top_level_impactors_for_business_services(
    context: ToolContext,
    business_service_ids: Annotated[
        str | None, "List of business service IDs to fetch impactors for."
    ] = None,
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'getBusinessServiceTopLevelImpactors'."
]:
    """Retrieve high-priority incidents impacting top-level business services.

    Use this tool to obtain a list of the most critical incidents (impactors) affecting the top-level business services in your account, up to a limit of 200. These incidents are sorted by priority and creation date. Utilize the `ids[]` parameter to specify particular business services."""  # 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="https://api.pagerduty.com/business_services/impactors",
        method="GET",
        params=remove_none_values({"ids[]": business_service_ids}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_business_service_impacts(
    context: ToolContext,
    business_service_ids: Annotated[
        str | None, "A list of specific Business Service IDs to retrieve impact information for."
    ] = None,
    include_additional_fields: Annotated[
        str | None,
        "Specify additional fields to include, such as 'services.highest_impacting_priority' or 'total_impacted_count'.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getBusinessServiceImpacts'."]:
    """Get top-level Business Services sorted by highest impact.

    Retrieve the most impacted Business Services, up to 200, with their status. The service list is sorted by impact, recency, and name. For specific services, use the `ids[]` parameter. Requires 'services.read' scope."""  # 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="https://api.pagerduty.com/business_services/impacts",
        method="GET",
        params=remove_none_values({
            "additional_fields[]": include_additional_fields,
            "ids[]": business_service_ids,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_priority_thresholds(
    context: ToolContext,
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'getBusinessServicePriorityThresholds'."
]:
    """Retrieve priority threshold details for an account.

    This tool retrieves the priority threshold information set for an account, including the global threshold impacting business services. It helps determine which incidents are considered impactful based on their priority."""  # 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="https://api.pagerduty.com/business_services/priority_thresholds",
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def clear_business_service_priority_thresholds(
    context: ToolContext,
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'deleteBusinessServicePriorityThresholds'."
]:
    """Clear priority thresholds for business services.

    This tool clears the priority thresholds for business services in the account, allowing any incident with a priority to impact them. It requires `services.write` OAuth scope."""  # 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="https://api.pagerduty.com/business_services/priority_thresholds",
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def set_business_service_priority(
    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 'putBusinessServicePriorityThresholds'."
]:
    """Set the priority threshold for a business service.

    Use this tool to update the account-level priority threshold for a business service. Requires the 'services.write' OAuth scope.

    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["SETBUSINESSSERVICEPRIORITY"],
            "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["SETBUSINESSSERVICEPRIORITY"]
                + "\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["SETBUSINESSSERVICEPRIORITY"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/business_services/priority_thresholds",
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["SETBUSINESSSERVICEPRIORITY"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_change_events(
    context: ToolContext,
    end_date_utc: Annotated[
        str | None,
        "The end date in UTC ISO 8601 format for the date range to search. Note: Must be a valid UTC string.",  # noqa: E501
    ] = None,
    include_total_in_pagination: Annotated[
        bool | None,
        "Set to true to include the total count of results in pagination responses, which is null by default.",  # noqa: E501
    ] = False,
    integration_ids: Annotated[
        list[str] | None, "Array of integration IDs; filters results to these integrations."
    ] = None,
    pagination_offset: Annotated[
        int | None, "Offset to start retrieving paginated search results."
    ] = None,
    results_per_page: Annotated[
        int | None, "Specify the number of change event results to return per page."
    ] = None,
    start_date_time_utc: Annotated[
        str | None, "The start date and time for searching change events, in UTC ISO 8601 format."
    ] = None,
    team_ids: Annotated[
        list[str] | None,
        "Array of team IDs. Filters results to those teams. Requires 'teams' ability.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listChangeEvents'."]:
    """Fetch a list of existing change events from PagerDuty.

    Use this tool to retrieve all current change events. Useful for monitoring and tracking changes within systems integrated with PagerDuty."""  # 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="https://api.pagerduty.com/change_events",
        method="GET",
        params=remove_none_values({
            "limit": results_per_page,
            "offset": pagination_offset,
            "total": include_total_in_pagination,
            "team_ids[]": team_ids,
            "integration_ids[]": integration_ids,
            "since": start_date_time_utc,
            "until": end_date_utc,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def send_change_event(
    context: ToolContext,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'createChangeEvent'."]:
    """Send a change event to PagerDuty's API.

    Use this tool to send change events to PagerDuty via the V2 Events API. Useful for logging changes in systems and notifying PagerDuty of updates."""  # 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="https://api.pagerduty.com/change_events",
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_change_event_details(
    context: ToolContext,
    change_event_id: Annotated[
        str, "The unique identifier of the Change Event to retrieve details for."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getChangeEvent'."]:
    """Retrieve detailed information about a Change Event.

    Use this tool to get details about a specific Change Event by providing its ID. Useful for tracking or analyzing changes in your 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="https://api.pagerduty.com/change_events/{id}".format(id=change_event_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_change_event(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The unique identifier of the change event to be updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateChangeEvent'."]:
    """Updates an existing change event in PagerDuty.

    Use this tool to modify details of an existing change event using PagerDuty's updateChangeEvent API. Requires appropriate OAuth scope (`change_events.write`).

    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["UPDATECHANGEEVENT"],
            "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 resource_id:
        missing_params.append(("resource_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["UPDATECHANGEEVENT"] + "\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["UPDATECHANGEEVENT"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/change_events/{id}".format(id=resource_id),  # noqa: UP032
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATECHANGEEVENT"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_escalation_policies(
    context: ToolContext,
    additional_models_to_include: Annotated[
        str | None,
        "Array of models to include in the response. Options: 'services', 'teams', 'targets'.",
    ] = None,
    filter_by_user_ids: Annotated[
        list[str] | None,
        "Filters the results to show only escalation policies where any specified user is a target. Provide an array of user IDs.",  # noqa: E501
    ] = None,
    include_total_in_pagination: Annotated[
        bool | None,
        "Set to true to include the total count of records in the pagination response. False ensures faster response times by setting it to null.",  # noqa: E501
    ] = False,
    name_filter_query: Annotated[
        str | None, "A string to filter results by matching escalation policy names."
    ] = None,
    pagination_offset: Annotated[
        int | None, "Offset to start pagination for search results."
    ] = None,
    results_per_page: Annotated[
        int | None, "Specifies the number of escalation policy results to display per page."
    ] = None,
    sort_by_field: Annotated[
        str | None, "Specify the sorting field for results: 'name', 'name:asc', or 'name:desc'."
    ] = "name",
    team_ids: Annotated[
        list[str] | None,
        "A list of team IDs to filter escalation policies. Requires 'teams' ability.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listEscalationPolicies'."]:
    """Retrieve all current escalation policies.

    Use this tool to obtain a list of all existing escalation policies, which define alerting priorities for users. Requires appropriate OAuth scope for access."""  # 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="https://api.pagerduty.com/escalation_policies",
        method="GET",
        params=remove_none_values({
            "limit": results_per_page,
            "offset": pagination_offset,
            "total": include_total_in_pagination,
            "query": name_filter_query,
            "user_ids[]": filter_by_user_ids,
            "team_ids[]": team_ids,
            "include[]": additional_models_to_include,
            "sort_by": sort_by_field,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_escalation_policy(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    change_tracking_user_email: Annotated[
        str | None,
        "The optional email address of a user for change tracking. Must be associated with the account making the request.  Only used when mode is 'execute'.",  # noqa: E501
    ] = None,
    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 'createEscalationPolicy'."]:
    """Create a new escalation policy in PagerDuty.

    Use this tool to create a new escalation policy on PagerDuty. Escalation policies are used to determine which users are alerted and when. At least one escalation rule must be included. Requires OAuth scope: 'escalation_policies.write'.

    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["CREATEESCALATIONPOLICY"],
            "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["CREATEESCALATIONPOLICY"] + "\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["CREATEESCALATIONPOLICY"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/escalation_policies",
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATEESCALATIONPOLICY"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "From": change_tracking_user_email,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_escalation_policy(
    context: ToolContext,
    resource_id: Annotated[str, "The unique identifier of the escalation policy to retrieve."],
    include_models: Annotated[
        str | None,
        "Specify additional models to include in the response, such as services, teams, or targets.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getEscalationPolicy'."]:
    """Retrieve details of an escalation policy and its rules.

    Use this tool to get information about a specific escalation policy, including which users are alerted and when. This is useful for understanding alert management 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="https://api.pagerduty.com/escalation_policies/{id}".format(id=resource_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({"include[]": include_models}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def delete_escalation_policy(
    context: ToolContext,
    escalation_policy_id: Annotated[
        str,
        "The ID of the escalation policy to be deleted. Ensure the policy is not in use by any services and that you have the required permissions.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteEscalationPolicy'."]:
    """Delete an existing escalation policy from PagerDuty.

    Use this tool when you need to delete an existing escalation policy that is not in use by any services. Escalation policies define alert sequences for users. Ensure you have the necessary permissions (`escalation_policies.write`)."""  # 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="https://api.pagerduty.com/escalation_policies/{id}".format(id=escalation_policy_id),  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_escalation_policy(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    escalation_policy_id: Annotated[
        str | None,
        "The unique identifier of the escalation policy to be updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateEscalationPolicy'."]:
    """Update an existing escalation policy and its rules.

    Use this tool to update an existing escalation policy and define which user should be alerted at which time. This tool requires appropriate OAuth credentials with `escalation_policies.write` permissions.

    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["UPDATEESCALATIONPOLICY"],
            "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 escalation_policy_id:
        missing_params.append(("escalation_policy_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["UPDATEESCALATIONPOLICY"] + "\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["UPDATEESCALATIONPOLICY"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/escalation_policies/{id}".format(id=escalation_policy_id),  # noqa: UP032
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEESCALATIONPOLICY"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_escalation_policy_audit_records(
    context: ToolContext,
    resource_id: Annotated[
        str, "Identifier for the escalation policy to retrieve audit records for."
    ],
    end_date_of_search: Annotated[
        str | None,
        "The end date of the search range. Defaults to now if not specified. Cannot exceed 31 days after the start date.",  # noqa: E501
    ] = None,
    next_cursor: Annotated[
        str | None,
        "A string used to fetch the next set of results. Obtain from the `next_cursor` of the previous request. If empty, it starts from the beginning of the result set.",  # noqa: E501
    ] = None,
    result_limit: Annotated[
        int | None,
        "Specifies the maximum number of audit records to return. It's the smaller of the provided limit or the API's max size.",  # noqa: E501
    ] = None,
    start_date_for_audit_search: Annotated[
        str | None,
        "The start date for the audit record search. If not specified, defaults to 24 hours ago.",
    ] = None,
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'listEscalationPolicyAuditRecords'."
]:
    """Retrieve audit records for a specific escalation policy.

    This tool fetches the audit records of a specified escalation policy from newest to oldest. It is useful for tracking changes and understanding historical actions related to escalation policies in PagerDuty. Ensure OAuth scope 'audit_records.read' is granted."""  # 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="https://api.pagerduty.com/escalation_policies/{id}/audit/records".format(  # noqa: UP032
            id=resource_id
        ),
        method="GET",
        params=remove_none_values({
            "limit": result_limit,
            "cursor": next_cursor,
            "since": start_date_for_audit_search,
            "until": end_date_of_search,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_event_orchestrations(
    context: ToolContext,
    pagination_offset: Annotated[
        int | None, "The starting point for pagination in search results, specified as an integer."
    ] = None,
    results_per_page: Annotated[
        int | None,
        "The number of results to return per page when listing the Global Event Orchestrations.",
    ] = None,
    sort_field_with_order: Annotated[
        str | None,
        "Specify the field and order (asc/desc) for sorting results. Options include: 'name:asc', 'name:desc', 'routes:asc', 'routes:desc', 'created_at:asc', 'created_at:desc'.",  # noqa: E501
    ] = "name:asc",
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listEventOrchestrations'."]:
    """Retrieve all Global Event Orchestrations from an account.

    This tool lists all Global Event Orchestrations on an account, allowing you to manage and view the defined sets of Global and Router Rules that determine event actions and service routing. Call this tool to access orchestration details, which require 'event_orchestrations.read' OAuth scope."""  # 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="https://api.pagerduty.com/event_orchestrations",
        method="GET",
        params=remove_none_values({
            "limit": results_per_page,
            "offset": pagination_offset,
            "sort_by": sort_field_with_order,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_global_event_orchestration(
    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 'postOrchestration'."]:
    """Create a Global Event Orchestration in PagerDuty.

    This tool allows you to create a Global Event Orchestration, defining Global Rules and Router Rules for event processing and routing based on event content.

    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["CREATEGLOBALEVENTORCHESTRATION"],
            "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["CREATEGLOBALEVENTORCHESTRATION"]
                + "\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["CREATEGLOBALEVENTORCHESTRATION"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/event_orchestrations",
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATEGLOBALEVENTORCHESTRATION"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_global_event_orchestration(
    context: ToolContext,
    event_orchestration_id: Annotated[
        str, "The unique identifier for the Event Orchestration to be retrieved."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getOrchestration'."]:
    """Retrieve details of a Global Event Orchestration by ID.

    Fetches information about a specific Global Event Orchestration including its Global Rules and Router Rules, allowing you to understand how events are processed and routed based on their content."""  # 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="https://api.pagerduty.com/event_orchestrations/{id}".format(id=event_orchestration_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_event_orchestration(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    event_orchestration_id: Annotated[
        str | None,
        "The unique identifier for the Event Orchestration to update.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateOrchestration'."]:
    """Update a Global Event Orchestration in PagerDuty.

    This tool updates a Global Event Orchestration, allowing users to define and modify sets of Global Rules and Router Rules for event routing and processing. It requires 'event_orchestrations.write' permission.

    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["UPDATEEVENTORCHESTRATION"],
            "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 event_orchestration_id:
        missing_params.append(("event_orchestration_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["UPDATEEVENTORCHESTRATION"] + "\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["UPDATEEVENTORCHESTRATION"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/event_orchestrations/{id}".format(id=event_orchestration_id),  # noqa: UP032
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEEVENTORCHESTRATION"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def delete_event_orchestration(
    context: ToolContext,
    event_orchestration_id: Annotated[str, "The ID of the Global Event Orchestration to delete."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteOrchestration'."]:
    """Delete a Global Event Orchestration on PagerDuty.

    This tool deletes a specified Global Event Orchestration, preventing further event ingestion using the orchestration's routing key. Use when you need to remove an orchestration from PagerDuty."""  # 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="https://api.pagerduty.com/event_orchestrations/{id}".format(id=event_orchestration_id),  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_orchestration_integrations(
    context: ToolContext,
    event_orchestration_id: Annotated[
        str,
        "The unique identifier for the Event Orchestration to retrieve integrations for. This ID is necessary to specify which event orchestration's integrations you wish to list.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listOrchestrationIntegrations'."]:
    """Retrieve integrations for an event orchestration.

    Use this tool to obtain the integrations linked to a specific event orchestration in PagerDuty. These integrations provide routing keys to send events to PagerDuty. Requires 'event_orchestrations.read' scope with OAuth."""  # 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="https://api.pagerduty.com/event_orchestrations/{id}/integrations".format(  # noqa: UP032
            id=event_orchestration_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_event_integration(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    event_orchestration_id: Annotated[
        str | None,
        "The unique identifier for the Event Orchestration within PagerDuty.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'postOrchestrationIntegration'."]:
    """Create an integration for event orchestration in PagerDuty.

    This tool creates an integration associated with a specified event orchestration in PagerDuty. Use this to obtain a Routing Key for sending events. Requires `event_orchestrations.write` permission.

    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["CREATEEVENTINTEGRATION"],
            "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 event_orchestration_id:
        missing_params.append(("event_orchestration_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["CREATEEVENTINTEGRATION"] + "\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["CREATEEVENTINTEGRATION"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/event_orchestrations/{id}/integrations".format(  # noqa: UP032
            id=event_orchestration_id
        ),
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATEEVENTINTEGRATION"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_integration_details(
    context: ToolContext,
    event_orchestration_id: Annotated[
        str, "The ID of the Event Orchestration to retrieve integration details for."
    ],
    integration_id: Annotated[
        str,
        "The ID of the integration to retrieve details for within an event orchestration in PagerDuty.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getOrchestrationIntegration'."]:
    """Retrieve details of an orchestration integration.

    Use this tool to obtain details about a specific integration associated with event orchestrations in PagerDuty. This can help in managing event routing using the provided integration's routing key. Requires 'event_orchestrations.read' OAuth scope."""  # 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="https://api.pagerduty.com/event_orchestrations/{id}/integrations/{integration_id}".format(  # noqa: UP032
            id=event_orchestration_id, integration_id=integration_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_event_integration(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    event_orchestration_id: Annotated[
        str | None,
        "The unique ID of the event orchestration to update.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    integration_id_for_update: Annotated[
        str | None,
        "The ID of an Integration to update within the event orchestration.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateOrchestrationIntegration'."]:
    """Update an event orchestration integration.

    Use this tool to update an integration associated with an event orchestration. This is useful when you need to configure or change settings for how events are sent to PagerDuty using a specific integration.

    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["UPDATEEVENTINTEGRATION"],
            "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 event_orchestration_id:
        missing_params.append(("event_orchestration_id", "path"))
    if not integration_id_for_update:
        missing_params.append(("integration_id_for_update", "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["UPDATEEVENTINTEGRATION"] + "\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["UPDATEEVENTINTEGRATION"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/event_orchestrations/{id}/integrations/{integration_id}".format(  # noqa: UP032
            id=event_orchestration_id, integration_id=integration_id_for_update
        ),
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEEVENTINTEGRATION"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def delete_integration_routing_key(
    context: ToolContext,
    event_orchestration_id: Annotated[
        str, "The identifier for the Event Orchestration to be deleted."
    ],
    integration_id: Annotated[
        str,
        "The unique ID of the integration to be deleted. This is necessary to identify which integration and its routing key should be removed.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteOrchestrationIntegration'."]:
    """Delete an integration and its associated routing key.

    Use this tool to delete an integration and its associated routing key in PagerDuty. Once deleted, all future events sent using the routing key will be dropped. Requires specific OAuth permissions."""  # 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="https://api.pagerduty.com/event_orchestrations/{id}/integrations/{integration_id}".format(  # noqa: UP032
            id=event_orchestration_id, integration_id=integration_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def migrate_integration_to_event_orchestration(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    event_orchestration_id: Annotated[
        str | None,
        "The unique identifier of an Event Orchestration to migrate the integration to.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'migrateOrchestrationIntegration'."]:
    """Migrate an integration to a different event orchestration.

    Move an Integration and its Routing Key from one Event Orchestration to another as specified in the request. Future events will be processed by the new Event Orchestration's Rules. Requires appropriate OAuth permissions.

    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["MIGRATEINTEGRATIONTOEVENTORCHESTRATION"],
            "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 event_orchestration_id:
        missing_params.append(("event_orchestration_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["MIGRATEINTEGRATIONTOEVENTORCHESTRATION"]
                + "\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["MIGRATEINTEGRATIONTOEVENTORCHESTRATION"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/event_orchestrations/{id}/integrations/migration".format(  # noqa: UP032
            id=event_orchestration_id
        ),
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["MIGRATEINTEGRATIONTOEVENTORCHESTRATION"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_global_orchestration_rules(
    context: ToolContext,
    event_orchestration_id: Annotated[
        str, "The ID of the specific Event Orchestration to retrieve rules for."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getOrchPathGlobal'."]:
    """Retrieve global orchestration rules for an event.

    This tool fetches the global orchestration rules for a specified event orchestration, which contains a set of event rules applicable to all incoming events. These rules can modify, enhance, and route the event for further processing."""  # 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="https://api.pagerduty.com/event_orchestrations/{id}/global".format(  # noqa: UP032
            id=event_orchestration_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_event_orchestration_global_rules(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    event_orchestration_id: Annotated[
        str | None,
        "The unique identifier for an Event Orchestration to update its global rules.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateOrchPathGlobal'."]:
    """Update global orchestration rules for event orchestration.

    This tool updates the Global Orchestration Rules for an Event Orchestration in PagerDuty. It is used to modify and enhance events by evaluating them against a set of global rules and potentially routing them for further processing. Use this tool when you need to adjust the rules governing all events within a specific orchestration.

    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["UPDATEEVENTORCHESTRATIONGLOBALRULES"],
            "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 event_orchestration_id:
        missing_params.append(("event_orchestration_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["UPDATEEVENTORCHESTRATIONGLOBALRULES"]
                + "\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["UPDATEEVENTORCHESTRATIONGLOBALRULES"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/event_orchestrations/{id}/global".format(  # noqa: UP032
            id=event_orchestration_id
        ),
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEEVENTORCHESTRATIONGLOBALRULES"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_global_orchestration_routing_rules(
    context: ToolContext,
    event_orchestration_id: Annotated[
        str, "The ID of the Event Orchestration to retrieve routing rules for."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getOrchPathRouter'."]:
    """Retrieve Global Orchestration's routing rules from PagerDuty.

    This tool retrieves the routing rules for a specified Global Orchestration in PagerDuty. It evaluates events against these rules to determine routing to a specific service. If no rules match, events are sent to a default service or an \"Unrouted\" Orchestration. This is useful for understanding event pathways and ensuring proper event management and routing."""  # 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="https://api.pagerduty.com/event_orchestrations/{id}/router".format(  # noqa: UP032
            id=event_orchestration_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_orchestration_routing_rules(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    event_orchestration_id: Annotated[
        str | None,
        "The unique identifier for the Event Orchestration to be updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateOrchPathRouter'."]:
    """Update rules for routing events in Global Orchestration.

    This tool updates the routing rules for a Global Orchestration in PagerDuty. It evaluates events against rules to determine routing to specific services. Use this tool when you need to modify how events are routed within a global orchestration. Requires necessary OAuth permissions.

    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["UPDATEORCHESTRATIONROUTINGRULES"],
            "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 event_orchestration_id:
        missing_params.append(("event_orchestration_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["UPDATEORCHESTRATIONROUTINGRULES"]
                + "\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["UPDATEORCHESTRATIONROUTINGRULES"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/event_orchestrations/{id}/router".format(  # noqa: UP032
            id=event_orchestration_id
        ),
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEORCHESTRATIONROUTINGRULES"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_unrouted_event_orchestration_rules(
    context: ToolContext,
    event_orchestration_id: Annotated[
        str, "The unique identifier for the Event Orchestration to retrieve unrouted event rules."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getOrchPathUnrouted'."]:
    """Retrieve rules for unrouted event orchestration in PagerDuty.

    This tool retrieves the set of rules used in a Global Event Orchestration for handling unrouted events in PagerDuty. It should be called to understand how events that don't match any global routing rules are processed, modified, or enhanced. The retrieved rules can provide insights into further event processing 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="https://api.pagerduty.com/event_orchestrations/{id}/unrouted".format(  # noqa: UP032
            id=event_orchestration_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_unrouted_event_rules(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    event_orchestration_id: Annotated[
        str | None,
        "The unique identifier for the Event Orchestration to update.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateOrchPathUnrouted'."]:
    """Update rules for Unrouted events in Global Event Orchestration.

    This tool updates the rules for handling Unrouted events in a Global Event Orchestration. Use it when you need to modify how unrouted events are processed, without routing them to a specific service. The tool evaluates events against its rules and can modify or enhance them for further processing.

    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["UPDATEUNROUTEDEVENTRULES"],
            "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 event_orchestration_id:
        missing_params.append(("event_orchestration_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["UPDATEUNROUTEDEVENTRULES"] + "\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["UPDATEUNROUTEDEVENTRULES"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/event_orchestrations/{id}/unrouted".format(  # noqa: UP032
            id=event_orchestration_id
        ),
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEUNROUTEDEVENTRULES"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_service_orchestration(
    context: ToolContext,
    service_identifier: Annotated[
        str, "The unique identifier for the service you want to retrieve orchestration details for."
    ],
    include_models_in_response: Annotated[
        str | None, "Specify additional models like 'migrated_metadata' to include in the response."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getOrchPathService'."]:
    """Retrieve details of a service orchestration configuration.

    Accesses service orchestration details, including event rules and processing pathways within PagerDuty. Useful for understanding or modifying event escalation paths."""  # 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="https://api.pagerduty.com/event_orchestrations/services/{service_id}".format(  # noqa: UP032
            service_id=service_identifier
        ),
        method="GET",
        params=remove_none_values({"include[]": include_models_in_response}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_service_orchestration(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    service_identifier: Annotated[
        str | None,
        "The unique identifier for the service to update the orchestration rules.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateOrchPathService'."]:
    """Update a Service Orchestration with new event rules.

    This tool updates a Service Orchestration in PagerDuty by modifying its event rules. It evaluates incoming events against these rules to enhance and route them effectively. Use this tool to adjust the orchestration of a service. Requires 'services.write' scope for OAuth.

    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["UPDATESERVICEORCHESTRATION"],
            "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 service_identifier:
        missing_params.append(("service_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["UPDATESERVICEORCHESTRATION"]
                + "\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["UPDATESERVICEORCHESTRATION"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/event_orchestrations/services/{service_id}".format(  # noqa: UP032
            service_id=service_identifier
        ),
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATESERVICEORCHESTRATION"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_service_orchestration_status(
    context: ToolContext,
    service_id: Annotated[
        str, "The unique identifier for the service to check its orchestration status."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getOrchActiveStatus'."]:
    """Retrieve the active status of a Service Orchestration.

    This tool is used to get the active status of a Service Orchestration, determining if the event evaluation is against a service orchestration path or service ruleset. Applicable for managing service paths and rulesets."""  # 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="https://api.pagerduty.com/event_orchestrations/services/{service_id}/active".format(  # noqa: UP032
            service_id=service_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_service_orchestration_status(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    service_id: Annotated[
        str | None,
        "The unique identifier for the service to update the orchestration status.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateOrchActiveStatus'."]:
    """Update the active status of a service orchestration.

    Use this tool to change whether an event will be evaluated against a service orchestration path or service ruleset. Useful for managing orchestration event paths in PagerDuty.

    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["UPDATESERVICEORCHESTRATIONSTATUS"],
            "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 service_id:
        missing_params.append(("service_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["UPDATESERVICEORCHESTRATIONSTATUS"]
                + "\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["UPDATESERVICEORCHESTRATIONSTATUS"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/event_orchestrations/services/{service_id}/active".format(  # noqa: UP032
            service_id=service_id
        ),
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATESERVICEORCHESTRATIONSTATUS"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_cache_variables(
    context: ToolContext,
    event_orchestration_id: Annotated[
        str, "The unique identifier for an Event Orchestration to retrieve its cache variables."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listCacheVarOnGlobalOrch'."]:
    """Retrieve cache variables for a global event orchestration.

    This tool retrieves cache variables stored for a global event orchestration, which can be used in orchestration rules for conditions or actions. Useful for managing and evaluating event 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="https://api.pagerduty.com/event_orchestrations/{id}/cache_variables".format(  # noqa: UP032
            id=event_orchestration_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_cache_variable_event_orchestration(
    context: ToolContext,
    event_orchestration_id: Annotated[
        str, "The ID of an Event Orchestration for which the cache variable is to be created."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'createCacheVarOnGlobalOrch'."]:
    """Create a cache variable for global event orchestration rules.

    This tool creates a cache variable within a global event orchestration on PagerDuty. Cache variables are useful for storing event data that can be utilized in orchestration rules for conditions or actions. Ideal for managing and automating event-driven processes."""  # 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="https://api.pagerduty.com/event_orchestrations/{id}/cache_variables".format(  # noqa: UP032
            id=event_orchestration_id
        ),
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_cache_variable_global_event(
    context: ToolContext,
    cache_variable_identifier: Annotated[
        str, "The unique identifier for a Cache Variable in a global event orchestration."
    ],
    event_orchestration_id: Annotated[
        str, "The ID of the event orchestration to retrieve the cache variable from."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getCacheVarOnGlobalOrch'."]:
    """Retrieve a cache variable for a global event orchestration.

    This tool retrieves a cache variable associated with a global event orchestration. It is useful for accessing stored event data that can be utilized in orchestration rules. Appropriate for cases where event orchestration data is required for condition or action setups."""  # 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="https://api.pagerduty.com/event_orchestrations/{id}/cache_variables/{cache_variable_id}".format(  # noqa: UP032
            id=event_orchestration_id, cache_variable_id=cache_variable_identifier
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_cache_variable(
    context: ToolContext,
    cache_variable_id: Annotated[
        str, "The ID of the cache variable to update for the event orchestration."
    ],
    event_orchestration_id: Annotated[
        str, "The ID of the Event Orchestration to update the cache variable for."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'updateCacheVarOnGlobalOrch'."]:
    """Update a cache variable for event orchestration rules.

    This tool updates a cache variable in a Global Event Orchestration, allowing stored event data to be used in orchestration rules. Useful for modifying conditions or actions based on event data. Requires `event_orchestrations.write` OAuth scope."""  # 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="https://api.pagerduty.com/event_orchestrations/{id}/cache_variables/{cache_variable_id}".format(  # noqa: UP032
            id=event_orchestration_id, cache_variable_id=cache_variable_id
        ),
        method="PUT",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def delete_cache_variable_global_event(
    context: ToolContext,
    cache_variable_id: Annotated[str, "The unique identifier of the cache variable to delete."],
    event_orchestration_id: Annotated[
        str,
        "The unique identifier for the event orchestration from which the cache variable will be deleted.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteCacheVarOnGlobalOrch'."]:
    """Delete a cache variable for a global event orchestration.

    This tool deletes a cache variable from a specified global event orchestration. Cache variables store event data, which can be used in orchestration rules. Use this tool when you need to remove such variables from global event 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="https://api.pagerduty.com/event_orchestrations/{id}/cache_variables/{cache_variable_id}".format(  # noqa: UP032
            id=event_orchestration_id, cache_variable_id=cache_variable_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_external_data_cache_var(
    context: ToolContext,
    cache_variable_id: Annotated[
        str, "Provide the ID of the Cache Variable whose data you want to retrieve."
    ],
    event_orchestration_id: Annotated[
        str, "The unique identifier of an Event Orchestration to retrieve its cache variable data."
    ],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'getExternalDataCacheVarDataOnGlobalOrch'."
]:
    """Retrieve external data Cache Variable data from Global Orchestration.

    Use this tool to obtain the data for an external data type Cache Variable on a Global Orchestration. These variables store string, number, or boolean values, which can be used in event orchestration conditions or actions. Requires `event_orchestrations.read` OAuth scope."""  # 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="https://api.pagerduty.com/event_orchestrations/{id}/cache_variables/{cache_variable_id}/data".format(  # noqa: UP032
            id=event_orchestration_id, cache_variable_id=cache_variable_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_external_data_cache_variable(
    context: ToolContext,
    cache_variable_id: Annotated[
        str,
        "The unique identifier for a Cache Variable within the event orchestration. This ID is used to specify which cache variable's data is to be updated.",  # noqa: E501
    ],
    event_orchestration_id: Annotated[
        str, "The unique identifier for an Event Orchestration to be updated."
    ],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'updateExternalDataCacheVarDataOnGlobalOrch'."
]:
    """Update values for external data cache variables in global event orchestration.

    This tool updates the data for an external data type cache variable within a global event orchestration in PagerDuty. It's used to store string, number, or boolean values, which can be utilized in conditions or actions in event orchestration rules. Requires appropriate OAuth permissions."""  # 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="https://api.pagerduty.com/event_orchestrations/{id}/cache_variables/{cache_variable_id}/data".format(  # noqa: UP032
            id=event_orchestration_id, cache_variable_id=cache_variable_id
        ),
        method="PUT",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def delete_external_data_cache_variable(
    context: ToolContext,
    cache_variable_id: Annotated[
        str, "The ID of the cache variable to delete within the event orchestration."
    ],
    event_orchestration_id: Annotated[
        str,
        "The unique identifier for the Event Orchestration to target for cache variable deletion.",
    ],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'deleteExternalDataCacheVarDataOnGlobalOrch'."
]:
    """Deletes external data cache variable for event orchestration.

    Use this tool to delete data stored in an external data type cache variable within a global event orchestration. This action affects the cache variables used in conditions or actions in event orchestration rules. Requires appropriate OAuth permissions."""  # 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="https://api.pagerduty.com/event_orchestrations/{id}/cache_variables/{cache_variable_id}/data".format(  # noqa: UP032
            id=event_orchestration_id, cache_variable_id=cache_variable_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_cache_variables_for_service_event_orchestration(
    context: ToolContext,
    service_id: Annotated[
        str,
        "The unique identifier of the service. It specifies which service's event orchestration cache variables to list.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listCacheVarOnServiceOrch'."]:
    """Retrieve cache variables for service event orchestration.

    Use this tool to obtain a list of cache variables associated with a specific service event orchestration in PagerDuty. Cache variables store event data and are utilized in orchestration rules. This tool should be called when you need to access or manage cache variables for event orchestration."""  # 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="https://api.pagerduty.com/event_orchestrations/services/{service_id}/cache_variables".format(  # noqa: UP032
            service_id=service_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def add_cache_variable_to_service_event(
    context: ToolContext,
    service_identifier: Annotated[
        str,
        "The ID of the service for which the cache variable is being created. This should be a string representing the unique identifier of the service.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'createCacheVarOnServiceOrch'."]:
    """Create a cache variable for a service event orchestration.

    Use this tool to create a cache variable within a service event orchestration on PagerDuty. Cache variables store event data that can be used in orchestration rules for conditions or actions. Requires OAuth with `services.write` scope."""  # 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="https://api.pagerduty.com/event_orchestrations/services/{service_id}/cache_variables".format(  # noqa: UP032
            service_id=service_identifier
        ),
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_service_event_cache_variable(
    context: ToolContext,
    cache_variable_id: Annotated[str, "The unique identifier of the cache variable to retrieve."],
    service_identifier: Annotated[
        str,
        "The unique identifier of the service. Use this to specify the service whose event orchestration cache variable you want to access.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getCacheVarOnServiceOrch'."]:
    """Get a cache variable for a service event orchestration.

    Fetches stored event data from a service event orchestration cache variable, useful for conditions or actions in event orchestration rules."""  # 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="https://api.pagerduty.com/event_orchestrations/services/{service_id}/cache_variables/{cache_variable_id}".format(  # noqa: UP032
            service_id=service_identifier, cache_variable_id=cache_variable_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_service_event_cache_variable(
    context: ToolContext,
    cache_variable_id: Annotated[
        str, "The ID of the cache variable to update for the service event orchestration."
    ],
    service_identifier: Annotated[
        str,
        "The unique identifier for the service to update the cache variable on a service event orchestration.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'updateCacheVarOnServiceOrch'."]:
    """Update a cache variable for a service event orchestration.

    This tool updates a cache variable for a specific service event orchestration in PagerDuty. Cache variables store event data used in orchestration rules. Requires 'services.write' permission. Useful for modifying orchestration rules or conditions."""  # 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="https://api.pagerduty.com/event_orchestrations/services/{service_id}/cache_variables/{cache_variable_id}".format(  # noqa: UP032
            service_id=service_identifier, cache_variable_id=cache_variable_id
        ),
        method="PUT",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def delete_service_cache_variable(
    context: ToolContext,
    cache_variable_id: Annotated[
        str,
        "The unique identifier for the cache variable to be deleted in the service event orchestration.",  # noqa: E501
    ],
    service_identifier: Annotated[
        str, "The unique identifier for the service related to the event orchestration."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteCacheVarOnServiceOrch'."]:
    """Delete a cache variable for a service event orchestration.

    Use this tool to delete a cache variable associated with a service event orchestration. This operation helps manage event data by removing unnecessary or outdated cache variables connected to event orchestration rules. Ensure scoped OAuth with `services.write` is enabled."""  # 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="https://api.pagerduty.com/event_orchestrations/services/{service_id}/cache_variables/{cache_variable_id}".format(  # noqa: UP032
            service_id=service_identifier, cache_variable_id=cache_variable_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_service_event_cache_data(
    context: ToolContext,
    cache_variable_id: Annotated[
        str,
        "The ID of the Cache Variable to retrieve data for, used in service event orchestration.",
    ],
    service_identifier: Annotated[
        str, "The unique identifier for the service to retrieve the cache variable data from."
    ],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'getExternalDataCacheVarDataOnServiceOrch'."
]:
    """Retrieve external data cache variable for event orchestration.

    This tool retrieves the data of an `external_data` type Cache Variable for a specified Service Event Orchestration in PagerDuty. It is useful when you need to access stored values like strings, numbers, or booleans for use in event orchestration rules. OAuth scope `services.read` is required."""  # 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="https://api.pagerduty.com/event_orchestrations/services/{service_id}/cache_variables/{cache_variable_id}/data".format(  # noqa: UP032
            service_id=service_identifier, cache_variable_id=cache_variable_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_cache_variable_data(
    context: ToolContext,
    cache_variable_id: Annotated[
        str, "The unique identifier for the Cache Variable to be updated."
    ],
    service_identifier: Annotated[
        str, "A unique identifier for the service whose cache variable data is to be updated."
    ],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'updateExternalDataCacheVarDataOnServiceOrch'."
]:
    """Update cache variable data for service event orchestration.

    This tool updates the data for an external data type cache variable within a service event orchestration. Use it to modify string, number, or boolean values stored via a dedicated API endpoint. These values can be used in event orchestration conditions and 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="https://api.pagerduty.com/event_orchestrations/services/{service_id}/cache_variables/{cache_variable_id}/data".format(  # noqa: UP032
            service_id=service_identifier, cache_variable_id=cache_variable_id
        ),
        method="PUT",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def remove_service_cache_variable(
    context: ToolContext,
    cache_variable_id: Annotated[
        str,
        "The unique identifier for an external data cache variable to be deleted from the service event orchestration.",  # noqa: E501
    ],
    service_identifier: Annotated[
        str, "The unique identifier for the service. Required for deleting cache variable data."
    ],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'deleteExternalDataCacheVarDataOnServiceOrch'."
]:
    """Delete external data cache variable on a service orchestration.

    Deletes data for an 'external_data' type cache variable within a service event orchestration. Useful for managing values used in orchestration rules. Requires 'services.write' authorization."""  # 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="https://api.pagerduty.com/event_orchestrations/services/{service_id}/cache_variables/{cache_variable_id}/data".format(  # noqa: UP032
            service_id=service_identifier, cache_variable_id=cache_variable_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_event_orchestration_enablings(
    context: ToolContext,
    event_orchestration_id: Annotated[
        str,
        "The unique identifier for a specific Event Orchestration in PagerDuty. This is required to retrieve its feature enablement settings.",  # noqa: E501
    ],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'listEventOrchestrationFeatureEnablements'."
]:
    """Retrieve feature enablement settings for Event Orchestrations.

    This tool retrieves all feature enablement settings for a specific Event Orchestration in PagerDuty, currently focusing on AIOps enablement. It should be used to check which AIOps features are enabled for an Event Orchestration. Note: A warning will be returned if the account is not entitled to use AIOps features."""  # 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="https://api.pagerduty.com/event_orchestrations/{id}/enablements".format(  # noqa: UP032
            id=event_orchestration_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_event_orchestration_features(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    event_orchestration_id: Annotated[
        str | None,
        "The unique identifier for an Event Orchestration to update features.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    feature_enablement_identifier: Annotated[
        str | None,
        "Specifies the feature enablement identifier for a product addon. Currently, only 'aiops' is supported.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateEventOrchestrationFeatureEnablements'."
]:
    """Update features for Event Orchestration in PagerDuty.

    This tool updates the enablement settings for specific product add-ons on an Event Orchestration in PagerDuty. Currently supports only the `aiops` feature. Use this to enable or disable features contained within the addon. Note: If the account lacks entitlement for AIOps, the change will occur but with a warning.

    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["UPDATEEVENTORCHESTRATIONFEATURES"],
            "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 event_orchestration_id:
        missing_params.append(("event_orchestration_id", "path"))
    if not feature_enablement_identifier:
        missing_params.append(("feature_enablement_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["UPDATEEVENTORCHESTRATIONFEATURES"]
                + "\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["UPDATEEVENTORCHESTRATIONFEATURES"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/event_orchestrations/{id}/enablements/{feature_name}".format(  # noqa: UP032
            id=event_orchestration_id, feature_name=feature_enablement_identifier
        ),
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEEVENTORCHESTRATIONFEATURES"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_extension_schemas(
    context: ToolContext,
    include_total_in_response: Annotated[
        bool | None,
        "Set to true to populate the total field in pagination responses, providing the total count, which may affect response time.",  # noqa: E501
    ] = False,
    pagination_offset: Annotated[
        int | None,
        "The starting point for pagination in the result set, defined as the number of items to skip.",  # noqa: E501
    ] = None,
    results_per_page: Annotated[
        int | None, "Specify the number of results to display per page."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listExtensionSchemas'."]:
    """Retrieve a list of all PagerDuty extension schemas.

    This tool fetches a list of all extension schemas in PagerDuty, representing outbound integrations like Webhooks, Slack, and ServiceNow. It should be called when needing details about available extension types. OAuth scope required: `extension_schemas.read`."""  # 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="https://api.pagerduty.com/extension_schemas",
        method="GET",
        params=remove_none_values({
            "limit": results_per_page,
            "offset": pagination_offset,
            "total": include_total_in_response,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_extension_vendor_details(
    context: ToolContext,
    resource_id: Annotated[str, "The unique identifier for the extension vendor resource."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getExtensionSchema'."]:
    """Retrieve details of a specific PagerDuty extension vendor.

    Use this tool to get detailed information about a particular extension vendor in PagerDuty, such as Generic Webhook, Slack, or ServiceNow. This can help in understanding the capabilities and characteristics of a specific vendor."""  # 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="https://api.pagerduty.com/extension_schemas/{id}".format(id=resource_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_extensions(
    context: ToolContext,
    filter_by_extension_object_id: Annotated[
        str | None,
        "Filter the extensions by specifying the extension object's ID you want to include.",
    ] = None,
    filter_by_extension_vendor_id: Annotated[
        str | None, "Specify the extension vendor ID to filter extensions by vendor."
    ] = None,
    include_details: Annotated[
        str | None,
        "Specify additional details to include, such as 'extension_objects' or 'extension_schemas'.",  # noqa: E501
    ] = None,
    include_total_in_response: Annotated[
        bool | None,
        "Set to true to populate the total field in pagination responses, providing the total count of results.",  # noqa: E501
    ] = False,
    name_query_filter: Annotated[
        str | None, "Filter results to show only records whose name matches this query string."
    ] = None,
    pagination_offset: Annotated[
        int | None,
        "Offset to begin pagination search results listing. Specify an integer value to set the starting point.",  # noqa: E501
    ] = None,
    results_per_page: Annotated[
        int | None, "The number of results to return per page retrieval request."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listExtensions'."]:
    """Retrieve a list of existing extensions and their details.

    Call this tool to obtain a list of extensions, which are representations of Extension Schema objects attached to Services. Useful for managing and identifying existing integrations within the 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="https://api.pagerduty.com/extensions",
        method="GET",
        params=remove_none_values({
            "limit": results_per_page,
            "offset": pagination_offset,
            "total": include_total_in_response,
            "query": name_query_filter,
            "extension_object_id": filter_by_extension_object_id,
            "extension_schema_id": filter_by_extension_vendor_id,
            "include[]": include_details,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_service_extension(
    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 'createExtension'."]:
    """Create a new extension for a service in PagerDuty.

    This tool is used to create a new extension in PagerDuty, representing an Extension Schema object attached to a service. It should be called when you need to add or register a new extension to enhance a service's functionality. Requires scoped OAuth: `extensions.write`.

    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["CREATESERVICEEXTENSION"],
            "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["CREATESERVICEEXTENSION"] + "\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["CREATESERVICEEXTENSION"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/extensions",
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATESERVICEEXTENSION"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_extension_details(
    context: ToolContext,
    resource_id: Annotated[
        str, "The unique identifier of the extension resource to retrieve details for."
    ],
    include_additional_details: Annotated[
        str | None,
        "Specify additional details to include, such as 'extension_schemas', 'extension_objects', or 'temporarily_disabled'.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getExtension'."]:
    """Retrieve details about a specific extension on PagerDuty.

    Use this tool to obtain information about an existing extension associated with a service in PagerDuty. Useful for understanding extension configurations and their properties."""  # 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="https://api.pagerduty.com/extensions/{id}".format(id=resource_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({"include[]": include_additional_details}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def delete_extension(
    context: ToolContext,
    resource_id: Annotated[str, "The unique identifier of the extension to be deleted."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteExtension'."]:
    """Delete an existing extension in PagerDuty.

    This tool deletes an existing extension in PagerDuty, making it inaccessible from the web UI and preventing new incidents from being created for this extension."""  # 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="https://api.pagerduty.com/extensions/{id}".format(id=resource_id),  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_extension(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The ID of the extension resource you want to update.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateExtension'."]:
    """Update an existing extension in PagerDuty.

    Use this tool to update an existing extension in PagerDuty. Extensions are linked to services and require appropriate permissions. This call requires 'extensions.write' OAuth scope.

    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["UPDATEEXTENSION"],
            "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 resource_id:
        missing_params.append(("resource_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["UPDATEEXTENSION"] + "\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["UPDATEEXTENSION"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/extensions/{id}".format(id=resource_id),  # noqa: UP032
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEEXTENSION"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def enable_pagerduty_extension(
    context: ToolContext,
    resource_id: Annotated[str, "The unique ID of the PagerDuty extension to enable."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'enableExtension'."]:
    """Enable a disabled extension on PagerDuty.

    Use this tool to enable an extension on PagerDuty that is currently disabled. This is useful for reactivating an extension connected to a service without requiring additional input 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="https://api.pagerduty.com/extensions/{id}/enable".format(id=resource_id),  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_incident_workflows(
    context: ToolContext,
    filter_by_name: Annotated[
        str | None, "Filter results to show only records whose name matches the query."
    ] = None,
    include_additional_details: Annotated[
        str | None, "Specify additional details to include, such as 'steps' or 'team'."
    ] = None,
    include_total_in_pagination: Annotated[
        bool | None,
        "Set to true to populate the `total` field in pagination responses, false otherwise to optimize for speed.",  # noqa: E501
    ] = False,
    pagination_offset: Annotated[int | None, "Offset to start pagination search results."] = None,
    results_per_page: Annotated[
        int | None, "Specifies the number of results to return per page in the response."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listIncidentWorkflows'."]:
    """Retrieve all incident workflows in your PagerDuty account.

    Use this tool to list all existing Incident Workflows in your PagerDuty account, which consist of configurable steps and triggers for automated actions. Ideal for managing workflows related to incidents."""  # 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="https://api.pagerduty.com/incident_workflows",
        method="GET",
        params=remove_none_values({
            "limit": results_per_page,
            "offset": pagination_offset,
            "total": include_total_in_pagination,
            "query": filter_by_name,
            "include[]": include_additional_details,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_incident_workflow(
    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 'postIncidentWorkflow'."]:
    """Create a new incident workflow to automate actions.

    This tool creates a new incident workflow, consisting of steps and triggers to execute automated actions for an incident.

    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["CREATEINCIDENTWORKFLOW"],
            "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["CREATEINCIDENTWORKFLOW"] + "\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["CREATEINCIDENTWORKFLOW"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/incident_workflows",
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATEINCIDENTWORKFLOW"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_incident_workflow(
    context: ToolContext,
    incident_workflow_id: Annotated[str, "The ID of the Incident Workflow to be retrieved."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getIncidentWorkflow'."]:
    """Retrieve an existing Incident Workflow.

    This tool retrieves the details of an existing Incident Workflow, which consists of configurable Steps and associated Triggers for automated Actions related to an Incident. Use this to understand or manage incident responses 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="https://api.pagerduty.com/incident_workflows/{id}".format(id=incident_workflow_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def delete_incident_workflow(
    context: ToolContext,
    resource_id: Annotated[str, "The unique identifier of the incident workflow to be deleted."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteIncidentWorkflow'."]:
    """Deletes an existing incident workflow in PagerDuty.

    Use this tool to delete an incident workflow from PagerDuty. An incident workflow is a sequence of steps and triggers for automating actions for a specific incident. This tool requires scoped OAuth with `incident_workflows.write`."""  # 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="https://api.pagerduty.com/incident_workflows/{id}".format(id=resource_id),  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_incident_workflow(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    incident_workflow_id: Annotated[
        str | None,
        "The unique ID of the incident workflow to update.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'putIncidentWorkflow'."]:
    """Updates an existing incident workflow in PagerDuty.

    Use this tool to update an incident workflow, which includes configurable steps and triggers for executing automated actions on an incident. Requires appropriate OAuth permissions.

    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["UPDATEINCIDENTWORKFLOW"],
            "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 incident_workflow_id:
        missing_params.append(("incident_workflow_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["UPDATEINCIDENTWORKFLOW"] + "\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["UPDATEINCIDENTWORKFLOW"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/incident_workflows/{id}".format(id=incident_workflow_id),  # noqa: UP032
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEINCIDENTWORKFLOW"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def start_incident_workflow(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The ID of the resource to start the incident workflow for.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'createIncidentWorkflowInstance'."]:
    """Start an instance of an incident workflow for automation.

    This tool initiates an incident workflow, which consists of configurable steps and triggers, to execute automated actions related to an incident. Use it to automate processes in response to specific incident events.

    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["STARTINCIDENTWORKFLOW"],
            "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 resource_id:
        missing_params.append(("resource_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["STARTINCIDENTWORKFLOW"] + "\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["STARTINCIDENTWORKFLOW"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/incident_workflows/{id}/instances".format(id=resource_id),  # noqa: UP032
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["STARTINCIDENTWORKFLOW"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_incident_workflow_actions(
    context: ToolContext,
    filter_by_keyword: Annotated[
        str | None,
        "Show actions tagged with the specified keyword. Provide a specific keyword to filter results.",  # noqa: E501
    ] = None,
    max_results_limit: Annotated[
        int | None,
        "The maximum number of incident workflow actions to return in a single request. This value is the lesser of the specified limit or the API's maximum request size.",  # noqa: E501
    ] = None,
    pagination_cursor: Annotated[
        str | None,
        "Optional parameter to fetch the next set of results. Use 'next_cursor' from the previous response. Starts at the beginning if not provided.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listIncidentWorkflowActions'."]:
    """Retrieve a list of incident workflow actions.

    Use this tool to get a list of available incident workflow actions from PagerDuty. This is useful for managing and understanding workflows associated with incidents. Requires `incident_workflows.read` scope."""  # 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="https://api.pagerduty.com/incident_workflows/actions",
        method="GET",
        params=remove_none_values({
            "limit": max_results_limit,
            "cursor": pagination_cursor,
            "keyword": filter_by_keyword,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_incident_workflow_action(
    context: ToolContext,
    resource_id: Annotated[str, "The unique ID of the incident workflow action to retrieve."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getIncidentWorkflowAction'."]:
    """Retrieve details of an incident workflow action.

    Use this tool to obtain information about a specific incident workflow action in PagerDuty. Ideal for scenarios where you need to understand or display workflow details based on an 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="https://api.pagerduty.com/incident_workflows/actions/{id}".format(id=resource_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_incident_workflow_triggers(
    context: ToolContext,
    filter_by_service_id: Annotated[
        str | None,
        "Show triggers for incidents in the given service. Cannot be used with `incident_id`.",
    ] = None,
    filter_by_trigger_type: Annotated[
        str | None,
        "Specify the type of triggers to show, such as 'manual', 'conditional', or 'incident_type'.",  # noqa: E501
    ] = None,
    filter_for_disabled_triggers: Annotated[
        bool | None,
        "Set to true to filter for disabled triggers, false for enabled. This parameter is deprecated.",  # noqa: E501
    ] = None,
    incident_id_filter: Annotated[
        str | None,
        "Show triggers for the service of the specified incident. Cannot be used with `service_id`.",  # noqa: E501
    ] = None,
    maximum_results: Annotated[
        int | None,
        "Specify the maximum number of triggers to return. This limits the size of the response, constrained by the API's maximum request size.",  # noqa: E501
    ] = None,
    pagination_cursor: Annotated[
        str | None,
        "Optional parameter to request the next set of results, usually from the `next_cursor` field of a previous request. Starts at the beginning if not provided.",  # noqa: E501
    ] = None,
    sort_triggers_by: Annotated[
        str | None,
        "Specify the property to sort triggers, such as 'workflow_id asc' or 'workflow_name desc'.",
    ] = None,
    workflow_id_filter: Annotated[
        str | None,
        "If provided, only show triggers configured to start the specified workflow, useful for listing services linked to a workflow.",  # noqa: E501
    ] = None,
    workflow_name_contains: Annotated[
        str | None, "Filter triggers by workflow names containing this value."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listIncidentWorkflowTriggers'."]:
    """Retrieve a list of existing incident workflow triggers.

    Use this tool to obtain information about all current incident workflow triggers. It requires `incident_workflows.read` OAuth scope to access the 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="https://api.pagerduty.com/incident_workflows/triggers",
        method="GET",
        params=remove_none_values({
            "workflow_id": workflow_id_filter,
            "incident_id": incident_id_filter,
            "service_id": filter_by_service_id,
            "trigger_type": filter_by_trigger_type,
            "workflow_name_contains": workflow_name_contains,
            "is_disabled": filter_for_disabled_triggers,
            "sort_by": sort_triggers_by,
            "limit": maximum_results,
            "cursor": pagination_cursor,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_incident_workflow_trigger(
    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 'createIncidentWorkflowTrigger'."]:
    """Initiate a new PagerDuty incident workflow trigger.

    Use this tool to start a new incident workflow trigger in PagerDuty. It requires appropriate OAuth permissions (`incident_workflows.write`).

    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["CREATEINCIDENTWORKFLOWTRIGGER"],
            "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["CREATEINCIDENTWORKFLOWTRIGGER"]
                + "\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["CREATEINCIDENTWORKFLOWTRIGGER"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/incident_workflows/triggers",
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATEINCIDENTWORKFLOWTRIGGER"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_incident_workflow_trigger(
    context: ToolContext,
    incident_workflow_trigger_id: Annotated[
        str, "The unique ID of the Incident Workflow Trigger to be retrieved."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getIncidentWorkflowTrigger'."]:
    """Retrieve an existing Incident Workflows Trigger.

    Call this tool to get details about a specific Incident Workflows Trigger using its ID. Useful for obtaining information on workflow triggers in incident management systems."""  # 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="https://api.pagerduty.com/incident_workflows/triggers/{id}".format(  # noqa: UP032
            id=incident_workflow_trigger_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_incident_workflow_trigger(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The ID of the incident workflow trigger to be updated in PagerDuty.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateIncidentWorkflowTrigger'."]:
    """Update an existing incident workflow trigger.

    Use this tool to update details of an existing incident workflow trigger in PagerDuty. This should be called when modifications to workflow triggers are needed for incident management. Scoped OAuth with 'incident_workflows.write' permission is required.

    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["UPDATEINCIDENTWORKFLOWTRIGGER"],
            "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 resource_id:
        missing_params.append(("resource_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["UPDATEINCIDENTWORKFLOWTRIGGER"]
                + "\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["UPDATEINCIDENTWORKFLOWTRIGGER"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/incident_workflows/triggers/{id}".format(id=resource_id),  # noqa: UP032
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEINCIDENTWORKFLOWTRIGGER"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def delete_incident_workflow_trigger(
    context: ToolContext,
    incident_workflow_trigger_id: Annotated[
        str, "The unique identifier of the incident workflow trigger to delete."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteIncidentWorkflowTrigger'."]:
    """Deletes an existing incident workflow trigger using its ID.

    Use this tool to delete an existing incident workflow trigger by specifying its ID. Requires authorized access for 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="https://api.pagerduty.com/incident_workflows/triggers/{id}".format(  # noqa: UP032
            id=incident_workflow_trigger_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def associate_service_to_incident_workflow_trigger(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The unique identifier of the resource to associate with the incident workflow trigger.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'associateServiceToIncidentWorkflowTrigger'."
]:
    """Associate a service with an existing incident workflow trigger.

    This tool associates a specific service with an existing incident workflow trigger in PagerDuty. It requires OAuth permission `incident_workflows.write`. Use this tool when you need to link a service to a workflow trigger for better incident management.

    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[
                "ASSOCIATESERVICETOINCIDENTWORKFLOWTRIGGER"
            ],
            "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 resource_id:
        missing_params.append(("resource_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["ASSOCIATESERVICETOINCIDENTWORKFLOWTRIGGER"]
                + "\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["ASSOCIATESERVICETOINCIDENTWORKFLOWTRIGGER"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/incident_workflows/triggers/{id}/services".format(  # noqa: UP032
            id=resource_id
        ),
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["ASSOCIATESERVICETOINCIDENTWORKFLOWTRIGGER"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def remove_service_from_incident_trigger(
    context: ToolContext,
    service_identifier: Annotated[
        str, "The unique identifier for the service to remove from the incident workflow trigger."
    ],
    trigger_identifier: Annotated[
        str,
        "The unique identifier for the incident workflow trigger from which the service will be removed.",  # noqa: E501
    ],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'deleteServiceFromIncidentWorkflowTrigger'."
]:
    """Remove a service from an incident workflow trigger.

    Use this tool to remove an existing service from a specific incident workflow trigger in PagerDuty. This action requires scoped OAuth with `incident_workflows.write` permission."""  # 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="https://api.pagerduty.com/incident_workflows/triggers/{trigger_id}/services/{service_id}".format(  # noqa: UP032
            trigger_id=trigger_identifier, service_id=service_identifier
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_existing_incidents(
    context: ToolContext,
    additional_details_to_include: Annotated[
        str | None,
        "Array of additional details to include in the incident list, such as 'acknowledgers', 'agents', 'assignees', etc.",  # noqa: E501
    ] = None,
    assigned_user_ids: Annotated[
        list[str] | None,
        "Return incidents currently assigned to specific users by providing their user IDs. Only incidents with statuses 'triggered' or 'acknowledged' are returned. Resolved incidents are not included.",  # noqa: E501
    ] = None,
    end_date_range: Annotated[
        str | None,
        "The end date of the range for searching incidents. Maximum range is 6 months; default is 1 month.",  # noqa: E501
    ] = None,
    filter_by_team_ids: Annotated[
        list[str] | None, "Array of team IDs to filter incidents. Requires `teams` ability."
    ] = None,
    ignore_since_until_date_range: Annotated[
        str | None,
        "Set to 'all' to ignore the 'since' and 'until' parameters, extending the search to all dates.",  # noqa: E501
    ] = None,
    incident_deduplication_key: Annotated[
        str | None,
        "A unique key to identify and retrieve specific incidents. Useful for querying by matching alert keys.",  # noqa: E501
    ] = None,
    incident_statuses: Annotated[
        str | None,
        "Specify the list of incident statuses to filter by, such as 'triggered', 'acknowledged', or 'resolved'.",  # noqa: E501
    ] = None,
    incident_urgencies: Annotated[
        str | None,
        "Array of incident urgencies to filter results by. Valid values are 'high' or 'low'. Defaults to all urgencies.",  # noqa: E501
    ] = None,
    include_total_in_response: Annotated[
        bool | None,
        "Set to true to include the total number of incidents in the response, which may reduce response speed.",  # noqa: E501
    ] = False,
    pagination_offset: Annotated[
        int | None,
        "Offset to start pagination of the incident search results. Specify the number of entries to skip before starting to collect the result set.",  # noqa: E501
    ] = None,
    render_time_zone: Annotated[
        str | None,
        "Specify the time zone for rendering results. Defaults to the account time zone.",
    ] = None,
    results_per_page: Annotated[
        int | None, "The number of results per page. Specify up to a maximum of 100."
    ] = None,
    service_ids: Annotated[
        list[str] | None,
        "A list of service IDs to filter incidents associated with specific services.",
    ] = None,
    sort_incidents_by: Annotated[
        list[str] | None,
        "Specify fields and directions for sorting incidents, e.g., 'created_at:asc'. Separate fields with a comma.",  # noqa: E501
    ] = None,
    start_date_range: Annotated[
        str | None,
        "The start date to begin searching for incidents, within a 6-month range. Defaults to 1 month if not provided.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listIncidents'."]:
    """Retrieve a list of existing incidents.

    Fetches a list of incidents that represent problems needing resolution. Useful for monitoring and addressing ongoing issues."""  # 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="https://api.pagerduty.com/incidents",
        method="GET",
        params=remove_none_values({
            "limit": results_per_page,
            "offset": pagination_offset,
            "total": include_total_in_response,
            "date_range": ignore_since_until_date_range,
            "incident_key": incident_deduplication_key,
            "service_ids[]": service_ids,
            "team_ids[]": filter_by_team_ids,
            "user_ids[]": assigned_user_ids,
            "urgencies[]": incident_urgencies,
            "time_zone": render_time_zone,
            "statuses[]": incident_statuses,
            "sort_by": sort_incidents_by,
            "include[]": additional_details_to_include,
            "since": start_date_range,
            "until": end_date_range,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_incidents(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    user_email: Annotated[
        str | None,
        "The email address of a valid user associated with the account making the request.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    results_per_page: Annotated[
        int | None,
        "Specifies the maximum number of incident results to return per page.  Only used when mode is 'execute'.",  # noqa: E501
    ] = None,
    pagination_start_offset: Annotated[
        int | None,
        "Offset from where to start paginated search results. This is used to navigate search results effectively.  Only used when mode is 'execute'.",  # noqa: E501
    ] = None,
    include_total_in_pagination: Annotated[
        bool | None,
        "Set to true to populate the 'total' field in pagination responses. Otherwise, it remains null for faster response times.  Only used when mode is 'execute'.",  # noqa: E501
    ] = None,
    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 'updateIncidents'."]:
    """Manage the status of multiple incidents.

    Use this tool to acknowledge, resolve, escalate, or reassign up to 250 incidents simultaneously. It is useful for addressing and managing problems that need immediate attention. Ensure to stay within the rate limits and have the required 'incidents.write' OAuth permission.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires 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 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["UPDATEINCIDENTS"],
            "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 query parameters. "
                "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["UPDATEINCIDENTS"] + "\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["UPDATEINCIDENTS"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/incidents",
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEINCIDENTS"],
        params=remove_none_values({
            "limit": results_per_page,
            "offset": pagination_start_offset,
            "total": include_total_in_pagination,
        }),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "From": user_email,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_incident(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    user_email: Annotated[
        str | None,
        "The email address of a valid user associated with the account making the request.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'createIncident'."]:
    """Create an incident in PagerDuty.

    Use this tool to create an incident in PagerDuty when there is a problem or issue that needs attention and resolution.

    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["CREATEINCIDENT"],
            "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["CREATEINCIDENT"] + "\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["CREATEINCIDENT"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/incidents",
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATEINCIDENT"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "From": user_email,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_incident_details(
    context: ToolContext,
    incident_id: Annotated[
        str,
        "The unique identifier for the specific incident. Include either the incident ID or number to retrieve details.",  # noqa: E501
    ],
    include_details: Annotated[
        str | None,
        "List of additional incident details to include, such as 'acknowledgers', 'agents', 'assignees', etc.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getIncident'."]:
    """Retrieve detailed information about a PagerDuty incident.

    Use this tool to get comprehensive details of a specific incident by providing its ID or number, helping to address and resolve issues 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="https://api.pagerduty.com/incidents/{id}".format(id=incident_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({"include[]": include_details}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def manage_incident_status(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    incident_id: Annotated[
        str | None,
        "The unique identifier of the incident to be managed.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    user_email_for_request: Annotated[
        str | None,
        "Email address of a valid user associated with the account making the request.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateIncident'."]:
    """Manage PagerDuty incident status and assignments.

    This tool allows you to acknowledge, resolve, escalate, or reassign a PagerDuty incident. It should be used when you need to update the status or assignment of an existing incident. OAuth scope 'incidents.write' is required.

    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["MANAGEINCIDENTSTATUS"],
            "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 incident_id:
        missing_params.append(("incident_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["MANAGEINCIDENTSTATUS"] + "\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["MANAGEINCIDENTSTATUS"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/incidents/{id}".format(id=incident_id),  # noqa: UP032
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["MANAGEINCIDENTSTATUS"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "From": user_email_for_request,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_incident_alerts(
    context: ToolContext,
    incident_id: Annotated[str, "The unique identifier of the incident to retrieve alerts for."],
    alert_deduplication_key: Annotated[
        str | None, "The unique key used for alert de-duplication."
    ] = None,
    filter_by_statuses: Annotated[
        str | None, "Filter alerts by specific statuses, such as 'triggered' or 'resolved'."
    ] = None,
    include_additional_details: Annotated[
        str | None,
        "Specify additional details to include, such as services, first_trigger_log_entries, or incidents.",  # noqa: E501
    ] = None,
    include_pagination_total: Annotated[
        bool | None,
        "Set to `true` to include the total count of results in pagination responses for faster response times. Set to `false` for the default behavior of `null`, which is faster.",  # noqa: E501
    ] = False,
    results_per_page: Annotated[
        int | None, "Specify the number of alert results per page for pagination."
    ] = None,
    sort_incident_alerts_by: Annotated[
        str | None,
        "Specify the field and order for sorting alerts (created_at or resolved_at, with ascending or descending options).",  # noqa: E501
    ] = None,
    start_pagination_offset: Annotated[
        int | None,
        "Offset for starting the pagination in search results. Use for navigating through paginated data.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listIncidentAlerts'."]:
    """Retrieve alerts for a specified incident.

    Use this tool to list all alerts associated with a specific incident, which represents an issue that requires resolution. Useful for tracking and managing problems 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="https://api.pagerduty.com/incidents/{id}/alerts".format(id=incident_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({
            "limit": results_per_page,
            "offset": start_pagination_offset,
            "total": include_pagination_total,
            "alert_key": alert_deduplication_key,
            "statuses[]": filter_by_statuses,
            "sort_by": sort_incident_alerts_by,
            "include[]": include_additional_details,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def resolve_or_reassociate_incident_alerts(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    incident_resource_id: Annotated[
        str | None,
        "The unique identifier for the incident resource to be resolved or reassociated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    user_email: Annotated[
        str | None,
        "The email address of a valid user associated with the account making the request.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    results_per_page: Annotated[
        int | None,
        "Specify the number of results to be returned per page. Must be an integer.  Only used when mode is 'execute'.",  # noqa: E501
    ] = None,
    pagination_offset: Annotated[
        int | None,
        "Offset for pagination to specify where search results should begin.  Only used when mode is 'execute'.",  # noqa: E501
    ] = None,
    populate_total: Annotated[
        bool | None,
        "Set to `true` to populate the `total` field in pagination responses, otherwise it remains `null` for faster response.  Only used when mode is 'execute'.",  # noqa: E501
    ] = None,
    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 'updateIncidentAlerts'."]:
    """Resolve or reassign alerts to incidents.

    Use this tool to resolve multiple alerts or associate them with different incidents in PagerDuty. Only up to 250 alerts can be updated at a time. Ideal for managing alerts detected by monitoring systems that need resolution or reassessment.

    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["RESOLVEORREASSOCIATEINCIDENTALERTS"],
            "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 incident_resource_id:
        missing_params.append(("incident_resource_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["RESOLVEORREASSOCIATEINCIDENTALERTS"]
                + "\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["RESOLVEORREASSOCIATEINCIDENTALERTS"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/incidents/{id}/alerts".format(id=incident_resource_id),  # noqa: UP032
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["RESOLVEORREASSOCIATEINCIDENTALERTS"],
        params=remove_none_values({
            "limit": results_per_page,
            "offset": pagination_offset,
            "total": populate_total,
        }),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "From": user_email,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_incident_alert_details(
    context: ToolContext,
    alert_identifier: Annotated[str, "The unique identifier of the alert to retrieve details for."],
    resource_id: Annotated[
        str,
        "The unique identifier for the resource. This ID is used to fetch specific alert details in PagerDuty.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getIncidentAlert'."]:
    """Retrieve detailed information about a specific alert.

    This tool provides detailed information about an alert using its alert ID. It is used when there is a need to know more about a particular problem or issue represented by an alert in PagerDuty."""  # 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="https://api.pagerduty.com/incidents/{id}/alerts/{alert_id}".format(  # noqa: UP032
            id=resource_id, alert_id=alert_identifier
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def resolve_or_update_incident_alert(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The unique identifier for the resource you want to update or resolve.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    alert_id: Annotated[
        str | None,
        "The ID of the alert to resolve or update its parent incident.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    user_email_address: Annotated[
        str | None,
        "The email address of a valid user associated with the account making the request. Ensure it is linked to the account with necessary permissions.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateIncidentAlert'."]:
    """Resolve an alert or update its associated incident.

    Use this tool to resolve a specific alert or associate it with a different parent incident in PagerDuty. This is useful when managing incidents that require updates or resolution. Ensure you have `incidents.write` OAuth permissions before calling this tool.

    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["RESOLVEORUPDATEINCIDENTALERT"],
            "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 resource_id:
        missing_params.append(("resource_id", "path"))
    if not alert_id:
        missing_params.append(("alert_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["RESOLVEORUPDATEINCIDENTALERT"]
                + "\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["RESOLVEORUPDATEINCIDENTALERT"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/incidents/{id}/alerts/{alert_id}".format(  # noqa: UP032
            id=resource_id, alert_id=alert_id
        ),
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["RESOLVEORUPDATEINCIDENTALERT"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "From": user_email_address,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_incident_service_impact(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The unique identifier for the incident resource to update impact.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    business_service_id: Annotated[
        str | None,
        "The ID of the specific business service affected by the incident.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'putIncidentManualBusinessServiceAssociation'."
]:
    """Update the impact of an incident on a business service.

    Use this tool to change the impact level of a specific incident on a specified business service. Useful for managing and communicating the effects of incidents within an organization. Requires appropriate OAuth permissions.

    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["UPDATEINCIDENTSERVICEIMPACT"],
            "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 resource_id:
        missing_params.append(("resource_id", "path"))
    if not business_service_id:
        missing_params.append(("business_service_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["UPDATEINCIDENTSERVICEIMPACT"]
                + "\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["UPDATEINCIDENTSERVICEIMPACT"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/incidents/{id}/business_services/{business_service_id}/impacts".format(  # noqa: UP032
            id=resource_id, business_service_id=business_service_id
        ),
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEINCIDENTSERVICEIMPACT"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_impacted_business_services(
    context: ToolContext,
    incident_id: Annotated[
        str, "The ID of the incident to retrieve impacted business services for."
    ],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'getIncidentImpactedBusinessServices'."
]:
    """Retrieve business services impacted by an incident.

    This tool retrieves a list of business services that are being impacted by a specified incident in PagerDuty. It should be called when you need to understand which business services are affected by a particular incident using the incident 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="https://api.pagerduty.com/incidents/{id}/business_services/impacts".format(  # noqa: UP032
            id=incident_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_custom_field_values(
    context: ToolContext,
    incident_id: Annotated[
        str, "The unique identifier for the incident whose custom field values are being requested."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getIncidentFieldValues'."]:
    """Retrieve custom field values for a specific incident.

    This tool is used to obtain custom field values for a given incident on PagerDuty. It should be called when you need detailed field information about a specific incident 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="https://api.pagerduty.com/incidents/{id}/custom_fields/values".format(id=incident_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()
            )
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_incident_custom_fields(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    incident_id: Annotated[
        str | None,
        "The ID of the incident to update custom field values.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'setIncidentFieldValues'."]:
    """Update custom field values for a specific incident.

    This tool updates custom field values for a given incident in PagerDuty. Requires 'incidents.write' OAuth scope.

    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["UPDATEINCIDENTCUSTOMFIELDS"],
            "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 incident_id:
        missing_params.append(("incident_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["UPDATEINCIDENTCUSTOMFIELDS"]
                + "\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["UPDATEINCIDENTCUSTOMFIELDS"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/incidents/{id}/custom_fields/values".format(id=incident_id),  # noqa: UP032
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEINCIDENTCUSTOMFIELDS"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_incident_log_entries(
    context: ToolContext,
    incident_id: Annotated[
        str, "The unique identifier for the incident to retrieve log entries for."
    ],
    additional_models_to_include: Annotated[
        str | None,
        "Array of additional models to include in the response, such as 'incidents', 'services', 'channels', or 'teams'.",  # noqa: E501
    ] = None,
    end_date: Annotated[
        str | None, "Specify the end date for the log entry search range. Format as 'YYYY-MM-DD'."
    ] = None,
    include_total_in_response: Annotated[
        bool | None,
        "Set to true to populate the total field in pagination responses for more detailed information. Defaults to null for faster responses.",  # noqa: E501
    ] = False,
    pagination_start_offset: Annotated[
        int | None,
        "Specifies the starting point for pagination to search results. Use an integer value.",
    ] = None,
    results_per_page: Annotated[
        int | None, "Specify the number of results to display per page."
    ] = None,
    results_time_zone: Annotated[
        str | None, "Time zone for rendering the results, defaults to the account time zone."
    ] = None,
    return_important_changes_only: Annotated[
        bool | None,
        "If `true`, returns a subset of log entries showing only the most important changes to the incident.",  # noqa: E501
    ] = False,
    start_date: Annotated[
        str | None,
        "The start date for the range to search log entries. Expected format: YYYY-MM-DDTHH:MM:SSZ.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listIncidentLogEntries'."]:
    """Retrieve log entries for a specific incident.

    Use this tool to obtain a list of log entries related to a specific incident, which represents a problem that needs resolution. This tool should be called when you need detailed records of events concerning an incident."""  # 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="https://api.pagerduty.com/incidents/{id}/log_entries".format(id=incident_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({
            "limit": results_per_page,
            "offset": pagination_start_offset,
            "total": include_total_in_response,
            "time_zone": results_time_zone,
            "since": start_date,
            "until": end_date,
            "is_overview": return_important_changes_only,
            "include[]": additional_models_to_include,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def merge_incidents(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The ID of the target incident for merging source incidents.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    user_email_address: Annotated[
        str | None,
        "The email address of a valid user associated with the account making the request.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'mergeIncidents'."]:
    """Merge source incidents into a target incident.

    This tool merges a list of source incidents into a specified target incident. The target incident will include alerts from the source incidents, and the source incidents will be resolved. Only incidents with alerts or those manually created in the UI can be merged. Ensure the target incident remains open and does not exceed 1000 alerts after merging.

    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["MERGEINCIDENTS"],
            "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 resource_id:
        missing_params.append(("resource_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["MERGEINCIDENTS"] + "\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["MERGEINCIDENTS"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/incidents/{id}/merge".format(id=resource_id),  # noqa: UP032
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["MERGEINCIDENTS"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "From": user_email_address,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_incident_notes(
    context: ToolContext,
    incident_id: Annotated[
        str, "The unique identifier for the incident whose notes you want to retrieve."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listIncidentNotes'."]:
    """List notes for a specific incident.

    Use this tool to retrieve all existing notes related to a specific incident, which represents a problem or issue needing resolution."""  # 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="https://api.pagerduty.com/incidents/{id}/notes".format(id=incident_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def add_incident_note(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    incident_id: Annotated[
        str | None,
        "The unique identifier of the incident to which the note will be added.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    user_email_address: Annotated[
        str | None,
        "The email address of a valid user associated with the account making the request. This must be an email registered with the PagerDuty account.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'createIncidentNote'."]:
    """Add a new note to a specific incident.

    Use this tool to attach a note to an existing incident when documenting updates or additional information is necessary. Ideal for tracking the progress of resolving an issue.

    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["ADDINCIDENTNOTE"],
            "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 incident_id:
        missing_params.append(("incident_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["ADDINCIDENTNOTE"] + "\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["ADDINCIDENTNOTE"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/incidents/{id}/notes".format(id=incident_id),  # noqa: UP032
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["ADDINCIDENTNOTE"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "From": user_email_address,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_outlier_incident_info(
    context: ToolContext,
    incident_resource_id: Annotated[
        str, "The unique identifier for the incident resource you want details about."
    ],
    include_additional_incident_details: Annotated[
        str | None, "Include additional attributes for related incidents, specified as strings."
    ] = None,
    start_date_range: Annotated[
        str | None, "The start date for the search range in YYYY-MM-DD format."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getOutlierIncident'."]:
    """Retrieve information about an outlier incident for a service.

    Use this tool to get detailed information about an outlier incident associated with a specified incident on its service. Requires appropriate OAuth scope."""  # 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="https://api.pagerduty.com/incidents/{id}/outlier_incident".format(  # noqa: UP032
            id=incident_resource_id
        ),
        method="GET",
        params=remove_none_values({
            "since": start_date_range,
            "additional_details[]": include_additional_incident_details,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def retrieve_past_incidents(
    context: ToolContext,
    incident_id: Annotated[
        str,
        "The unique identifier of the incident. Used to fetch past incidents with similar metadata.",  # noqa: E501
    ],
    include_total_past_incidents: Annotated[
        bool | None,
        "Set to true to include the total number of past incidents in the response. This may increase response time.",  # noqa: E501
    ] = False,
    results_limit: Annotated[
        int | None, "Specifies the maximum number of past incidents to return."
    ] = 5,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getPastIncidents'."]:
    """Retrieve past incidents with similar metadata.

    Fetches incidents from the past 6 months that share similar metadata and were generated on the same service as a given incident. Available with Event Intelligence or Digital Operations plans only."""  # 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="https://api.pagerduty.com/incidents/{id}/past_incidents".format(id=incident_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({"limit": results_limit, "total": include_total_past_incidents}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_incident_related_change_events(
    context: ToolContext,
    incident_id: Annotated[
        str,
        "The unique identifier of the incident for which related change events are to be listed.",
    ],
    results_per_page_limit: Annotated[
        int | None,
        "The maximum number of change events to return per page for a specific incident.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listIncidentRelatedChangeEvents'."]:
    """Retrieve change events related to a specific incident.

    This tool retrieves a list of change events related to a specific incident, including the reasons for their correlation. It is useful during incident triage to understand recent changes such as deployments or configuration updates that might be relevant to the incident. This feature helps incident responders by providing insights based on time, related service, or machine learning intelligence."""  # 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="https://api.pagerduty.com/incidents/{id}/related_change_events".format(id=incident_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({"limit": results_per_page_limit}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_related_incidents(
    context: ToolContext,
    resource_id: Annotated[
        str, "The unique identifier of the resource to retrieve related incidents for."
    ],
    additional_attributes: Annotated[
        str | None,
        "Array of additional attributes to include for each related incident. Use 'incident' as the value.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getRelatedIncidents'."]:
    """Retrieve recent related incidents impacting services.

    Use this tool to get the 20 most recent related incidents that affect other responders and services. This feature is part of PagerDuty's Event Intelligence package or Digital Operations plan."""  # 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="https://api.pagerduty.com/incidents/{id}/related_incidents".format(id=resource_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({"additional_details[]": additional_attributes}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_incident_responder_request(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    incident_id: Annotated[
        str | None,
        "The unique identifier for the incident requiring a responder request.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    user_email: Annotated[
        str | None,
        "The email address of a valid user associated with the account making the request.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'createIncidentResponderRequest'."]:
    """Send a responder request for a specified incident.

    This tool allows you to send a new responder request for a specific incident that needs attention and resolution. It should be called whenever additional assistance is required to address an ongoing issue. Proper OAuth scope is required.

    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["CREATEINCIDENTRESPONDERREQUEST"],
            "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 incident_id:
        missing_params.append(("incident_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["CREATEINCIDENTRESPONDERREQUEST"]
                + "\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["CREATEINCIDENTRESPONDERREQUEST"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/incidents/{id}/responder_requests".format(id=incident_id),  # noqa: UP032
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATEINCIDENTRESPONDERREQUEST"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "From": user_email,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def snooze_incident(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    incident_id: Annotated[
        str | None,
        "The unique ID of the incident to snooze.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    user_email: Annotated[
        str | None,
        "The email address of a valid user associated with the account making the request.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'createIncidentSnooze'."]:
    """Temporarily suspend alerts for an incident.

    Use this tool to pause notifications for a specific incident, allowing you to manage alerts more effectively. Ideal for situations where immediate attention isn't required.

    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["SNOOZEINCIDENT"],
            "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 incident_id:
        missing_params.append(("incident_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["SNOOZEINCIDENT"] + "\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["SNOOZEINCIDENT"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/incidents/{id}/snooze".format(id=incident_id),  # noqa: UP032
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["SNOOZEINCIDENT"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "From": user_email,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_incident_status(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    incident_id: Annotated[
        str | None,
        "The ID of the incident to update. This is required to specify which incident the status update is for.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    requestor_email: Annotated[
        str | None,
        "The email address of a valid user making the request in PagerDuty.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'createIncidentStatusUpdate'."]:
    """Create a status update for a specific incident.

    Use this tool to update the status of a specific incident in PagerDuty. It allows for optional customization of the email notification through the `subject` and `html_message` properties.

    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["UPDATEINCIDENTSTATUS"],
            "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 incident_id:
        missing_params.append(("incident_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["UPDATEINCIDENTSTATUS"] + "\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["UPDATEINCIDENTSTATUS"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/incidents/{id}/status_updates".format(id=incident_id),  # noqa: UP032
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEINCIDENTSTATUS"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "From": requestor_email,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_incident_notification_subscribers(
    context: ToolContext,
    incident_id: Annotated[str, "The unique identifier of the incident resource."],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'getIncidentNotificationSubscribers'."
]:
    """Retrieve a list of notification subscribers for an incident.

    This tool retrieves the list of users subscribed to receive notifications for a specific incident. It should be called when you need to know who is subscribed to an incident's updates. Note: Users must be added through another endpoint to appear here. Requires appropriate OAuth permissions."""  # 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="https://api.pagerduty.com/incidents/{id}/status_updates/subscribers".format(  # noqa: UP032
            id=incident_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def subscribe_incident_notifications(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The ID of the resource to subscribe entities for notification updates.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'createIncidentNotificationSubscribers'."
]:
    """Subscribe entities to incident status update notifications.

    This tool subscribes specified entities to receive notifications about updates to an incident's status. It requires the `subscribers.write` OAuth scope.

    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["SUBSCRIBEINCIDENTNOTIFICATIONS"],
            "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 resource_id:
        missing_params.append(("resource_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["SUBSCRIBEINCIDENTNOTIFICATIONS"]
                + "\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["SUBSCRIBEINCIDENTNOTIFICATIONS"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/incidents/{id}/status_updates/subscribers".format(  # noqa: UP032
            id=resource_id
        ),
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["SUBSCRIBEINCIDENTNOTIFICATIONS"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def unsubscribe_incident_notification(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The unique identifier for the incident resource to unsubscribe from notifications.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'removeIncidentNotificationSubscribers'."
]:
    """Unsubscribe users from incident status update notifications.

    Removes specified subscribers from receiving status update notifications for a particular incident. Useful for managing notification preferences in incident response scenarios.

    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["UNSUBSCRIBEINCIDENTNOTIFICATION"],
            "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 resource_id:
        missing_params.append(("resource_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["UNSUBSCRIBEINCIDENTNOTIFICATION"]
                + "\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["UNSUBSCRIBEINCIDENTNOTIFICATION"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/incidents/{id}/status_updates/unsubscribe".format(  # noqa: UP032
            id=resource_id
        ),
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UNSUBSCRIBEINCIDENTNOTIFICATION"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_incident_types(
    context: ToolContext,
    incident_type_filter: Annotated[
        str | None,
        "Filter incident types by their enabled state. Options: 'enabled', 'disabled', 'all'.",
    ] = "enabled",
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listIncidentTypes'."]:
    """Retrieve available incident types from PagerDuty.

    Use this tool to list incident types, such as security or major incidents, categorized by their enabled or disabled status. Useful for understanding how incidents are classified within PagerDuty."""  # 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="https://api.pagerduty.com/incidents/types",
        method="GET",
        params=remove_none_values({"filter": incident_type_filter}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_incident_type(
    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 'createIncidentType'."]:
    """Create a new incident type in PagerDuty to categorize incidents.

    Use this tool to create a new incident type in PagerDuty, allowing categorization by type, such as security incidents, major incidents, or fraud incidents. This helps organize and respond to different kinds of incidents effectively.

    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["CREATEINCIDENTTYPE"],
            "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["CREATEINCIDENTTYPE"] + "\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["CREATEINCIDENTTYPE"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/incidents/types",
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATEINCIDENTTYPE"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_incident_type_details(
    context: ToolContext,
    incident_type_identifier: Annotated[
        str, "The ID or name of the Incident Type to retrieve details for."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getIncidentType'."]:
    """Retrieve detailed information on a specific incident type.

    This tool fetches detailed information about a single incident type using either an incident type ID or name. It helps categorize incidents such as security or major incidents. Use this tool to get insights on incident categorization in your 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="https://api.pagerduty.com/incidents/types/{type_id_or_name}".format(  # noqa: UP032
            type_id_or_name=incident_type_identifier
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_incident_type(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    incident_type_id_or_name: Annotated[
        str | None,
        "The ID or name of the incident type to be updated. Specify to categorize the incident.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateIncidentType'."]:
    """Update or categorize an incident type on PagerDuty.

    Use this tool to update or categorize an incident type on PagerDuty, such as security or major incidents. Requires appropriate OAuth scope for modification.

    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["UPDATEINCIDENTTYPE"],
            "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 incident_type_id_or_name:
        missing_params.append(("incident_type_id_or_name", "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["UPDATEINCIDENTTYPE"] + "\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["UPDATEINCIDENTTYPE"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/incidents/types/{type_id_or_name}".format(  # noqa: UP032
            type_id_or_name=incident_type_id_or_name
        ),
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEINCIDENTTYPE"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_incident_type_custom_fields(
    context: ToolContext,
    incident_type_id_or_name: Annotated[
        str, "The ID or name of the incident type to retrieve custom fields for."
    ],
    include_additional_details: Annotated[
        str | None, "Specify additional details to include, such as 'field_options'."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listIncidentTypeCustomFields'."]:
    """List custom fields for a specified incident type.

    This tool retrieves custom fields associated with a specific incident type in PagerDuty. Custom fields allow for extended data to support features like customized filtering, search, and analytics. Use this tool when you need details on the custom fields for a particular incident type."""  # 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="https://api.pagerduty.com/incidents/types/{type_id_or_name}/custom_fields".format(  # noqa: UP032
            type_id_or_name=incident_type_id_or_name
        ),
        method="GET",
        params=remove_none_values({"include[]": include_additional_details}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_incident_type_custom_field(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    incident_type_id_or_name: Annotated[
        str | None,
        "The ID or name of the incident type for which the custom field is created.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'createIncidentTypeCustomField'."]:
    """Create a custom field for a specific incident type.

    This tool creates a custom field for a specified incident type on PagerDuty, allowing users to extend incidents with their own data to enhance filtering, search, and analytics. It requires `custom_fields.write` OAuth scope.

    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["CREATEINCIDENTTYPECUSTOMFIELD"],
            "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 incident_type_id_or_name:
        missing_params.append(("incident_type_id_or_name", "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["CREATEINCIDENTTYPECUSTOMFIELD"]
                + "\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["CREATEINCIDENTTYPECUSTOMFIELD"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/incidents/types/{type_id_or_name}/custom_fields".format(  # noqa: UP032
            type_id_or_name=incident_type_id_or_name
        ),
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATEINCIDENTTYPECUSTOMFIELD"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_incident_type_custom_field(
    context: ToolContext,
    field_id: Annotated[str, "The ID of the custom field to retrieve for the incident type."],
    incident_type_id_or_name: Annotated[
        str, "The ID or name of the Incident Type for which to retrieve the custom field."
    ],
    include_field_details: Annotated[
        str | None,
        "Specify additional details, such as 'field_options', to include in the response.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getIncidentTypeCustomField'."]:
    """Retrieve a custom field for a specific incident type.

    Use this tool to obtain custom fields associated with a specific incident type, enhancing incident details with user-defined data for filtering, search, and analytics."""  # 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="https://api.pagerduty.com/incidents/types/{type_id_or_name}/custom_fields/{field_id}".format(  # noqa: UP032
            type_id_or_name=incident_type_id_or_name, field_id=field_id
        ),
        method="GET",
        params=remove_none_values({"include[]": include_field_details}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_incident_custom_field(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    incident_type_identifier: Annotated[
        str | None,
        "The ID or name of the specific incident type to update the custom field for.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    field_identifier: Annotated[
        str | None,
        "Provide the unique ID of the field to be updated for the incident type.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateIncidentTypeCustomField'."]:
    """Update a custom field for a specific incident type.

    Use this tool to update custom fields for incident types, providing additional context and support for filtering and analytics. Custom field options can be modified in the same call.

    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["UPDATEINCIDENTCUSTOMFIELD"],
            "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 incident_type_identifier:
        missing_params.append(("incident_type_identifier", "path"))
    if not field_identifier:
        missing_params.append(("field_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["UPDATEINCIDENTCUSTOMFIELD"] + "\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["UPDATEINCIDENTCUSTOMFIELD"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/incidents/types/{type_id_or_name}/custom_fields/{field_id}".format(  # noqa: UP032
            type_id_or_name=incident_type_identifier, field_id=field_identifier
        ),
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEINCIDENTCUSTOMFIELD"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def delete_incident_type_custom_field(
    context: ToolContext,
    field_id: Annotated[str, "The unique identifier of the custom field to be deleted."],
    incident_type_id_or_name: Annotated[
        str, "The ID or name of the specific incident type to delete a custom field from."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteIncidentTypeCustomField'."]:
    """Delete a custom field for a specified incident type.

    Use this tool to delete a custom field from a specific incident type, enhancing filtering, search, or analytics flexibility. Ensure you have the necessary OAuth scope: `custom_fields.write`."""  # 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="https://api.pagerduty.com/incidents/types/{type_id_or_name}/custom_fields/{field_id}".format(  # noqa: UP032
            type_id_or_name=incident_type_id_or_name, field_id=field_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_custom_field_options(
    context: ToolContext,
    field_identifier: Annotated[str, "The unique identifier for the custom field."],
    incident_type_identifier: Annotated[
        str, "The ID or name of the Incident Type for which to retrieve custom field options."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listIncidentTypeCustomField'."]:
    """Retrieve options for a custom field in an incident type.

    This tool retrieves a list of field options for a custom field associated with a specific incident type. It helps in extending incidents with custom data for better filtering, search, and analytics."""  # 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="https://api.pagerduty.com/incidents/types/{type_id_or_name}/custom_fields/{field_id}/field_options".format(  # noqa: UP032
            type_id_or_name=incident_type_identifier, field_id=field_identifier
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_custom_field_option(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    incident_type_id_or_name: Annotated[
        str | None,
        "The ID or name of the incident type for which the custom field option will be created.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    field_id: Annotated[
        str | None,
        "The unique identifier for the custom field to which the option will be added. This should be a string that specifies the field within the incident type.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'createIncidentTypeCustomFieldFieldOptions'."
]:
    """Create a custom field option for incidents.

    This tool creates a field option for a custom field in incidents, allowing users to extend incident data with custom options. It supports additional context, customized filtering, search, and analytics.

    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["CREATECUSTOMFIELDOPTION"],
            "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 incident_type_id_or_name:
        missing_params.append(("incident_type_id_or_name", "path"))
    if not field_id:
        missing_params.append(("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["CREATECUSTOMFIELDOPTION"] + "\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["CREATECUSTOMFIELDOPTION"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/incidents/types/{type_id_or_name}/custom_fields/{field_id}/field_options".format(  # noqa: UP032
            type_id_or_name=incident_type_id_or_name, field_id=field_id
        ),
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATECUSTOMFIELDOPTION"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_custom_field_option(
    context: ToolContext,
    field_id: Annotated[
        str,
        "The ID of the custom field for which the field option details are retrieved. This ID specifies the field within the incident type.",  # noqa: E501
    ],
    field_option_id: Annotated[
        str,
        "The unique identifier for the field option within a custom field. Used to retrieve specific option details.",  # noqa: E501
    ],
    incident_type_identifier: Annotated[
        str,
        "The ID or name of the incident type for which the custom field option is to be retrieved.",
    ],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'getIncidentTypeCustomFieldFieldOptions'."
]:
    """Retrieve a specific custom field option for an incident type.

    This tool retrieves details of a specific field option within a custom field for a given incident type in PagerDuty. Custom fields allow users to extend incidents with custom data for filtering, search, and analytics. Use this tool when you need to access a particular field option of a custom field associated with an incident type."""  # 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="https://api.pagerduty.com/incidents/types/{type_id_or_name}/custom_fields/{field_id}/field_options/{field_option_id}".format(  # noqa: UP032
            type_id_or_name=incident_type_identifier,
            field_option_id=field_option_id,
            field_id=field_id,
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_custom_field_option(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    incident_type_id_or_name: Annotated[
        str | None,
        "The ID or name of the PagerDuty incident type.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    field_option_identifier: Annotated[
        str | None,
        "The unique identifier for the field option to be updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    field_id: Annotated[
        str | None,
        "The ID of the custom field to be updated in the incident type.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateIncidentTypeCustomFieldFieldOption'."
]:
    """Update a field option for a custom incident field.

    This tool updates a specific field option for a custom field in a PagerDuty incident type. Use it to modify custom data for improved filtering, search, and analytics features. Requires 'custom_fields.write' OAuth scope.

    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["UPDATECUSTOMFIELDOPTION"],
            "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 incident_type_id_or_name:
        missing_params.append(("incident_type_id_or_name", "path"))
    if not field_option_identifier:
        missing_params.append(("field_option_identifier", "path"))
    if not field_id:
        missing_params.append(("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["UPDATECUSTOMFIELDOPTION"] + "\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["UPDATECUSTOMFIELDOPTION"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/incidents/types/{type_id_or_name}/custom_fields/{field_id}/field_options/{field_option_id}".format(  # noqa: UP032
            type_id_or_name=incident_type_id_or_name,
            field_option_id=field_option_identifier,
            field_id=field_id,
        ),
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATECUSTOMFIELDOPTION"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def delete_custom_field_option(
    context: ToolContext,
    field_identifier: Annotated[
        str, "The unique identifier of the custom field from which the option will be deleted."
    ],
    field_option_id: Annotated[
        str,
        "The ID of the field option to be deleted. This is required for identifying which option to remove from the custom field.",  # noqa: E501
    ],
    incident_type_identifier: Annotated[
        str,
        "The ID or name of the incident type for which the custom field option should be deleted.",
    ],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'deleteIncidentTypeCustomFieldFieldOption'."
]:
    """Delete a custom field option for an incident type.

    Use this tool to delete a specific field option from a custom field in PagerDuty. This is useful for managing and organizing custom fields associated with different incident types. Requires appropriate OAuth scope."""  # 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="https://api.pagerduty.com/incidents/types/{type_id_or_name}/custom_fields/{field_id}/field_options/{field_option_id}".format(  # noqa: UP032
            type_id_or_name=incident_type_identifier,
            field_option_id=field_option_id,
            field_id=field_identifier,
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_user_license_allocations(
    context: ToolContext,
    pagination_offset: Annotated[
        int | None, "The starting position for pagination in the search results."
    ] = None,
    results_per_page: Annotated[
        int | None,
        "Specifies the number of results to display per page when retrieving user licenses.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listLicenseAllocations'."]:
    """Retrieve licenses allocated to users in your account.

    Use this tool to get a list of all licenses allocated to users within your account. This can be useful for tracking license usage or managing permissions. Requires `licenses.read` OAuth scope."""  # 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="https://api.pagerduty.com/license_allocations",
        method="GET",
        params=remove_none_values({"limit": results_per_page, "offset": pagination_offset}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_account_licenses(
    context: ToolContext,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listLicenses'."]:
    """Retrieve the list of licenses for your account.

    Use this tool to obtain a list of licenses associated with your PagerDuty account. This can be useful for managing permissions and understanding the resources available to your account. Requires the `licenses.read` OAuth scope."""  # 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="https://api.pagerduty.com/licenses",
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def fetch_incident_logs(
    context: ToolContext,
    additional_models_to_include: Annotated[
        str | None,
        "Specify additional models to include in the response, such as incidents, services, channels, or teams.",  # noqa: E501
    ] = None,
    include_total_in_pagination: Annotated[
        bool | None,
        "Set to true to populate the total field in pagination responses. Set to false for faster response times.",  # noqa: E501
    ] = False,
    pagination_offset: Annotated[
        int | None,
        "Offset to start pagination in search results. Used for navigating through large datasets.",
    ] = None,
    render_results_in_time_zone: Annotated[
        str | None,
        "Time zone for rendering results. Defaults to the account time zone if not specified.",
    ] = None,
    results_per_page: Annotated[
        int | None, "Specifies the number of results returned per page."
    ] = None,
    return_important_changes_only: Annotated[
        bool | None,
        "If true, return only the most important changes to the incident in log entries.",
    ] = False,
    search_end_date: Annotated[
        str | None, "The end date for the search range. Specify in YYYY-MM-DD format."
    ] = None,
    start_date_range: Annotated[
        str | None, "Specify the start date for the search range. Format: YYYY-MM-DD."
    ] = None,
    team_ids: Annotated[
        list[str] | None,
        "Array of team IDs to filter log entries. Requires 'teams' ability on the account.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listLogEntries'."]:
    """Retrieve all incident log entries across the account.

    This tool lists all the incident log entries, detailing events that occur for each incident across the entire account. Useful for tracking and analyzing incident-related activities."""  # 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="https://api.pagerduty.com/log_entries",
        method="GET",
        params=remove_none_values({
            "limit": results_per_page,
            "offset": pagination_offset,
            "total": include_total_in_pagination,
            "time_zone": render_results_in_time_zone,
            "since": start_date_range,
            "until": search_end_date,
            "is_overview": return_important_changes_only,
            "include[]": additional_models_to_include,
            "team_ids[]": team_ids,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_incident_log_entry_details(
    context: ToolContext,
    resource_id: Annotated[
        str, "The unique identifier of the incident log entry to retrieve details for."
    ],
    additional_models_to_include: Annotated[
        str | None,
        "List of additional models like 'incidents', 'services', 'channels', or 'teams' to include in the response.",  # noqa: E501
    ] = None,
    render_results_in_time_zone: Annotated[
        str | None,
        "Specify the time zone for rendering the results. Defaults to the account's time zone if not provided.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getLogEntry'."]:
    """Retrieve detailed information about a specific incident log entry.

    This tool is used to obtain detailed information for a specific incident log entry from PagerDuty. It is useful for accessing raw event data related to incidents. This action requires the 'incidents.read' OAuth scope."""  # 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="https://api.pagerduty.com/log_entries/{id}".format(id=resource_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({
            "time_zone": render_results_in_time_zone,
            "include[]": additional_models_to_include,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_incident_log_entry(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    incident_resource_id: Annotated[
        str | None,
        "The unique ID of the incident log entry resource to update.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    user_email: Annotated[
        str | None,
        "The email address of a valid user associated with the account making the log entry update request.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateLogEntryChannel'."]:
    """Update an existing incident log entry channel.

    This tool updates an existing incident log entry channel in PagerDuty. Use it when you need to modify the communication channel for a specific log entry. Requires OAuth scope: `incidents.write`.

    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["UPDATEINCIDENTLOGENTRY"],
            "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 incident_resource_id:
        missing_params.append(("incident_resource_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["UPDATEINCIDENTLOGENTRY"] + "\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["UPDATEINCIDENTLOGENTRY"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/log_entries/{id}/channel".format(id=incident_resource_id),  # noqa: UP032
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEINCIDENTLOGENTRY"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "From": user_email,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_maintenance_windows(
    context: ToolContext,
    filter_by_name: Annotated[
        str | None, "Filter maintenance windows to show only those with names matching the query."
    ] = None,
    filter_by_service_ids: Annotated[
        list[str] | None,
        "An array of service IDs to filter maintenance windows. Only results related to these services will be returned.",  # noqa: E501
    ] = None,
    filter_by_team_ids: Annotated[
        list[str] | None, "Array of team IDs to filter results. Requires 'teams' ability."
    ] = None,
    include_models: Annotated[
        str | None,
        "Specify models to include in the response, such as 'teams', 'services', or 'users'.",
    ] = None,
    include_total_in_response: Annotated[
        bool | None,
        "Set to true to populate the `total` field in pagination responses and get the total count of records.",  # noqa: E501
    ] = False,
    maintenance_window_state: Annotated[
        str | None,
        "Specify the state of maintenance windows to return: 'past', 'future', 'ongoing', 'open', or 'all'.",  # noqa: E501
    ] = None,
    pagination_offset: Annotated[
        int | None,
        "Offset to start the pagination of search results. Use to skip a number of results.",
    ] = None,
    results_per_page: Annotated[
        int | None, "The number of maintenance window results to display per page."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listMaintenanceWindows'."]:
    """Retrieve maintenance windows with optional filters for service or team.

    This tool retrieves a list of existing maintenance windows, allowing optional filtering by service and/or team. It can specify windows from the past, present, or future. A maintenance window is used to disable services temporarily for a set period. Scoped OAuth requires: `services.read`."""  # 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="https://api.pagerduty.com/maintenance_windows",
        method="GET",
        params=remove_none_values({
            "query": filter_by_name,
            "limit": results_per_page,
            "offset": pagination_offset,
            "total": include_total_in_response,
            "team_ids[]": filter_by_team_ids,
            "service_ids[]": filter_by_service_ids,
            "include[]": include_models,
            "filter": maintenance_window_state,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_maintenance_window(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    user_email: Annotated[
        str | None,
        "The email address of a valid user associated with the account making the request.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'createMaintenanceWindow'."]:
    """Create a maintenance window for specified services.

    This tool is used to create a maintenance window during which specified services are temporarily disabled to prevent new incidents from being created. Useful when upgrading systems or performing maintenance. Requires OAuth permission: `services.write`.

    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["CREATEMAINTENANCEWINDOW"],
            "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["CREATEMAINTENANCEWINDOW"] + "\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["CREATEMAINTENANCEWINDOW"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/maintenance_windows",
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATEMAINTENANCEWINDOW"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "From": user_email,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_maintenance_window(
    context: ToolContext,
    maintenance_window_id: Annotated[
        str, "The unique identifier of the maintenance window to retrieve."
    ],
    include_models: Annotated[
        str | None,
        "Array of additional models to include in the response. Options are 'teams', 'services', or 'users'.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getMaintenanceWindow'."]:
    """Retrieve details of an existing maintenance window in PagerDuty.

    Use this tool to get information about a specific maintenance window, which temporarily disables one or more services during a set period."""  # 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="https://api.pagerduty.com/maintenance_windows/{id}".format(id=maintenance_window_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({"include[]": include_models}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def delete_maintenance_window(
    context: ToolContext,
    maintenance_window_id: Annotated[
        str, "The unique identifier for the maintenance window to delete or end."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteMaintenanceWindow'."]:
    """Delete or end a maintenance window in PagerDuty.

    Use this tool to delete an existing maintenance window if it is scheduled for the future, or to end it if it is currently ongoing in PagerDuty. It cannot delete a maintenance window that has already ended."""  # 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="https://api.pagerduty.com/maintenance_windows/{id}".format(id=maintenance_window_id),  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_maintenance_window(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The unique identifier for the maintenance window to be updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateMaintenanceWindow'."]:
    """Update an existing maintenance window for services.

    Use this tool to modify an existing maintenance window, temporarily disabling specified services for a defined period. Ideal for scheduling downtime updates or adjustments.

    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["UPDATEMAINTENANCEWINDOW"],
            "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 resource_id:
        missing_params.append(("resource_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["UPDATEMAINTENANCEWINDOW"] + "\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["UPDATEMAINTENANCEWINDOW"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/maintenance_windows/{id}".format(id=resource_id),  # noqa: UP032
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEMAINTENANCEWINDOW"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_notifications(
    context: ToolContext,
    end_date_for_search: Annotated[
        str,
        "The end of the date range for the search. Must be in the same format as the 'since' date and within 3 months of it.",  # noqa: E501
    ],
    start_date: Annotated[
        str,
        "The start date for the search range. Time is optional and must match format of 'until'.",
    ],
    additional_details_include: Annotated[
        str | None, "Specify additional details to include, such as 'users'."
    ] = None,
    include_total_in_response: Annotated[
        bool | None,
        "Set to true to populate the total field in pagination responses, otherwise it will be null.",  # noqa: E501
    ] = False,
    notification_type_filter: Annotated[
        str | None, "Return notifications of a specific type such as SMS, email, phone, or push."
    ] = None,
    output_time_zone: Annotated[
        str | None,
        "Time zone for rendering results. Defaults to the account's time zone if not specified.",
    ] = None,
    pagination_offset: Annotated[
        int | None, "Offset number to begin the pagination of search results."
    ] = None,
    results_per_page: Annotated[int | None, "The number of results to display per page."] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listNotifications'."]:
    """Retrieve notifications within a specified time range.

    This tool retrieves notifications for a given time range, which can be filtered by type such as SMS, email, phone, or push notifications. Notifications are created when an incident is triggered or escalated."""  # 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="https://api.pagerduty.com/notifications",
        method="GET",
        params=remove_none_values({
            "limit": results_per_page,
            "offset": pagination_offset,
            "total": include_total_in_response,
            "time_zone": output_time_zone,
            "since": start_date,
            "until": end_date_for_search,
            "filter": notification_type_filter,
            "include[]": additional_details_include,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def delete_oauth_delegations(
    context: ToolContext,
    delegation_type: Annotated[
        str,
        "Specify the OAuth delegation type(s) to target: 'mobile' for mobile app or 'web' for web app sign-out. Multiple types can be separated by commas, for example, 'mobile,web'.",  # noqa: E501
    ],
    user_identifier: Annotated[
        str, "The unique ID of the user whose OAuth delegations will be deleted."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteOauthDelegations'."]:
    """Revoke OAuth app access for a user or account.

    Use this tool to delete all OAuth delegations, revoking app access for specified users or accounts on PagerDuty. This action requires reauthorization to regain access."""  # 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="https://api.pagerduty.com/oauth_delegations",
        method="DELETE",
        params=remove_none_values({"user_id": user_identifier, "type": delegation_type}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_on_call_entries(
    context: ToolContext,
    additional_details_to_include: Annotated[
        str | None,
        "Array of additional details to include such as escalation policies, users, or schedules.",
    ] = None,
    end_time_for_on_call_search: Annotated[
        str | None,
        "Specify the end of the time period to search for on-call entries. The end time must be after the start time ('since') and cannot exceed 90 days in the future. Defaults to current time if not specified.",  # noqa: E501
    ] = None,
    filter_by_escalation_policy_ids: Annotated[
        list[str] | None,
        "Array of escalation policy IDs to filter the on-call results. Only entries matching these IDs will be included.",  # noqa: E501
    ] = None,
    filter_user_ids: Annotated[
        list[str] | None,
        "An array of user IDs to filter and show only the on-calls for these users.",
    ] = None,
    include_total_in_response: Annotated[
        bool | None,
        "Set to true to populate the total field in pagination responses, enhancing the response with total entry count.",  # noqa: E501
    ] = False,
    pagination_offset: Annotated[
        int | None, "Offset indicating where to start the pagination for search results."
    ] = None,
    results_per_page: Annotated[
        int | None,
        "The maximum number of on-call entries to return per page. Set this to control pagination.",
    ] = None,
    results_time_zone: Annotated[
        str | None,
        "Specifies the time zone for rendering results. Defaults to the account time zone if not provided.",  # noqa: E501
    ] = None,
    return_earliest_on_call: Annotated[
        bool | None,
        "Set to true to filter and return only the earliest on-call entry for each combination of escalation policy, escalation level, and user.",  # noqa: E501
    ] = None,
    schedule_ids_filter: Annotated[
        list[str] | None,
        "Array of schedule IDs to filter results. Include `null` to cover permanent on-calls from direct user escalations.",  # noqa: E501
    ] = None,
    start_time_range: Annotated[
        str | None,
        "The start time for the search range. On-call periods overlapping this time will be included. Defaults to the current time. Limited to 90 days in the future.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listOnCalls'."]:
    """Retrieve on-call entries for a specified time range.

    This tool fetches the on-call entries indicating who is scheduled to be on call during a specified time period. This can be used to determine coverage for escalation policies and rules. Note that specific OAuth permissions ('oncalls.read') are required, and rate limits may apply."""  # 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="https://api.pagerduty.com/oncalls",
        method="GET",
        params=remove_none_values({
            "time_zone": results_time_zone,
            "limit": results_per_page,
            "offset": pagination_offset,
            "total": include_total_in_response,
            "include[]": additional_details_to_include,
            "user_ids[]": filter_user_ids,
            "escalation_policy_ids[]": filter_by_escalation_policy_ids,
            "schedule_ids[]": schedule_ids_filter,
            "since": start_time_range,
            "until": end_time_for_on_call_search,
            "earliest": return_earliest_on_call,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_paused_incident_report_alerts(
    context: ToolContext,
    end_date_range: Annotated[
        str | None, "The end date for the search range to retrieve alerts. Must be within 6 months."
    ] = None,
    filter_by_suspend_method: Annotated[
        str | None, "Filter alerts by suspension type: 'Auto Pause' or 'Event Rules'."
    ] = None,
    service_identifier: Annotated[
        str | None, "Filter reports to a specific service by providing its service ID."
    ] = None,
    start_date: Annotated[
        str | None,
        "The start date for the search range. It should be in ISO 8601 format (YYYY-MM-DD).",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getPausedIncidentReportAlerts'."]:
    """Retrieve recent paused incident report alerts.

    Fetches the 5 most recent alerts triggered and resolved after being paused within a maximum 6-month period. Available with Event Intelligence or Digital Operations plan."""  # 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="https://api.pagerduty.com/paused_incident_reports/alerts",
        method="GET",
        params=remove_none_values({
            "since": start_date,
            "until": end_date_range,
            "service_id": service_identifier,
            "suspended_by": filter_by_suspend_method,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_paused_incident_report_counts(
    context: ToolContext,
    end_date: Annotated[
        str | None,
        "End date for the date range over which to search for paused incident reports. Format: YYYY-MM-DD.",  # noqa: E501
    ] = None,
    filter_by_suspended_type: Annotated[
        str | None,
        "Filter to specify whether to include alerts suspended by Auto Pause or Event Rules. Use 'Auto Pause' or 'Event Rules'.",  # noqa: E501
    ] = None,
    service_identifier: Annotated[
        str | None,
        "Filter to limit reporting to a particular service by providing a specific service ID.",
    ] = None,
    start_date: Annotated[
        str | None, "The start date for the reporting period to search, in YYYY-MM-DD format."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getPausedIncidentReportCounts'."]:
    """Retrieve reporting counts for paused incident usage.

    This tool returns reporting counts for paused incident usage within a specified reporting period, up to a 6-month lookback. It is available with the Event Intelligence package or Digital Operations plan."""  # 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="https://api.pagerduty.com/paused_incident_reports/counts",
        method="GET",
        params=remove_none_values({
            "since": start_date,
            "until": end_date,
            "service_id": service_identifier,
            "suspended_by": filter_by_suspended_type,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_incident_priorities(
    context: ToolContext,
    include_total_in_response: Annotated[
        bool | None,
        "Set to true to include the total number of results in the response, which is not shown by default for performance reasons.",  # noqa: E501
    ] = False,
    pagination_offset: Annotated[
        int | None, "Offset to start pagination from this position in the results."
    ] = None,
    results_per_page: Annotated[
        int | None, "The number of incident priorities to display per page."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listPriorities'."]:
    """Retrieve a list of incident priorities by severity.

    This tool retrieves the list of existing incident priorities, ordered from most to least severe. It is used to understand the importance and impact levels of incidents within the Standard and Enterprise plans."""  # 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="https://api.pagerduty.com/priorities",
        method="GET",
        params=remove_none_values({
            "limit": results_per_page,
            "offset": pagination_offset,
            "total": include_total_in_response,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_rulesets(
    context: ToolContext,
    include_total_count: Annotated[
        bool | None,
        "Set to true to include the total count of results in the response. By default, this is omitted for speed. Refer to the Pagination Docs for details.",  # noqa: E501
    ] = False,
    pagination_offset: Annotated[
        int | None,
        "The starting point for pagination in search results. Use this to skip a specific number of results.",  # noqa: E501
    ] = None,
    results_per_page: Annotated[
        int | None, "Specify the number of ruleset results to return per page."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listRulesets'."]:
    """Retrieve a list of all rulesets from PagerDuty.

    This tool retrieves all rulesets, which are used to route events to endpoints and define actions based on event contents. Note that rulesets and event rules will soon be deprecated, and it is recommended to migrate to Event Orchestration. Use this tool to access existing rulesets until they are phased out."""  # 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="https://api.pagerduty.com/rulesets",
        method="GET",
        params=remove_none_values({
            "limit": results_per_page,
            "offset": pagination_offset,
            "total": include_total_count,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_ruleset(
    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 'createRuleset'."]:
    """Create a new ruleset to manage event routing.

    Use this tool to create a new ruleset for routing events and defining event rules. Note: Rulesets and Event Rules will soon reach end-of-life; consider migrating to Event Orchestration for enhanced features.

    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["CREATERULESET"],
            "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["CREATERULESET"] + "\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["CREATERULESET"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/rulesets",
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATERULESET"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_ruleset(
    context: ToolContext,
    ruleset_id: Annotated[str, "The unique identifier for the ruleset to retrieve from PagerDuty."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getRuleset'."]:
    """Retrieve details of a ruleset from PagerDuty.

    Fetch information about a specific ruleset, including event routing and actions. Useful for understanding or managing event rules within a ruleset. Note: Rulesets and Event Rules will be deprecated soon; consider migrating to Event Orchestration."""  # 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="https://api.pagerduty.com/rulesets/{id}".format(id=ruleset_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_ruleset(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The unique identifier for the ruleset to be updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateRuleset'."]:
    """Update an existing ruleset in PagerDuty.

    Use this tool to update a ruleset in PagerDuty, which routes events to endpoints and defines actions based on event content. Note: Rulesets are being phased out, and migration to Event Orchestration is recommended. Requires `event_rules.write` OAuth scope.

    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["UPDATERULESET"],
            "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 resource_id:
        missing_params.append(("resource_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["UPDATERULESET"] + "\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["UPDATERULESET"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/rulesets/{id}".format(id=resource_id),  # noqa: UP032
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATERULESET"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def delete_ruleset(
    context: ToolContext,
    ruleset_id: Annotated[str, "The unique identifier of the ruleset to be deleted."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteRuleset'."]:
    """Delete an existing ruleset in PagerDuty.

    Use this tool to delete a specified ruleset in PagerDuty. Note that rulesets and event rules are nearing end-of-life, and it's recommended to migrate to Event Orchestration for enhanced features. Ensure you have the appropriate OAuth scope: 'event_rules.write'."""  # 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="https://api.pagerduty.com/rulesets/{id}".format(id=ruleset_id),  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_event_rules(
    context: ToolContext,
    ruleset_id: Annotated[str, "The unique identifier for the ruleset to list event rules from."],
    include_total_in_response: Annotated[
        bool | None,
        "Set to true to include the total number of results in the pagination response. This may impact response time.",  # noqa: E501
    ] = False,
    pagination_start_offset: Annotated[
        int | None,
        "The starting point for pagination to begin returning results from a specific offset.",
    ] = None,
    results_per_page: Annotated[
        int | None, "Specify the number of results to return per page."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listRulesetEventRules'."]:
    """Retrieve all event rules within a specified ruleset.

    This tool lists all event rules associated with a specified ruleset on PagerDuty. It should be called to view actions based on event content within a ruleset. Note that rulesets and event rules will soon be deprecated, and migrating to Event Orchestration is recommended."""  # 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="https://api.pagerduty.com/rulesets/{id}/rules".format(id=ruleset_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({
            "limit": results_per_page,
            "offset": pagination_start_offset,
            "total": include_total_in_response,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_event_rule(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The unique identifier for the resource (ruleset) in which the event rule will be created.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'createRulesetEventRule'."]:
    """Create a new event rule within a ruleset.

    This tool creates a new event rule in a specified ruleset in PagerDuty. It should be called when you need to set up routing actions based on event content. Note: functionalities related to rulesets and event rules will be deprecated soon. Consider migrating to Event Orchestration.

    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["CREATEEVENTRULE"],
            "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 resource_id:
        missing_params.append(("resource_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["CREATEEVENTRULE"] + "\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["CREATEEVENTRULE"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/rulesets/{id}/rules".format(id=resource_id),  # noqa: UP032
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATEEVENTRULE"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_event_rule(
    context: ToolContext,
    event_rule_id: Annotated[str, "The ID of the Event Rule to retrieve from a ruleset."],
    resource_id: Annotated[
        str,
        "The unique ID of the resource to retrieve details for. This is required to specify which resource's event rule details are needed.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getRulesetEventRule'."]:
    """Retrieve details of an event rule from a ruleset.

    Use this tool to get information about a specific event rule within a ruleset on PagerDuty. Note that rulesets and event rules will be phased out soon, and migrating to Event Orchestration is recommended. This tool requires event_rules.read OAuth scope."""  # 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="https://api.pagerduty.com/rulesets/{id}/rules/{rule_id}".format(  # noqa: UP032
            id=resource_id, rule_id=event_rule_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_event_rule(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The unique ID of the ruleset resource to update.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    event_rule_id: Annotated[
        str | None,
        "The unique identifier of the Event Rule to update within the ruleset.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateRulesetEventRule'."]:
    """Update an existing event rule within a ruleset.

    This tool updates an event rule in a specific ruleset in PagerDuty. It supports partial updates, allowing modification of any combination of writable fields. It is recommended to migrate to Event Orchestration for enhanced features. OAuth with `event_rules.write` scope is required.

    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["UPDATEEVENTRULE"],
            "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 resource_id:
        missing_params.append(("resource_id", "path"))
    if not event_rule_id:
        missing_params.append(("event_rule_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["UPDATEEVENTRULE"] + "\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["UPDATEEVENTRULE"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/rulesets/{id}/rules/{rule_id}".format(  # noqa: UP032
            id=resource_id, rule_id=event_rule_id
        ),
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEEVENTRULE"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def delete_event_rule(
    context: ToolContext,
    event_rule_id: Annotated[str, "The unique identifier of the Event Rule to be deleted."],
    resource_id: Annotated[
        str, "The unique identifier of the resource (ruleset) to delete the event rule from."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteRulesetEventRule'."]:
    """Delete an event rule from a specified ruleset.

    Use this tool to delete an event rule within a specified ruleset on PagerDuty. This function should be called when you need to remove a rule that defines specific actions for routing events. Note that rulesets and event rules will be phased out soon, and migration to Event Orchestration is recommended."""  # 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="https://api.pagerduty.com/rulesets/{id}/rules/{rule_id}".format(  # noqa: UP032
            id=resource_id, rule_id=event_rule_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_on_call_schedules(
    context: ToolContext,
    additional_details_to_include: Annotated[
        str | None,
        "Specify additional details to include, such as 'schedule_layers', 'overrides_subschedule', 'final_schedule'.",  # noqa: E501
    ] = None,
    end_date_range: Annotated[
        str | None,
        "Specify the end date for the schedule entries range. Defaults to 2 weeks after the 'since' date if not provided.",  # noqa: E501
    ] = None,
    filter_by_name: Annotated[
        str | None, "Filters results to show records with matching names."
    ] = None,
    include_total_in_pagination: Annotated[
        bool | None,
        "Set to true to populate the total field in pagination responses. Defaults to null for faster response times if false.",  # noqa: E501
    ] = False,
    pagination_offset: Annotated[
        int | None,
        "The starting point for pagination of search results. Use this to skip a specific number of results.",  # noqa: E501
    ] = None,
    render_results_in_time_zone: Annotated[
        str | None,
        "Specify the time zone for displaying results. Defaults to the user's or account's time zone.",  # noqa: E501
    ] = None,
    results_per_page: Annotated[
        int | None, "The number of results to retrieve per page for the on-call schedules."
    ] = None,
    start_date_for_schedule_entries: Annotated[
        str | None,
        "The start date for showing schedule entries. Defaults to 2 weeks before the 'until' date if not specified.",  # noqa: E501
    ] = None,
    user_id_for_next_oncall: Annotated[
        str | None, "Specify a user_id to get information about this user's next on-call schedule."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listSchedules'."]:
    """Retrieve the on-call schedules from PagerDuty.

    Use this tool to get information about the time periods when users are on-call in PagerDuty. This tool is useful for understanding and managing on-call rotations. OAuth with 'schedules.read' scope is required."""  # 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="https://api.pagerduty.com/schedules",
        method="GET",
        params=remove_none_values({
            "limit": results_per_page,
            "offset": pagination_offset,
            "total": include_total_in_pagination,
            "query": filter_by_name,
            "include[]": additional_details_to_include,
            "time_zone": render_results_in_time_zone,
            "include_next_oncall_for_user": user_id_for_next_oncall,
            "since": start_date_for_schedule_entries,
            "until": end_date_range,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_on_call_schedule(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    allow_overflow: Annotated[
        bool | None,
        "Set to true to allow on-call schedule entries to extend beyond date range bounds. Defaults to false. This results in longer schedule entries that encompass the full day if applicable.  Only used when mode is 'execute'.",  # noqa: E501
    ] = None,
    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 'createSchedule'."]:
    """Create a new on-call schedule for users.

    This tool is used to create a new on-call schedule, specifying the time periods when users are on call. Use it when you need to establish or update on-call rotations for team members. Requires appropriate permissions (`schedules.write`).

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires 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 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["CREATEONCALLSCHEDULE"],
            "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 query parameters. "
                "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["CREATEONCALLSCHEDULE"] + "\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["CREATEONCALLSCHEDULE"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/schedules",
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATEONCALLSCHEDULE"],
        params=remove_none_values({"overflow": allow_overflow}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_schedule_details(
    context: ToolContext,
    schedule_id: Annotated[str, "The unique identifier for the schedule to retrieve details."],
    allow_schedule_overflow: Annotated[
        bool | None,
        "If true, schedule entries can extend beyond date range bounds. Defaults to false, truncating entries at bounds.",  # noqa: E501
    ] = False,
    date_range_start: Annotated[
        str | None,
        "The start date for the schedule entries. Defaults to 2 weeks before the end date if not provided. Optional parameter.",  # noqa: E501
    ] = None,
    end_date_for_schedule_entries: Annotated[
        str | None,
        "The end of the date range to display schedule entries. Defaults to 2 weeks after the start date if provided.",  # noqa: E501
    ] = None,
    results_time_zone: Annotated[
        str | None,
        "The time zone in which the schedule results will be rendered. Defaults to the schedule's time zone if not specified.",  # noqa: E501
    ] = None,
    user_id_for_next_oncall: Annotated[
        str | None,
        "Specify the `user_id` to get information about this user's next on-call schedule.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getSchedule'."]:
    """Retrieve detailed schedule information.

    Fetch detailed information about a specific schedule, including entries for each layer. Use this tool to access comprehensive schedule details when 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="https://api.pagerduty.com/schedules/{id}".format(id=schedule_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({
            "time_zone": results_time_zone,
            "since": date_range_start,
            "until": end_date_for_schedule_entries,
            "overflow": allow_schedule_overflow,
            "include_next_oncall_for_user": user_id_for_next_oncall,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def delete_schedule(
    context: ToolContext,
    schedule_id: Annotated[str, "The unique identifier for the schedule to delete."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteSchedule'."]:
    """Delete an on-call schedule.

    Use this tool to delete an on-call schedule, which defines when users are on call. This action requires scoped OAuth with 'schedules.write' permission."""  # 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="https://api.pagerduty.com/schedules/{id}".format(id=schedule_id),  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_on_call_schedule(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    schedule_id: Annotated[
        str | None,
        "The ID of the on-call schedule to be updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    allow_schedule_overflow: Annotated[
        bool | None,
        "Allows schedule entries to exceed date range bounds if set to true. Defaults to false.  Only used when mode is 'execute'.",  # noqa: E501
    ] = None,
    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 'updateSchedule'."]:
    """Update an existing on-call schedule in PagerDuty.

    Use this tool to modify the time periods that users are on-call in an existing schedule in PagerDuty. This function is useful when duty schedules need adjustments. Requires 'schedules.write' permission.

    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["UPDATEONCALLSCHEDULE"],
            "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 schedule_id:
        missing_params.append(("schedule_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["UPDATEONCALLSCHEDULE"] + "\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["UPDATEONCALLSCHEDULE"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/schedules/{id}".format(id=schedule_id),  # noqa: UP032
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEONCALLSCHEDULE"],
        params=remove_none_values({"overflow": allow_schedule_overflow}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_schedule_audit_records(
    context: ToolContext,
    resource_id: Annotated[
        str, "The unique identifier of the schedule resource to retrieve audit records for."
    ],
    end_of_date_range: Annotated[
        str | None,
        "The end date for the search range. Defaults to 'now' if not specified; must be within 31 days after the 'since' date.",  # noqa: E501
    ] = None,
    maximum_records_limit: Annotated[
        int | None,
        "The maximum number of records to return. This is the lesser of the specified limit or the API's maximum size.",  # noqa: E501
    ] = None,
    pagination_cursor: Annotated[
        str | None,
        "Cursor for requesting the next set of results. Use the `next_cursor` from the previous request to paginate.",  # noqa: E501
    ] = None,
    start_date: Annotated[
        str | None,
        "The start date for searching audit records. Defaults to 24 hours ago if not specified.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listSchedulesAuditRecords'."]:
    """Retrieve sorted audit records for a specific schedule.

    Fetches audit records for a particular schedule identified by its ID, sorted by the execution time from newest to oldest. Useful for monitoring changes in schedule configurations or activities. Requires OAuth with 'audit_records.read' scope for authorization. Supports cursor-based pagination for large datasets."""  # 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="https://api.pagerduty.com/schedules/{id}/audit/records".format(id=resource_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({
            "limit": maximum_records_limit,
            "cursor": pagination_cursor,
            "since": start_date,
            "until": end_of_date_range,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_schedule_overrides(
    context: ToolContext,
    end_date_range: Annotated[
        str, "The end date for the search range in which to list schedule overrides."
    ],
    resource_id: Annotated[str, "Specify the ID of the schedule resource to fetch overrides."],
    start_date: Annotated[str, "The start date for the search range, formatted as YYYY-MM-DD."],
    include_overflown_entries: Annotated[
        bool | None,
        "Set to true to include schedule entries extending beyond date range bounds. Defaults to false.",  # noqa: E501
    ] = None,
    return_only_editable_overrides: Annotated[
        bool | None,
        "Set to true to return only editable overrides. Only future overrides will be included.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listScheduleOverrides'."]:
    """Fetch overrides for a specific schedule and time range.

    Use this tool to list all the overrides for a given schedule within a specified time range. Useful for understanding changes to on-call schedules. Requires `schedules.read` OAuth scope."""  # 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="https://api.pagerduty.com/schedules/{id}/overrides".format(id=resource_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({
            "since": start_date,
            "until": end_date_range,
            "editable": return_only_editable_overrides,
            "overflow": include_overflown_entries,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_schedule_override(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The unique identifier for the schedule resource to which the override will be applied.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'createScheduleOverride'."]:
    """Create schedule overrides for specific users and time ranges.

    This tool creates one or more schedule overrides for specific users covering specified time periods. Overrides are used to manage on-call schedules. It should be called when you need to modify or assign on-call duties temporarily, ensuring the latest override has priority if overlapping occurs.

    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["CREATESCHEDULEOVERRIDE"],
            "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 resource_id:
        missing_params.append(("resource_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["CREATESCHEDULEOVERRIDE"] + "\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["CREATESCHEDULEOVERRIDE"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/schedules/{id}/overrides".format(id=resource_id),  # noqa: UP032
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATESCHEDULEOVERRIDE"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def delete_schedule_override(
    context: ToolContext,
    override_id: Annotated[
        str, "The unique identifier for the schedule override to be deleted or truncated."
    ],
    resource_id: Annotated[
        str, "The unique identifier for the schedule to remove or truncate the override from."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteScheduleOverride'."]:
    """Remove or truncate an on-call schedule override.

    Use this tool to remove a schedule override if it hasn't started, or truncate it if it's currently active. Overrides with start times before now but end times in the future are shortened to the current time. Successful deletion returns a 204 status, while truncation returns a 200 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="https://api.pagerduty.com/schedules/{id}/overrides/{override_id}".format(  # noqa: UP032
            id=resource_id, override_id=override_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_on_call_users(
    context: ToolContext,
    schedule_resource_id: Annotated[
        str, "The ID of the schedule resource to retrieve on-call users for."
    ],
    end_date_range: Annotated[
        str | None, "The end date for the time range of user search. Format as YYYY-MM-DD."
    ] = None,
    start_date_range: Annotated[
        str | None,
        "The start date of the range to search for users on call. Format should be YYYY-MM-DD.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listScheduleUsers'."]:
    """Retrieve users on call for a given schedule and time range.

    This tool lists all users who are on call for a specified schedule within a given time range. It is useful for managing and viewing on-call schedules and requires the `users.read` OAuth permission."""  # 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="https://api.pagerduty.com/schedules/{id}/users".format(id=schedule_resource_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({"since": start_date_range, "until": end_date_range}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def preview_on_call_schedule(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    start_date_range: Annotated[
        str | None,
        "The start date and time for the schedule preview. Use ISO 8601 format (e.g., '2023-10-01T10:00:00Z').  Only used when mode is 'execute'.",  # noqa: E501
    ] = None,
    end_date: Annotated[
        str | None,
        "The end date of the range for the on-call schedule preview. Format as ISO 8601 string.  Only used when mode is 'execute'.",  # noqa: E501
    ] = None,
    include_overflow_entries: Annotated[
        bool | None,
        "Set to true to allow schedule entries to overflow beyond the date range bounds. Defaults to false. True includes entries beyond specified dates.  Only used when mode is 'execute'.",  # noqa: E501
    ] = None,
    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 'createSchedulePreview'."]:
    """Generate a preview of an on-call schedule without saving it.

    This tool previews an on-call schedule, allowing users to see time periods when team members are on-call without making any permanent changes. Useful for planning and adjustments before finalizing the schedule. Requires appropriate OAuth permissions.

    Note: Understanding the request schema is necessary to properly create
    the stringified JSON input object for execution.\n\nThis operation also requires 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 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["PREVIEWONCALLSCHEDULE"],
            "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 query parameters. "
                "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["PREVIEWONCALLSCHEDULE"] + "\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["PREVIEWONCALLSCHEDULE"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/schedules/preview",
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["PREVIEWONCALLSCHEDULE"],
        params=remove_none_values({
            "since": start_date_range,
            "until": end_date,
            "overflow": include_overflow_entries,
        }),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_service_dependency(
    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 'createServiceDependency'."]:
    """Creates dependencies between two services in PagerDuty.

    Use this tool to establish new relationships between business or technical services on PagerDuty. It manages dependencies with constraints on the number of relations and depth. Useful for modeling complex service architectures across teams.

    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["CREATESERVICEDEPENDENCY"],
            "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["CREATESERVICEDEPENDENCY"] + "\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["CREATESERVICEDEPENDENCY"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/service_dependencies/associate",
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATESERVICEDEPENDENCY"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_business_service_dependencies(
    context: ToolContext,
    service_id: Annotated[str, "The ID of the Business Service to retrieve its dependencies."],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'getBusinessServiceServiceDependencies'."
]:
    """Retrieve immediate dependencies of a Business Service.

    This tool retrieves all immediate dependencies of a specified Business Service in PagerDuty. It models capabilities that span multiple technical services and may be owned by various teams. Appropriate for understanding service dependencies in a business context."""  # 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="https://api.pagerduty.com/service_dependencies/business_services/{id}".format(  # noqa: UP032
            id=service_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def remove_service_dependency(
    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 'deleteServiceDependency'."]:
    """Disassociate dependencies between two services.

    Use this tool to disassociate or remove dependencies between two business or technical services in PagerDuty. Suitable for scenarios where you need to update or modify service relationships managed by different teams.

    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["REMOVESERVICEDEPENDENCY"],
            "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["REMOVESERVICEDEPENDENCY"] + "\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["REMOVESERVICEDEPENDENCY"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/service_dependencies/disassociate",
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["REMOVESERVICEDEPENDENCY"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_service_dependencies(
    context: ToolContext,
    resource_id: Annotated[
        str, "The ID of the technical service whose dependencies are to be retrieved."
    ],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'getTechnicalServiceServiceDependencies'."
]:
    """Fetch immediate dependencies of a technical service.

    This tool retrieves all immediate dependencies of a specified technical service, also known as a service, using its ID. Useful for understanding service interconnections. Requires 'services.read' OAuth scope."""  # 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="https://api.pagerduty.com/service_dependencies/technical_services/{id}".format(  # noqa: UP032
            id=resource_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_services(
    context: ToolContext,
    filter_by_service_name: Annotated[
        str | None, "Filters results to show only services with the specified name."
    ] = None,
    filter_by_team_ids: Annotated[
        list[str] | None,
        "Filter results to only include services related to the specified team IDs. Requires 'teams' ability.",  # noqa: E501
    ] = None,
    include_additional_details: Annotated[
        str | None,
        "Array of additional details to include, such as 'escalation_policies', 'teams', 'integrations', or 'auto_pause_notifications_parameters'.",  # noqa: E501
    ] = None,
    include_total_in_response: Annotated[
        bool | None, "Set to true to include the total count of results in the pagination response."
    ] = False,
    name_query_filter: Annotated[
        str | None, "Filters results to show only services with names matching the query."
    ] = None,
    pagination_offset: Annotated[int | None, "Offset to start pagination search results."] = None,
    results_per_page: Annotated[
        int | None, "Specify the number of results to be returned per page."
    ] = None,
    results_time_zone: Annotated[
        str | None, "Time zone for rendering results, defaulting to the account time zone."
    ] = None,
    sort_results_by: Annotated[
        str | None,
        "Specifies the field and order (ascending/descending) to sort the results by. Options include: 'name', 'name:asc', 'name:desc'.",  # noqa: E501
    ] = "name",
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listServices'."]:
    """Retrieve a list of existing services.

    Use this tool to get a list of services, which may include applications, components, or teams for incident 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="https://api.pagerduty.com/services",
        method="GET",
        params=remove_none_values({
            "query": name_query_filter,
            "limit": results_per_page,
            "offset": pagination_offset,
            "total": include_total_in_response,
            "team_ids[]": filter_by_team_ids,
            "time_zone": results_time_zone,
            "sort_by": sort_results_by,
            "include[]": include_additional_details,
            "name": filter_by_service_name,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_new_service(
    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 'createService'."]:
    """Create a new service for incident management.

    Use this tool to create a new service within an account for incident management, representing an application, component, or team. Ensure the status is set to 'active' during creation. This tool is essential for managing services and handling incidents efficiently.

    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["CREATENEWSERVICE"],
            "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["CREATENEWSERVICE"] + "\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["CREATENEWSERVICE"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/services",
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATENEWSERVICE"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_service_details(
    context: ToolContext,
    service_id: Annotated[str, "The unique identifier of the service to retrieve details for."],
    additional_details_to_include: Annotated[
        str | None,
        "Array of additional details to include, such as escalation policies, teams, auto pause notifications parameters, or integrations.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getService'."]:
    """Retrieve details about an existing service.

    Fetch detailed information about a service, which may represent an application, component, or team for incident management. Useful for accessing specific service data when managing incidents."""  # 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="https://api.pagerduty.com/services/{id}".format(id=service_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({"include[]": additional_details_to_include}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def delete_service(
    context: ToolContext,
    service_id: Annotated[str, "The unique ID of the service to be deleted."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteService'."]:
    """Remove a service to prevent new incident creation.

    Use this tool to delete an existing service from PagerDuty. Once deleted, the service will no longer be accessible via the web UI, and new incidents cannot be created for it. Typically used for applications, components, or teams no longer needing incident 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="https://api.pagerduty.com/services/{id}".format(id=service_id),  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_service_details(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    service_id: Annotated[
        str | None,
        "The unique identifier of the service to be updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateService'."]:
    """Update details of an existing service in PagerDuty.

    Update information for an existing service, such as an application, component, or team. Ensure the open incident limit is not exceeded and handle `auto_resolve_timeout` appropriately. Requires `services.write` OAuth scope.

    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["UPDATESERVICEDETAILS"],
            "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 service_id:
        missing_params.append(("service_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["UPDATESERVICEDETAILS"] + "\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["UPDATESERVICEDETAILS"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/services/{id}".format(id=service_id),  # noqa: UP032
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATESERVICEDETAILS"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_service_audit_records(
    context: ToolContext,
    resource_id: Annotated[
        str, "The ID of the service for which audit records are being retrieved."
    ],
    end_date: Annotated[
        str | None,
        "The end of the date range for searching audit records. Defaults to `now()` if unspecified. Must be within 31 days after `start_date`.",  # noqa: E501
    ] = None,
    pagination_cursor: Annotated[
        str | None,
        "Optional parameter to retrieve the next set of audit records. Use the token from `next_cursor` of the previous response. Defaults to the start if not provided.",  # noqa: E501
    ] = None,
    result_limit: Annotated[
        int | None,
        "Specify the maximum number of audit records to return. Accepts an integer value.",
    ] = None,
    start_date_range: Annotated[
        str | None,
        "The start of the date range for search. Defaults to 24 hours ago if not specified.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listServiceAuditRecords'."]:
    """Retrieve service audit records sorted by execution time.

    Use this tool to get audit records for a specific service from PagerDuty, sorted by execution time from newest to oldest. Ideal for monitoring actions and changes related to a service. Ensure proper OAuth scope with `audit_records.read`."""  # 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="https://api.pagerduty.com/services/{id}/audit/records".format(id=resource_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({
            "limit": result_limit,
            "cursor": pagination_cursor,
            "since": start_date_range,
            "until": end_date,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_service_change_events(
    context: ToolContext,
    resource_id: Annotated[str, "The ID of the service resource for which to list change events."],
    end_date_utc: Annotated[
        str | None,
        "The end of the date range for the search, in UTC ISO 8601 format. Only UTC dates are accepted.",  # noqa: E501
    ] = None,
    filter_by_integration_ids: Annotated[
        list[str] | None,
        "An array of integration IDs to filter results. Only events related to these integrations will be returned.",  # noqa: E501
    ] = None,
    include_total_in_response: Annotated[
        bool | None,
        "Set to true to populate the total field in pagination responses, which may affect response time.",  # noqa: E501
    ] = False,
    pagination_offset: Annotated[int | None, "Offset to start pagination search results."] = None,
    results_per_page: Annotated[
        int | None, "Specify the number of results to return per page."
    ] = None,
    start_date: Annotated[
        str | None,
        "The start date of the search range, in UTC ISO 8601 format (e.g., '2023-10-01T00:00:00Z'). Ensure it is in UTC to avoid errors.",  # noqa: E501
    ] = None,
    team_ids: Annotated[
        list[str] | None,
        "An array of team IDs to filter results. Account must have `teams` ability to use this.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listServiceChangeEvents'."]:
    """Retrieve change events for a specific service.

    Use this tool to list all existing change events related to a specified service. Requires the 'services.read' OAuth scope."""  # 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="https://api.pagerduty.com/services/{id}/change_events".format(id=resource_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({
            "since": start_date,
            "until": end_date_utc,
            "limit": results_per_page,
            "offset": pagination_offset,
            "total": include_total_in_response,
            "team_ids[]": team_ids,
            "integration_ids[]": filter_by_integration_ids,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_service_integration(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The ID of the resource to create an integration for.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'createServiceIntegration'."]:
    """Create a new integration for a specific service.

    Use this tool to create a new integration for a service, which can represent an application, component, or team. This action is relevant when you need to establish connections that allow incident management for that service.

    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["CREATESERVICEINTEGRATION"],
            "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 resource_id:
        missing_params.append(("resource_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["CREATESERVICEINTEGRATION"] + "\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["CREATESERVICEINTEGRATION"] + "\n```"
            ),
        ) from e

    response = await make_request(
        url="https://api.pagerduty.com/services/{id}/integrations".format(id=resource_id),  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=json.dumps(request_data),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_service_integration(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The unique identifier of the resource to be updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    service_integration_id: Annotated[
        str | None,
        "The unique identifier for the integration associated with the service to update. This ID specifies which integration to modify.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateServiceIntegration'."]:
    """Update an integration for a specific service.

    Use this tool to update an integration that belongs to a specific service in PagerDuty. Services represent applications, components, or teams for incident management. Appropriate for when you need to modify integration settings or 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["UPDATESERVICEINTEGRATION"],
            "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 resource_id:
        missing_params.append(("resource_id", "path"))
    if not service_integration_id:
        missing_params.append(("service_integration_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["UPDATESERVICEINTEGRATION"] + "\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["UPDATESERVICEINTEGRATION"] + "\n```"
            ),
        ) from e

    response = await make_request(
        url="https://api.pagerduty.com/services/{id}/integrations/{integration_id}".format(  # noqa: UP032
            id=resource_id, integration_id=service_integration_id
        ),
        method="PUT",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=json.dumps(request_data),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_service_integration_details(
    context: ToolContext,
    integration_id: Annotated[
        str, "The unique ID of the integration on the specified service in PagerDuty."
    ],
    resource_id: Annotated[
        str, "The unique identifier for the service resource to retrieve integration details."
    ],
    include_additional_details: Annotated[
        str | None, "Specify additional details like 'services' or 'vendors' to include."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getServiceIntegration'."]:
    """Retrieve details about a specific service integration.

    This tool retrieves details about an integration for a specified service in PagerDuty. Use this tool to find information about how an application, component, or team is integrated for incident management. Requires appropriate OAuth permissions."""  # 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="https://api.pagerduty.com/services/{id}/integrations/{integration_id}".format(  # noqa: UP032
            id=resource_id, integration_id=integration_id
        ),
        method="GET",
        params=remove_none_values({"include[]": include_additional_details}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_service_event_rules(
    context: ToolContext,
    service_id: Annotated[
        str, "The unique identifier for the service whose event rules are being listed."
    ],
    include_additional_models: Annotated[
        str | None,
        "Array of additional models to include in response, such as 'migrated_metadata'.",
    ] = None,
    pagination_offset: Annotated[
        int | None, "The starting point for pagination of search results, specified as an integer."
    ] = None,
    populate_total_field: Annotated[
        bool | None,
        "Set to true to populate the total field in pagination responses; set to false to keep it null for faster responses.",  # noqa: E501
    ] = False,
    results_per_page: Annotated[
        int | None, "Specifies the number of results returned per page in the response."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listServiceEventRules'."]:
    """Retrieve a list of event rules for a specific service.

    Use this tool to get a list of event rules associated with a specific service in PagerDuty. This functionality is marked for end-of-life, so consider migrating to Event Orchestration for enhanced features."""  # 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="https://api.pagerduty.com/services/{id}/rules".format(id=service_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({
            "limit": results_per_page,
            "offset": pagination_offset,
            "total": populate_total_field,
            "include[]": include_additional_models,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_service_event_rule(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    service_resource_id: Annotated[
        str | None,
        "The unique ID of the service resource where the event rule will be created.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'createServiceEventRule'."]:
    """Create a new Event Rule on a Service in PagerDuty.

    This tool creates a new Event Rule for a specified service in PagerDuty. It should be called when you need to set up or manage event rules for monitoring and alerting within a service. Note that rulesets and event rules will be deprecated, so consider migrating to Event Orchestration.

    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["CREATESERVICEEVENTRULE"],
            "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 service_resource_id:
        missing_params.append(("service_resource_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["CREATESERVICEEVENTRULE"] + "\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["CREATESERVICEEVENTRULE"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/services/{id}/rules".format(id=service_resource_id),  # noqa: UP032
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATESERVICEEVENTRULE"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def convert_service_event_rules(
    context: ToolContext,
    resource_id: Annotated[
        str,
        "The unique identifier of the service to be converted. This is required to specify which service's event rules need to be converted to orchestration rules.",  # noqa: E501
    ],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'convertServiceEventRulesToEventOrchestration'."
]:
    """Convert service event rules to orchestration rules.

    Use this tool to convert a service's event rules into equivalent event orchestration rules. This process makes existing event rules read-only, with future updates needing orchestration rules. This tool is vital for migrating as event rules will soon be deprecated."""  # 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="https://api.pagerduty.com/services/{id}/rules/convert".format(id=resource_id),  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_event_rule_from_service(
    context: ToolContext,
    event_rule_id: Annotated[
        str, "The ID of the event rule to retrieve from the specified service."
    ],
    resource_id: Annotated[
        str, "The unique identifier of the service resource to retrieve the event rule for."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getServiceEventRule'."]:
    """Retrieve an event rule from a specified service.

    This tool retrieves details of a specific event rule from a given service in PagerDuty. It is important to migrate to Event Orchestration for enhanced features."""  # 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="https://api.pagerduty.com/services/{id}/rules/{rule_id}".format(  # noqa: UP032
            id=resource_id, rule_id=event_rule_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_service_event_rule(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The unique ID of the service resource to be updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    event_rule_id: Annotated[
        str | None,
        "The ID of the Event Rule to update within the service. It identifies which event rule the update will apply to.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateServiceEventRule'."]:
    """Update a specific event rule within a service.

    This tool updates an event rule on a particular service in PagerDuty. It supports partial updates, meaning you can provide any number of writable fields to modify the rule. This should be called when there's a need to adjust event rules to maintain or enhance service monitoring. Note: Migration to Event Orchestration is recommended as these rules will be phased out soon.

    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["UPDATESERVICEEVENTRULE"],
            "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 resource_id:
        missing_params.append(("resource_id", "path"))
    if not event_rule_id:
        missing_params.append(("event_rule_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["UPDATESERVICEEVENTRULE"] + "\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["UPDATESERVICEEVENTRULE"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/services/{id}/rules/{rule_id}".format(  # noqa: UP032
            id=resource_id, rule_id=event_rule_id
        ),
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATESERVICEEVENTRULE"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def delete_service_event_rule(
    context: ToolContext,
    event_rule_id: Annotated[
        str, "The ID of the Event Rule to be deleted. Use this to specify which rule to remove."
    ],
    service_id: Annotated[
        str, "The unique identifier of the service resource from which to delete the event rule."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteServiceEventRule'."]:
    """Delete an event rule from a service in PagerDuty.

    Use this tool to delete a specific event rule from a service using its service and rule IDs. Note that event rules will soon be deprecated, and migration to Event Orchestration is recommended."""  # 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="https://api.pagerduty.com/services/{id}/rules/{rule_id}".format(  # noqa: UP032
            id=service_id, rule_id=event_rule_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_service_custom_field(
    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 'createServiceCustomField'."]:
    """Create a new custom field for services.

    This tool is used to create a new custom field for services in PagerDuty, including field options if provided. It is useful when you need to add custom metadata or specifications to a service. Requires custom_fields.write permission.

    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["CREATESERVICECUSTOMFIELD"],
            "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["CREATESERVICECUSTOMFIELD"] + "\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["CREATESERVICECUSTOMFIELD"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/services/custom_fields",
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATESERVICECUSTOMFIELD"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_service_custom_fields(
    context: ToolContext,
    include_additional_details: Annotated[
        str | None, "Specify additional details to include, such as 'field_options'."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listServiceCustomFields'."]:
    """Retrieve the custom fields for PagerDuty services.

    This tool should be called to obtain a list of custom fields available for services in PagerDuty. It requires the 'custom_fields.read' OAuth scope."""  # 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="https://api.pagerduty.com/services/custom_fields",
        method="GET",
        params=remove_none_values({"include[]": include_additional_details}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_service_custom_field_info(
    context: ToolContext,
    field_id: Annotated[
        str, "The unique identifier for the custom field you want to retrieve information about."
    ],
    include_field_details: Annotated[
        str | None, "Specify additional details to include, such as 'field_options'."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getServiceCustomField'."]:
    """Retrieve detailed information about a custom field for a service.

    Use this tool to get detailed information about a specific custom field associated with a service in PagerDuty. Requires OAuth scope: custom_fields.read."""  # 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="https://api.pagerduty.com/services/custom_fields/{field_id}".format(field_id=field_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({"include[]": include_field_details}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_service_custom_field(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    service_field_id: Annotated[
        str | None,
        "The unique identifier of the custom field to update in PagerDuty.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateServiceCustomField'."]:
    """Update a custom field for a PagerDuty service.

    This tool updates a specified custom field for services in PagerDuty. It requires OAuth with `custom_fields.write` permission.

    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["UPDATESERVICECUSTOMFIELD"],
            "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 service_field_id:
        missing_params.append(("service_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["UPDATESERVICECUSTOMFIELD"] + "\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["UPDATESERVICECUSTOMFIELD"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/services/custom_fields/{field_id}".format(  # noqa: UP032
            field_id=service_field_id
        ),
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATESERVICECUSTOMFIELD"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def delete_service_custom_field(
    context: ToolContext,
    field_id: Annotated[str, "The ID of the custom field you want to delete from the service."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteServiceCustomField'."]:
    """Deletes a custom field from a service.

    Use this tool to delete a custom field from a service in PagerDuty. This action requires 'custom_fields.write' permissions."""  # 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="https://api.pagerduty.com/services/custom_fields/{field_id}".format(field_id=field_id),  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_service_custom_field_options(
    context: ToolContext,
    field_id: Annotated[str, "The unique identifier for the custom field to retrieve options for."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listServiceCustomFieldOptions'."]:
    """Retrieve all options for a specific custom field in PagerDuty.

    Call this tool to get all options available for a specific custom field in PagerDuty services. Useful for understanding the potential values a custom field can take."""  # 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="https://api.pagerduty.com/services/custom_fields/{field_id}/field_options".format(  # noqa: UP032
            field_id=field_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def add_service_field_option(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    field_identifier: Annotated[
        str | None,
        "The unique identifier for the custom field where the new option will be added. This is required to specify which field you are modifying.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'createServiceCustomFieldOption'."]:
    """Create a new option for a custom field in PagerDuty services.

    This tool is used to create a new option for a specified custom field in the PagerDuty services. It should be called when you want to extend the available options for a specific field. Requires `custom_fields.write` OAuth scope.

    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["ADDSERVICEFIELDOPTION"],
            "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 field_identifier:
        missing_params.append(("field_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["ADDSERVICEFIELDOPTION"] + "\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["ADDSERVICEFIELDOPTION"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/services/custom_fields/{field_id}/field_options".format(  # noqa: UP032
            field_id=field_identifier
        ),
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["ADDSERVICEFIELDOPTION"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_service_custom_field_option(
    context: ToolContext,
    field_id: Annotated[
        str,
        "The unique identifier for the field to which the custom option belongs. Required to fetch the specific field option.",  # noqa: E501
    ],
    field_option_identifier: Annotated[
        str,
        "The unique identifier for the field option. Use to specify which custom field option to retrieve.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getServiceCustomFieldOption'."]:
    """Retrieve a service custom field option by field and option ID.

    Use this tool to get details of a specific custom field option within a service by providing the field and option IDs. Requires 'custom_fields.read' OAuth scope."""  # 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="https://api.pagerduty.com/services/custom_fields/{field_id}/field_options/{field_option_id}".format(  # noqa: UP032
            field_id=field_id, field_option_id=field_option_identifier
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_service_custom_field_option(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    field_id: Annotated[
        str | None,
        "The unique identifier of the field to be updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    field_option_id: Annotated[
        str | None,
        "The ID of the custom field option to update.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateServiceCustomFieldOption'."]:
    """Update a custom field option in a service.

    Use this tool to update a specific custom field option for a service in PagerDuty. This is useful when you need to adjust configurations related to custom fields. Requires appropriate OAuth permissions.

    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["UPDATESERVICECUSTOMFIELDOPTION"],
            "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 field_id:
        missing_params.append(("field_id", "path"))
    if not field_option_id:
        missing_params.append(("field_option_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["UPDATESERVICECUSTOMFIELDOPTION"]
                + "\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["UPDATESERVICECUSTOMFIELDOPTION"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/services/custom_fields/{field_id}/field_options/{field_option_id}".format(  # noqa: UP032
            field_id=field_id, field_option_id=field_option_id
        ),
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATESERVICECUSTOMFIELDOPTION"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def delete_service_custom_field_option(
    context: ToolContext,
    field_identifier: Annotated[str, "The ID of the field to be deleted from the service."],
    field_option_id: Annotated[
        str, "The unique identifier for the custom field option to be deleted."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteServiceCustomFieldOption'."]:
    """Delete a custom field option from a service.

    Use this tool to remove a specific custom field option associated with a service in PagerDuty. This is useful when you need to manage or update service configurations by deleting unnecessary or outdated options."""  # 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="https://api.pagerduty.com/services/custom_fields/{field_id}/field_options/{field_option_id}".format(  # noqa: UP032
            field_id=field_identifier, field_option_id=field_option_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_service_custom_field_values(
    context: ToolContext,
    service_id: Annotated[
        str,
        "The unique identifier for the PagerDuty service whose custom field values are to be retrieved.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getServiceCustomFieldValues'."]:
    """Retrieve custom field values for a specific service.

    Use this tool to get custom field values associated with a specific service in PagerDuty. This is useful for accessing additional information formatted as custom fields. Requires appropriate OAuth scopes."""  # 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="https://api.pagerduty.com/services/{id}/custom_fields/values".format(id=service_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def set_service_custom_field_values(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    service_id: Annotated[
        str | None,
        "The unique identifier of the service whose custom field values need to be updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateServiceCustomFieldValues'."]:
    """Update custom field values for a specific service.

    Use this tool to set custom field values for a specific service in PagerDuty. It requires the scoped OAuth `services.write` permission.

    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["SETSERVICECUSTOMFIELDVALUES"],
            "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 service_id:
        missing_params.append(("service_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["SETSERVICECUSTOMFIELDVALUES"]
                + "\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["SETSERVICECUSTOMFIELDVALUES"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/services/{id}/custom_fields/values".format(id=service_id),  # noqa: UP032
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["SETSERVICECUSTOMFIELDVALUES"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_service_feature_enablements(
    context: ToolContext,
    service_id: Annotated[
        str,
        "The unique identifier for the PagerDuty service whose feature enablements you want to list.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listServiceFeatureEnablements'."]:
    """List feature enablement settings for a service.

    Retrieves all feature enablement settings for a specified service, focusing on AIOps enablements. If the account lacks AIOps entitlement, a warning will be included with the 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="https://api.pagerduty.com/services/{id}/enablements".format(id=service_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_service_feature_enablement(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The ID of the PagerDuty resource to update the feature enablement for.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    feature_enablement_identifier: Annotated[
        str | None,
        "Specify the feature enablement identifier, typically the addon name. Currently, only 'aiops' is supported.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateServiceFeatureEnablement'."]:
    """Update the feature enablement for a service addon.

    Update the feature enablement setting for a specific product addon on a PagerDuty service. This tool manages enabling or disabling the addon features. Currently, only 'aiops' is supported. Warnings may be returned if the account is not entitled to use AIOps features.

    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["UPDATESERVICEFEATUREENABLEMENT"],
            "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 resource_id:
        missing_params.append(("resource_id", "path"))
    if not feature_enablement_identifier:
        missing_params.append(("feature_enablement_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["UPDATESERVICEFEATUREENABLEMENT"]
                + "\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["UPDATESERVICEFEATUREENABLEMENT"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/services/{id}/enablements/{feature_name}".format(  # noqa: UP032
            id=resource_id, feature_name=feature_enablement_identifier
        ),
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATESERVICEFEATUREENABLEMENT"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def retrieve_session_configurations(
    context: ToolContext,
    session_configuration_type: Annotated[
        str | None,
        "Specifies session configuration type: 'mobile' or 'web'. Omit to return both types.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getSessionConfigurations'."]:
    """Retrieve session configurations for a PagerDuty account.

    This tool retrieves session configurations for a PagerDuty account, either returning all available configurations or a specific type if requested. No configurations result in a 404 error. Use it to access mobile and web session settings."""  # 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="https://api.pagerduty.com/session_configurations",
        method="GET",
        params=remove_none_values({"type": session_configuration_type}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_session_configurations(
    context: ToolContext,
    absolute_session_time_to_live_seconds: Annotated[
        int, "Specify the absolute session time to live in seconds."
    ],
    idle_session_time_to_live: Annotated[
        int,
        "Specify the idle session time to live in seconds. This determines how long a session remains active without activity before being terminated.",  # noqa: E501
    ],
    session_configuration_type: Annotated[
        str,
        "Specify session configuration type: 'mobile', 'web', or a comma-separated list of both.",
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'updateSessionConfigurations'."]:
    """Create or update session configurations in PagerDuty.

    This tool is used to create or update session configurations for a PagerDuty account. Changes will apply immediately to new sessions, and existing sessions of specified types will be revoked. Early access is required, and scoped OAuth with `session_configurations.write` permission is necessary."""  # noqa: E501
    request_data: Any = {
        "session_configuration": {
            "absolute_session_ttl": absolute_session_time_to_live_seconds,
            "idle_session_ttl": idle_session_time_to_live,
        }
    }
    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="https://api.pagerduty.com/session_configurations",
        method="PUT",
        params=remove_none_values({"type": session_configuration_type}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def delete_pagerduty_session_configurations(
    context: ToolContext,
    session_configuration_type: Annotated[
        str,
        "Specify 'mobile', 'web', or a comma-separated list of both to define which session configurations to delete.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteSessionConfigurations'."]:
    """Delete session configurations for a PagerDuty account.

    This tool deletes specific session configurations ('mobile' or 'web') for a PagerDuty account. It should be called when there's a need to remove these configurations. The tool requires the 'session-configurations-early-access' header for early access and scoped OAuth with `session_configurations.write` permissions."""  # 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="https://api.pagerduty.com/session_configurations",
        method="DELETE",
        params=remove_none_values({"type": session_configuration_type}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_account_standards(
    context: ToolContext,
    active_standards_only: Annotated[
        bool | None,
        "Set to true to include only active standards. Set to false to include both active and inactive standards.",  # noqa: E501
    ] = None,
    resource_type_filter: Annotated[
        str | None, "Specify the type of resource to filter standards. Must be 'technical_service'."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listStandards'."]:
    """Retrieve all standards of an account.

    Use this tool to get a comprehensive list of standards associated with a PagerDuty account. Useful for understanding the compliance and operational guidelines in place. Requires OAuth scope: `standards.read`."""  # 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="https://api.pagerduty.com/standards",
        method="GET",
        params=remove_none_values({
            "active": active_standards_only,
            "resource_type": resource_type_filter,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_standard(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    standard_id: Annotated[
        str | None,
        "The unique identifier of the standard to update.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateStandard'."]:
    """Updates a standard in PagerDuty.

    Use this tool to update an existing standard in PagerDuty. Requires appropriate OAuth permissions.

    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["UPDATESTANDARD"],
            "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 standard_id:
        missing_params.append(("standard_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["UPDATESTANDARD"] + "\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["UPDATESTANDARD"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/standards/{id}".format(id=standard_id),  # noqa: UP032
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATESTANDARD"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_resource_standards(
    context: ToolContext,
    resource_ids: Annotated[
        list[str], "Array of resource IDs to which standards will be applied. Maximum of 100 items."
    ],
    resource_type: Annotated[
        str,
        "Specifies the type of resources to which the standards are applied. For example, 'technical_services'.",  # noqa: E501
    ],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'listResourceStandardsManyServices'."
]:
    """Retrieve standards applied to multiple resources.

    Use this tool to get a list of standards applied to a specified set of resources. It requires scoped OAuth permission `standards.read` and is useful for obtaining compliance information or resource evaluations."""  # 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="https://api.pagerduty.com/standards/scores/{resource_type}".format(  # noqa: UP032
            resource_type=resource_type
        ),
        method="GET",
        params=remove_none_values({"ids": resource_ids}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_resource_standards(
    context: ToolContext,
    resource_id: Annotated[
        str, "The ID of the resource for which you want to list the applied standards."
    ],
    resource_type: Annotated[
        str,
        "Specify the type of resource to which standards are applied, such as 'technical_services'.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listResourceStandards'."]:
    """Retrieve standards applied to a specified resource on PagerDuty.

    Use this tool to get a list of standards that are applied to a specified resource type and ID on PagerDuty. Requires 'standards.read' OAuth scope."""  # 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="https://api.pagerduty.com/standards/scores/{resource_type}/{id}".format(  # noqa: UP032
            id=resource_id, resource_type=resource_type
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_status_dashboards(
    context: ToolContext,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listStatusDashboards'."]:
    """Retrieve all custom Status Dashboard views for your account.

    Use this tool to get an overview of all Status Dashboard views configured in your PagerDuty account. Useful for monitoring and management 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="https://api.pagerduty.com/status_dashboards",
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_status_dashboard(
    context: ToolContext,
    status_dashboard_id: Annotated[
        str, "The unique ID of the PagerDuty status dashboard to retrieve."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getStatusDashboardById'."]:
    """Retrieve PagerDuty status dashboard details by ID.

    Use this tool to get detailed information about a specific PagerDuty status dashboard using its unique ID. This can be helpful for monitoring and analysis of service 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="https://api.pagerduty.com/status_dashboards/{id}".format(id=status_dashboard_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_impacted_services_dashboard(
    context: ToolContext,
    status_dashboard_id: Annotated[
        str, "The ID of the Status Dashboard to fetch impacted Business Services for."
    ],
    include_additional_fields: Annotated[
        str | None,
        "Specify additional fields to include, like highest impacting priority or total impacted count. Use values: 'services.highest_impacting_priority' or 'total_impacted_count'.",  # noqa: E501
    ] = None,
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'getStatusDashboardServiceImpactsById'."
]:
    """Get most impacted Business Services for a Status Dashboard.

    Use this tool to retrieve the most impacted Business Services for a specific Status Dashboard by ID. It returns a list sorted by impact level, recency, and name, up to a limit of 200 services."""  # 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="https://api.pagerduty.com/status_dashboards/{id}/service_impacts".format(  # noqa: UP032
            id=status_dashboard_id
        ),
        method="GET",
        params=remove_none_values({"additional_fields[]": include_additional_fields}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_status_dashboard_by_slug(
    context: ToolContext,
    status_dashboard_url_slug: Annotated[
        str,
        "The URL slug for a status dashboard, typically a dash-separated string like 'dash-separated-string'. Used to identify a specific dashboard in PagerDuty.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getStatusDashboardByUrlSlug'."]:
    """Retrieve a PagerDuty Status Dashboard by its URL slug.

    Use this tool to get details of a custom Status Dashboard in PagerDuty using the URL slug. Ideal for accessing human-readable dashboard references."""  # 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="https://api.pagerduty.com/status_dashboards/url_slugs/{url_slug}".format(  # noqa: UP032
            url_slug=status_dashboard_url_slug
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_service_impacts_by_url_slug(
    context: ToolContext,
    status_dashboard_url_slug: Annotated[
        str, "The URL slug for the specific status dashboard to retrieve service impacts from."
    ],
    include_additional_fields: Annotated[
        str | None,
        "Specify whether to include additional fields such as highest impacting priority and total impacted count. Choose from 'services.highest_impacting_priority' or 'total_impacted_count'.",  # noqa: E501
    ] = None,
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'getStatusDashboardServiceImpactsByUrlSlug'."
]:
    """Retrieve impacted business services from a status dashboard.

    Use this tool to obtain business service impact details for status dashboards using a specific `url_slug`. It returns a sorted list of the most impacted services, limited to 200 entries."""  # 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="https://api.pagerduty.com/status_dashboards/url_slugs/{url_slug}/service_impacts".format(  # noqa: UP032
            url_slug=status_dashboard_url_slug
        ),
        method="GET",
        params=remove_none_values({"additional_fields[]": include_additional_fields}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_status_pages(
    context: ToolContext,
    status_page_type: Annotated[
        str | None, "Specifies the type of the status page. Must be 'public' or 'private'."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listStatusPages'."]:
    """Retrieve a list of status pages.

    Use this tool to get a list of status pages. Requires `status_pages.read` OAuth scope."""
    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="https://api.pagerduty.com/status_pages",
        method="GET",
        params=remove_none_values({"status_page_type": status_page_type}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_status_page_impacts(
    context: ToolContext,
    status_page_id: Annotated[str, "The ID of the status page to retrieve impacts for."],
    filter_by_post_type: Annotated[
        str | None, "Specify the type of posts to filter by: 'incident' or 'maintenance'."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listStatusPageImpacts'."]:
    """Retrieve impacts for a specified status page by ID.

    Use this tool to fetch a list of impacts affecting a particular status page. This is helpful for monitoring and managing service disruptions and their effects. Ensure the necessary OAuth scope `status_pages.read` is granted to access the 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="https://api.pagerduty.com/status_pages/{id}/impacts".format(id=status_page_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({"post_type": filter_by_post_type}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_status_page_impact(
    context: ToolContext,
    status_page_id: Annotated[
        str, "The ID of the status page resource to retrieve impact details for."
    ],
    status_page_impact_id: Annotated[
        str,
        "The unique identifier for the Status Page Impact. Use this to fetch specific impact details.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getStatusPageImpact'."]:
    """Retrieve impact details for a specific status page.

    This tool retrieves impact information for a given status page using the status page ID and impact ID. It should be called when detailed impact data is needed for specific status pages. Requires `status_pages.read` OAuth scope."""  # 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="https://api.pagerduty.com/status_pages/{id}/impacts/{impact_id}".format(  # noqa: UP032
            id=status_page_id, impact_id=status_page_impact_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_status_page_services(
    context: ToolContext,
    status_page_id: Annotated[
        str, "The unique identifier of the Status Page to retrieve associated services."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listStatusPageServices'."]:
    """Retrieve services for a specific Status Page by ID.

    Use this tool to list all the services linked to a particular Status Page by providing the Status Page ID. Requires appropriate OAuth permissions."""  # 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="https://api.pagerduty.com/status_pages/{id}/services".format(id=status_page_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_status_page_service(
    context: ToolContext,
    resource_id: Annotated[str, "The ID of the status page resource to fetch the service for."],
    status_page_service_id: Annotated[
        str, "The unique identifier of the Status Page service to be retrieved."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getStatusPageService'."]:
    """Get service details for a status page by ID and service ID.

    Fetches and returns details of a specific service associated with a given status page using the status page ID and service ID. Useful for monitoring or auditing service statuses on PagerDuty status pages."""  # 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="https://api.pagerduty.com/status_pages/{id}/services/{service_id}".format(  # noqa: UP032
            id=resource_id, service_id=status_page_service_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_status_page_severities(
    context: ToolContext,
    status_page_id: Annotated[
        str, "The unique identifier for the status page to retrieve severities."
    ],
    post_type_filter: Annotated[
        str | None, "Specify the type of post to filter. Options: 'incident' or 'maintenance'."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listStatusPageSeverities'."]:
    """Retrieve severities for a specified status page.

    Use this tool to get a list of severities associated with a specific status page by providing its ID. Requires `status_pages.read` permissions."""  # 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="https://api.pagerduty.com/status_pages/{id}/severities".format(id=status_page_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({"post_type": post_type_filter}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_status_page_severity(
    context: ToolContext,
    status_page_id: Annotated[str, "The unique identifier for the status page resource."],
    status_page_severity_id: Annotated[
        str,
        "The unique identifier for the specific severity on a status page. Used to fetch severity details.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getStatusPageSeverity'."]:
    """Retrieve severity details for a status page using IDs.

    This tool fetches the severity information for a given status page by using the status page ID and severity ID. It's useful for monitoring and managing incident details."""  # 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="https://api.pagerduty.com/status_pages/{id}/severities/{severity_id}".format(  # noqa: UP032
            id=status_page_id, severity_id=status_page_severity_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_status_page_statuses(
    context: ToolContext,
    status_page_id: Annotated[str, "The unique ID of the status page to retrieve statuses for."],
    filter_by_post_type: Annotated[
        str | None, "Filter statuses by post type. Options include 'incident' or 'maintenance'."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listStatusPageStatuses'."]:
    """Retrieve statuses for a specific status page by ID.

    Use this tool to list the statuses of a status page using its ID. This requires the `status_pages.read` OAuth scope."""  # 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="https://api.pagerduty.com/status_pages/{id}/statuses".format(id=status_page_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({"post_type": filter_by_post_type}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_status_page_status(
    context: ToolContext,
    resource_id: Annotated[str, "The unique identifier for the resource to fetch the status for."],
    status_page_status_id: Annotated[
        str,
        "The ID of the Status Page status to retrieve. This is required to specify which status is being queried.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getStatusPageStatus'."]:
    """Retrieve the status of a status page by ID and status ID.

    Use this tool to get the current status of a specific status page by providing the page ID and status ID. Useful for monitoring and analyzing the current operational status of services."""  # 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="https://api.pagerduty.com/status_pages/{id}/statuses/{status_id}".format(  # noqa: UP032
            id=resource_id, status_id=status_page_status_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_status_page_posts(
    context: ToolContext,
    status_page_id: Annotated[str, "The unique ID of the status page to retrieve posts from."],
    filter_by_post_type: Annotated[
        str | None, "Filter posts by type. Acceptable values are 'incident' or 'maintenance'."
    ] = None,
    filter_by_reviewed_status: Annotated[
        str | None,
        "Filter posts by their reviewed status. Possible values are 'approved' or 'not_reviewed'.",
    ] = None,
    status_identifiers: Annotated[
        list[str] | None,
        "Filter posts by an array of status identifiers to specify which statuses to retrieve.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listStatusPagePosts'."]:
    """Retrieve posts for a specific status page using its ID.

    Use this tool to get posts associated with a given status page by providing its ID. Useful for monitoring updates and information shared through the status 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="https://api.pagerduty.com/status_pages/{id}/posts".format(id=status_page_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({
            "post_type": filter_by_post_type,
            "reviewed_status": filter_by_reviewed_status,
            "status[]": status_identifiers,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_status_page_post(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    status_page_id: Annotated[
        str | None,
        "The unique identifier for the status page to which the post will be added.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'createStatusPagePost'."]:
    """Create a status page post using a specific page ID.

    This tool is used to create a post on a status page identified by its ID. Useful for updating status pages with the latest information. Requires `status_pages.write` permission.

    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["CREATESTATUSPAGEPOST"],
            "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 status_page_id:
        missing_params.append(("status_page_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["CREATESTATUSPAGEPOST"] + "\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["CREATESTATUSPAGEPOST"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/status_pages/{id}/posts".format(id=status_page_id),  # noqa: UP032
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATESTATUSPAGEPOST"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_status_page_post(
    context: ToolContext,
    status_page_id: Annotated[str, "The ID of the status page resource to retrieve the post from."],
    status_page_post_id: Annotated[
        str, "The unique identifier for the Status Page Post to retrieve details."
    ],
    include_models: Annotated[
        list[str] | None, "Array of model names to include in the response for additional detail."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getStatusPagePost'."]:
    """Retrieve a post from a specific status page.

    Use this tool to fetch detailed information about a specific post on a status page using the status page ID and post 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="https://api.pagerduty.com/status_pages/{id}/posts/{post_id}".format(  # noqa: UP032
            id=status_page_id, post_id=status_page_post_id
        ),
        method="GET",
        params=remove_none_values({"include[]": include_models}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_status_page_post(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The ID of the status page resource to be updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    status_page_post_id: Annotated[
        str | None,
        "The ID of the status page post to update.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateStatusPagePost'."]:
    """Update a post on a status page by its ID.

    Use this tool to update an existing post on a specific status page. Requires the status pages write permission.

    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["UPDATESTATUSPAGEPOST"],
            "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 resource_id:
        missing_params.append(("resource_id", "path"))
    if not status_page_post_id:
        missing_params.append(("status_page_post_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["UPDATESTATUSPAGEPOST"] + "\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["UPDATESTATUSPAGEPOST"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/status_pages/{id}/posts/{post_id}".format(  # noqa: UP032
            id=resource_id, post_id=status_page_post_id
        ),
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATESTATUSPAGEPOST"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def delete_status_page_post(
    context: ToolContext,
    status_page_id: Annotated[
        str, "The unique identifier for the status page from which the post will be deleted."
    ],
    status_page_post_id: Annotated[
        str, "The unique identifier for the Status Page Post to be deleted."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteStatusPagePost'."]:
    """Delete a post from a status page using its ID.

    Use this tool to delete a specific post from a status page by providing the status page ID and post ID. Requires appropriate OAuth permissions."""  # 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="https://api.pagerduty.com/status_pages/{id}/posts/{post_id}".format(  # noqa: UP032
            id=status_page_id, post_id=status_page_post_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_status_updates(
    context: ToolContext,
    resource_id: Annotated[
        str, "The unique ID of the status page resource for which updates are needed."
    ],
    status_page_post_id: Annotated[
        str,
        "The ID of the specific status page post to retrieve updates for. This identifies which post's updates will be listed.",  # noqa: E501
    ],
    filter_by_reviewed_status: Annotated[
        str | None,
        "Filter post updates by their reviewed status. Options are 'approved' or 'not_reviewed'.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listStatusPagePostUpdates'."]:
    """Retrieve post updates for a specific status page and post ID.

    This tool retrieves a list of post updates for a given status page and post ID. It should be called when you need detailed updates for a specific post on a status page. Requires appropriate OAuth permissions."""  # 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="https://api.pagerduty.com/status_pages/{id}/posts/{post_id}/post_updates".format(  # noqa: UP032
            id=resource_id, post_id=status_page_post_id
        ),
        method="GET",
        params=remove_none_values({"reviewed_status": filter_by_reviewed_status}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_status_page_post_update(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The unique identifier of the resource you are targeting.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    status_page_post_id: Annotated[
        str | None,
        "The ID of the Status Page Post for which the update is created.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'createStatusPagePostUpdate'."]:
    """Create a post update for a specific status page post.

    This tool creates an update for a post on a status page by providing the post ID. Use it to communicate changes or progress in ongoing incidents or updates.

    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["CREATESTATUSPAGEPOSTUPDATE"],
            "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 resource_id:
        missing_params.append(("resource_id", "path"))
    if not status_page_post_id:
        missing_params.append(("status_page_post_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["CREATESTATUSPAGEPOSTUPDATE"]
                + "\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["CREATESTATUSPAGEPOSTUPDATE"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/status_pages/{id}/posts/{post_id}/post_updates".format(  # noqa: UP032
            id=resource_id, post_id=status_page_post_id
        ),
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATESTATUSPAGEPOSTUPDATE"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_post_update(
    context: ToolContext,
    post_update_id: Annotated[
        str, "The ID of the Status Page Post Update required for fetching specific update details."
    ],
    resource_id: Annotated[
        str, "The unique identifier for the resource to retrieve the post update."
    ],
    status_page_post_id: Annotated[
        str, "The unique identifier for the Status Page Post to retrieve updates for."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getPostUpdate'."]:
    """Retrieve specific post updates by post and update IDs.

    Use this tool to get detailed information about a specific post update from a status page, using the specified post and update IDs. Scoped OAuth with `status_pages.read` is required."""  # 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="https://api.pagerduty.com/status_pages/{id}/posts/{post_id}/post_updates/{post_update_id}".format(  # noqa: UP032
            id=resource_id, post_id=status_page_post_id, post_update_id=post_update_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def modify_status_page_post_update(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The unique identifier for the resource to be updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    status_page_post_id: Annotated[
        str | None,
        "The unique ID of the Status Page Post to be updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    status_page_post_update_id: Annotated[
        str | None,
        "The unique identifier for the specific status page post update to be modified.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateStatusPagePostUpdate'."]:
    """Update a specific status page post update.

    Use this tool to update details of a specific status page post by providing the required Post ID and Post Update ID. Appropriate for modifying existing post updates.

    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["MODIFYSTATUSPAGEPOSTUPDATE"],
            "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 resource_id:
        missing_params.append(("resource_id", "path"))
    if not status_page_post_id:
        missing_params.append(("status_page_post_id", "path"))
    if not status_page_post_update_id:
        missing_params.append(("status_page_post_update_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["MODIFYSTATUSPAGEPOSTUPDATE"]
                + "\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["MODIFYSTATUSPAGEPOSTUPDATE"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/status_pages/{id}/posts/{post_id}/post_updates/{post_update_id}".format(  # noqa: UP032
            id=resource_id, post_id=status_page_post_id, post_update_id=status_page_post_update_id
        ),
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["MODIFYSTATUSPAGEPOSTUPDATE"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def delete_status_page_post_update(
    context: ToolContext,
    resource_id: Annotated[str, "The unique ID of the resource to be deleted."],
    status_page_post_id: Annotated[
        str, "The ID of the Status Page Post to identify the specific post."
    ],
    status_page_post_update_id: Annotated[
        str, "The unique ID of the status page post update to delete."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteStatusPagePostUpdate'."]:
    """Delete a specific post update on PagerDuty.

    Use this tool to delete a post update for a specific post on PagerDuty's status page by providing the post ID and post update ID. Requires appropriate OAuth permissions."""  # 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="https://api.pagerduty.com/status_pages/{id}/posts/{post_id}/post_updates/{post_update_id}".format(  # noqa: UP032
            id=resource_id, post_id=status_page_post_id, post_update_id=status_page_post_update_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_postmortem_by_post_id(
    context: ToolContext,
    resource_id: Annotated[
        str,
        "The unique identifier for the resource. Used to retrieve the specific postmortem information.",  # noqa: E501
    ],
    status_page_post_id: Annotated[
        str, "The ID of the Status Page Post to retrieve postmortem details."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getPostmortem'."]:
    """Retrieve postmortem details using post ID.

    Use this tool to get detailed postmortem information for a specific post using its Post ID on PagerDuty. This is useful for obtaining insights and summaries related to incidents."""  # 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="https://api.pagerduty.com/status_pages/{id}/posts/{post_id}/postmortem".format(  # noqa: UP032
            id=resource_id, post_id=status_page_post_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_status_page_postmortem(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The unique ID of the resource for which the postmortem is being created.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    status_page_post_id: Annotated[
        str | None,
        "The unique identifier of the status page post for which the postmortem is being created.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'createStatusPagePostmortem'."]:
    """Create a postmortem for a status page post.

    Use this tool to generate a detailed postmortem for a specific status page post using its post ID. Requires appropriate access permissions.

    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["CREATESTATUSPAGEPOSTMORTEM"],
            "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 resource_id:
        missing_params.append(("resource_id", "path"))
    if not status_page_post_id:
        missing_params.append(("status_page_post_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["CREATESTATUSPAGEPOSTMORTEM"]
                + "\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["CREATESTATUSPAGEPOSTMORTEM"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/status_pages/{id}/posts/{post_id}/postmortem".format(  # noqa: UP032
            id=resource_id, post_id=status_page_post_id
        ),
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATESTATUSPAGEPOSTMORTEM"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_status_page_postmortem(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The unique ID of the resource to be updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    status_page_post_id: Annotated[
        str | None,
        "The ID of the Status Page Post to be updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateStatusPagePostmortem'."]:
    """Update a postmortem for a specific post by ID.

    This tool updates a postmortem for a given post on a status page using the post ID. It requires the 'status_pages.write' scope for OAuth authorization.

    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["UPDATESTATUSPAGEPOSTMORTEM"],
            "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 resource_id:
        missing_params.append(("resource_id", "path"))
    if not status_page_post_id:
        missing_params.append(("status_page_post_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["UPDATESTATUSPAGEPOSTMORTEM"]
                + "\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["UPDATESTATUSPAGEPOSTMORTEM"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/status_pages/{id}/posts/{post_id}/postmortem".format(  # noqa: UP032
            id=resource_id, post_id=status_page_post_id
        ),
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATESTATUSPAGEPOSTMORTEM"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def delete_postmortem(
    context: ToolContext,
    resource_id: Annotated[str, "The unique identifier of the resource to delete."],
    status_page_post_id: Annotated[
        str, "The unique identifier for the status page post whose postmortem you want to delete."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteStatusPagePostmortem'."]:
    """Deletes a postmortem from a status page post by ID.

    Use this tool to remove a postmortem linked to a specific status page post using the post's ID. This operation requires scoped OAuth with `status_pages.write` permission."""  # 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="https://api.pagerduty.com/status_pages/{id}/posts/{post_id}/postmortem".format(  # noqa: UP032
            id=resource_id, post_id=status_page_post_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_status_page_subscriptions(
    context: ToolContext,
    status_page_id: Annotated[
        str,
        "The unique identifier for the status page. Required to retrieve subscriptions associated with it.",  # noqa: E501
    ],
    subscription_channel_filter: Annotated[
        str | None, "Specify the channel to filter subscriptions. Options: webhook, email, slack."
    ] = None,
    subscription_status_filter: Annotated[
        str | None, "Filter the list of subscriptions by their status: 'active' or 'pending'."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listStatusPageSubscriptions'."]:
    """Retrieve subscriptions for a specific status page by ID.

    Use this tool to get a list of subscriptions associated with a specific status page by providing the status page ID. Useful for managing or viewing existing subscriptions on the 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="https://api.pagerduty.com/status_pages/{id}/subscriptions".format(id=status_page_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({
            "status": subscription_status_filter,
            "channel": subscription_channel_filter,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_status_page_subscription(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    status_page_id: Annotated[
        str | None,
        "The ID of the status page to subscribe to. This string is used to identify the specific page.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'createStatusPageSubscription'."]:
    """Subscribe to a status page by ID.

    Use this tool to create a subscription for a specific status page using its ID. Requires appropriate OAuth permissions.

    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["CREATESTATUSPAGESUBSCRIPTION"],
            "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 status_page_id:
        missing_params.append(("status_page_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["CREATESTATUSPAGESUBSCRIPTION"]
                + "\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["CREATESTATUSPAGESUBSCRIPTION"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/status_pages/{id}/subscriptions".format(id=status_page_id),  # noqa: UP032
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATESTATUSPAGESUBSCRIPTION"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_status_page_subscription(
    context: ToolContext,
    resource_id: Annotated[
        str, "The unique ID of the status page resource to retrieve the subscription details."
    ],
    status_page_subscription_id: Annotated[
        str, "The unique identifier for the Status Page subscription."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getStatusPageSubscription'."]:
    """Retrieve a status page subscription by ID.

    Fetch details of a specific subscription linked to a status page using the status page ID and subscription ID. This tool requires relevant OAuth permissions to access the 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="https://api.pagerduty.com/status_pages/{id}/subscriptions/{subscription_id}".format(  # noqa: UP032
            id=resource_id, subscription_id=status_page_subscription_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def delete_status_page_subscription(
    context: ToolContext,
    resource_id: Annotated[
        str, "The unique identifier of the status page resource to delete the subscription from."
    ],
    status_page_subscription_id: Annotated[
        str, "The unique identifier for the specific status page subscription to be deleted."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteStatusPageSubscription'."]:
    """Delete a status page subscription by ID.

    Use this tool to delete a subscription for a specific status page by providing the status page ID and subscription ID. It requires the 'status_pages.write' permission with scoped OAuth."""  # 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="https://api.pagerduty.com/status_pages/{id}/subscriptions/{subscription_id}".format(  # noqa: UP032
            id=resource_id, subscription_id=status_page_subscription_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_account_tags(
    context: ToolContext,
    include_total_in_pagination: Annotated[
        bool | None,
        "Set to true to include the total number of results in the pagination response. Defaults to false for faster response without total.",  # noqa: E501
    ] = False,
    pagination_offset: Annotated[
        int | None,
        "Offset to start pagination search results. Use this to specify the starting point for retrieval when paginating through results.",  # noqa: E501
    ] = None,
    results_per_page: Annotated[int | None, "The number of results to display per page."] = None,
    tag_filter_query: Annotated[
        str | None, "Filters the results to show only tags whose labels match this query string."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listTags'."]:
    """Retrieve all tags for your account.

    This tool retrieves a list of all tags associated with your account, which can be applied to Escalation Policies, Teams, or Users. Use this tool to manage or filter these entities based on tags."""  # 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="https://api.pagerduty.com/tags",
        method="GET",
        params=remove_none_values({
            "limit": results_per_page,
            "offset": pagination_offset,
            "total": include_total_in_pagination,
            "query": tag_filter_query,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_tag(
    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 'createTags'."]:
    """Create a tag for filtering in PagerDuty.

    This tool is used to create a new tag in PagerDuty. Tags can be applied to escalation policies, teams, or users to facilitate filtering. Use this tool when you need to organize or categorize these entities by tags.

    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["CREATETAG"],
            "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["CREATETAG"] + "\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["CREATETAG"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/tags",
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATETAG"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_tag_details(
    context: ToolContext,
    resource_id: Annotated[str, "The unique ID of the PagerDuty Tag to retrieve details for."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getTag'."]:
    """Retrieve details about a specific PagerDuty Tag.

    Use this tool to obtain details about a specific Tag in PagerDuty, which can be associated with Escalation Policies, Teams, or Users for filtering 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="https://api.pagerduty.com/tags/{id}".format(id=resource_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def remove_tag(
    context: ToolContext,
    resource_id: Annotated[str, "The unique identifier of the resource (tag) to be removed."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteTag'."]:
    """Remove an existing tag from escalation policies, teams, or users.

    This tool removes an existing tag applied to escalation policies, teams, or users in PagerDuty. Use this when you need to delete a tag for organizational or operational 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="https://api.pagerduty.com/tags/{id}".format(id=resource_id),  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_tags_by_entity(
    context: ToolContext,
    entity_type: Annotated[
        str,
        "Specify the type of entity related to the tag. Options: 'users', 'teams', or 'escalation_policies'.",  # noqa: E501
    ],
    resource_id: Annotated[
        str, "The unique identifier of the resource to retrieve related entities for a tag."
    ],
    include_total_in_pagination: Annotated[
        bool | None,
        "Set to true to include the total count of results in pagination responses, which may impact response times.",  # noqa: E501
    ] = False,
    pagination_offset: Annotated[
        int | None, "Offset to start pagination of search results."
    ] = None,
    results_per_page: Annotated[
        int | None, "Specify the number of results to return per page."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getTagsByEntityType'."]:
    """Retrieve related entities for a specific tag.

    Call this tool to get users, teams, or escalation policies related to a specific tag. Useful for filtering entities by tags. Appropriate for scenarios where you need to understand what entities a particular tag is associated with."""  # 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="https://api.pagerduty.com/tags/{id}/{entity_type}".format(  # noqa: UP032
            id=resource_id, entity_type=entity_type
        ),
        method="GET",
        params=remove_none_values({
            "limit": results_per_page,
            "offset": pagination_offset,
            "total": include_total_in_pagination,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_new_team(
    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 'createTeam'."]:
    """Create a new team with users and escalation policies.

    This tool should be called to create a new team within an organization in PagerDuty. A team includes a collection of users and escalation policies. Requires proper OAuth scope for execution.

    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["CREATENEWTEAM"],
            "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["CREATENEWTEAM"] + "\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["CREATENEWTEAM"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/teams",
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATENEWTEAM"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_pagerduty_teams(
    context: ToolContext,
    filter_by_name_query: Annotated[
        str | None,
        "Specify a query to filter teams by name. Only teams with names matching this query will be returned.",  # noqa: E501
    ] = None,
    include_total_in_response: Annotated[
        bool | None,
        "Set to true to include the total count of results in the response for pagination. This may impact response time.",  # noqa: E501
    ] = False,
    pagination_offset: Annotated[
        int | None, "Offset to start returning team results from in pagination."
    ] = None,
    results_per_page: Annotated[
        int | None, "Specify the number of teams to return per page."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listTeams'."]:
    """Retrieve a list of teams from your PagerDuty account.

    This tool retrieves a list of teams from your PagerDuty account, possibly filtered by a search query. Teams comprise users and escalation policies representing organizational groups. Use this tool to get insights into team structures and members."""  # 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="https://api.pagerduty.com/teams",
        method="GET",
        params=remove_none_values({
            "limit": results_per_page,
            "offset": pagination_offset,
            "total": include_total_in_response,
            "query": filter_by_name_query,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_team_details(
    context: ToolContext,
    team_id: Annotated[str, "The unique ID of the team to retrieve information for."],
    include_additional_models: Annotated[
        str | None, "Specify additional models like 'privileges' to include in the response."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getTeam'."]:
    """Retrieve details about a specified team.

    Fetches information about an existing team, which includes users and escalation policies. Useful for understanding team composition and responsibilities within an organization."""  # 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="https://api.pagerduty.com/teams/{id}".format(id=team_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({"include[]": include_additional_models}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def delete_team_in_pagerduty(
    context: ToolContext,
    team_id: Annotated[str, "The unique identifier of the team to be deleted in PagerDuty."],
    reassignment_team_id: Annotated[
        str | None,
        "The ID of the team to reassign unresolved incidents. If omitted, incidents will become account-level.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteTeam'."]:
    """Delete an existing team in PagerDuty.

    This tool removes an existing team in PagerDuty if it has no associated Escalation Policies, Services, Schedules, and Subteams. Unresolved incidents will be reassigned or become account-level."""  # 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="https://api.pagerduty.com/teams/{id}".format(id=team_id),  # noqa: UP032
        method="DELETE",
        params=remove_none_values({"reassignment_team": reassignment_team_id}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_team(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    team_id: Annotated[
        str | None,
        "The unique identifier of the team to be updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateTeam'."]:
    """Update the details of an existing team.

    Use this tool to modify the information of an existing team, which includes users and escalation policies within an organization. Ideal for updating team configurations in response to organizational changes.

    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["UPDATETEAM"],
            "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 team_id:
        missing_params.append(("team_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["UPDATETEAM"] + "\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["UPDATETEAM"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/teams/{id}".format(id=team_id),  # noqa: UP032
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATETEAM"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_latest_team_audit_records(
    context: ToolContext,
    resource_id: Annotated[
        str,
        "The unique identifier of the team or resource for which you want to retrieve audit records. This ID specifies which team's audit records to retrieve.",  # noqa: E501
    ],
    end_date_for_search_range: Annotated[
        str | None,
        "The end date of the search range. Defaults to current date if not specified, and must be within 31 days of the 'since' date.",  # noqa: E501
    ] = None,
    next_results_cursor: Annotated[
        str | None,
        "Cursor for fetching the next set of results. Obtained from the `next_cursor` of a previous request. Starts from the beginning if not provided.",  # noqa: E501
    ] = None,
    number_of_records_limit: Annotated[
        int | None, "Specify the maximum number of audit records to retrieve in the request."
    ] = None,
    start_date_range: Annotated[
        str | None,
        "The date from which to start searching audit records. Defaults to 24 hours ago if not specified.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listTeamsAuditRecords'."]:
    """Retrieve the latest audit records for a specific team.

    Use this tool to get a sorted list of the most recent audit records for a team, from newest to oldest. This is useful for monitoring team activities and changes. For handling large data sets, utilize cursor-based pagination as detailed in PagerDuty's documentation."""  # 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="https://api.pagerduty.com/teams/{id}/audit/records".format(id=resource_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({
            "limit": number_of_records_limit,
            "cursor": next_results_cursor,
            "since": start_date_range,
            "until": end_date_for_search_range,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def remove_team_escalation_policy(
    context: ToolContext,
    escalation_policy_id: Annotated[
        str, "The identifier of the escalation policy to remove from the team."
    ],
    resource_id: Annotated[
        str,
        "The unique identifier of the team resource from which the escalation policy will be removed.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteTeamEscalationPolicy'."]:
    """Remove an escalation policy from a team.

    This tool removes an escalation policy from a specific team in PagerDuty. It's useful when you need to alter team configurations by deleting unnecessary or outdated escalation policies."""  # 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="https://api.pagerduty.com/teams/{id}/escalation_policies/{escalation_policy_id}".format(  # noqa: UP032
            id=resource_id, escalation_policy_id=escalation_policy_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def add_escalation_policy_to_team(
    context: ToolContext,
    escalation_policy_id: Annotated[
        str,
        "The ID of the escalation policy to be added to the team. Ensure it is a valid policy ID within your organization.",  # noqa: E501
    ],
    team_resource_id: Annotated[
        str, "The unique identifier for the team resource to update with an escalation policy."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'updateTeamEscalationPolicy'."]:
    """Add an escalation policy to a team.

    This tool adds an escalation policy to a specified team within an organization. It is useful for managing team response structures and assigning appropriate escalation policies to teams. Users should have 'teams.write' permissions to perform this update."""  # 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="https://api.pagerduty.com/teams/{id}/escalation_policies/{escalation_policy_id}".format(  # noqa: UP032
            id=team_resource_id, escalation_policy_id=escalation_policy_id
        ),
        method="PUT",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_team_members(
    context: ToolContext,
    team_id: Annotated[
        str, "The unique identifier for the team whose members you want to retrieve."
    ],
    include_total_in_pagination: Annotated[
        bool | None,
        "Set to true to populate the total field in pagination responses. Default is false for faster response times.",  # noqa: E501
    ] = False,
    include_users_in_response: Annotated[
        str | None, "Include additional models such as 'users' in the team members response."
    ] = None,
    pagination_offset: Annotated[
        int | None, "Integer to set the starting point for pagination in search results."
    ] = None,
    results_per_page: Annotated[
        int | None, "Specifies the number of results to return per page."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listTeamUsers'."]:
    """Retrieve details of members in a specified team.

    Use to get information about users and escalation policies associated with a team in an organization. Requires appropriate OAuth scope."""  # 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="https://api.pagerduty.com/teams/{id}/members".format(id=team_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({
            "limit": results_per_page,
            "offset": pagination_offset,
            "total": include_total_in_pagination,
            "include[]": include_users_in_response,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_team_notification_subscriptions(
    context: ToolContext,
    team_id: Annotated[
        str,
        "The ID of the team to retrieve notification subscriptions for. This must be a valid team ID added through the notification subscriptions endpoint.",  # noqa: E501
    ],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'getTeamNotificationSubscriptions'."
]:
    """Retrieve a team's notification subscriptions from PagerDuty.

    This tool retrieves notification subscriptions for a specific team in PagerDuty. It should be called when you need to get a list of current notification subscriptions for a team that has been added through the notification subscriptions endpoint. Requires `subscribers.read` OAuth scope."""  # 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="https://api.pagerduty.com/teams/{id}/notification_subscriptions".format(id=team_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_team_notification_subscriptions(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    team_id: Annotated[
        str | None,
        "The ID of the team for which you want to create notification subscriptions. This is a required identifier.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'createTeamNotificationSubscriptions'."
]:
    """Create notification subscriptions for a specified team.

    Use this tool to create new notification subscriptions for a given team by specifying the team's ID. Requires appropriate OAuth permissions.

    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["CREATETEAMNOTIFICATIONSUBSCRIPTIONS"],
            "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 team_id:
        missing_params.append(("team_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["CREATETEAMNOTIFICATIONSUBSCRIPTIONS"]
                + "\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["CREATETEAMNOTIFICATIONSUBSCRIPTIONS"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/teams/{id}/notification_subscriptions".format(id=team_id),  # noqa: UP032
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATETEAMNOTIFICATIONSUBSCRIPTIONS"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def unsubscribe_team_notifications(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The ID of the resource to unsubscribe from notifications. This should be a string value representing the unique identifier for the specific resource.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'removeTeamNotificationSubscriptions'."
]:
    """Unsubscribe a team from specific notification subscriptions.

    Use this tool to unsubscribe a specific team from receiving notifications on specified entities. This is helpful when you need to manage or reduce notification overload for teams.

    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["UNSUBSCRIBETEAMNOTIFICATIONS"],
            "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 resource_id:
        missing_params.append(("resource_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["UNSUBSCRIBETEAMNOTIFICATIONS"]
                + "\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["UNSUBSCRIBETEAMNOTIFICATIONS"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/teams/{id}/notification_subscriptions/unsubscribe".format(  # noqa: UP032
            id=resource_id
        ),
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UNSUBSCRIBETEAMNOTIFICATIONS"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def remove_user_from_team(
    context: ToolContext,
    team_id: Annotated[str, "The ID of the team from which the user will be removed."],
    team_user_id: Annotated[str, "The ID of the user to be removed from the team in PagerDuty."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteTeamUser'."]:
    """Remove a user from a specific team in PagerDuty.

    This tool removes a specified user from a team in PagerDuty. It should be called when you need to manage team memberships by deleting a user. Requires appropriate OAuth scope 'teams.write'."""  # 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="https://api.pagerduty.com/teams/{id}/users/{user_id}".format(  # noqa: UP032
            id=team_id, user_id=team_user_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def add_user_to_team(
    context: ToolContext,
    team_id: Annotated[str, "The ID of the team to which the user will be added."],
    user_id: Annotated[
        str,
        "The unique identifier for the user to be added to the team. This ID should match a user already present in the system.",  # noqa: E501
    ],
    user_role_on_team: Annotated[
        str | None,
        "Specify the role of the user on the team. Allowed values are 'observer', 'responder', or 'manager'.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'updateTeamUser'."]:
    """Add a user to a specified team on PagerDuty.

    This tool adds a user to a specified team using PagerDuty. It should be called when you need to integrate a user within a team structure in an organization. Note that attempting to add a user with a 'read_only_user' role will result in an error. OAuth scope 'teams.write' is required."""  # noqa: E501
    request_data: Any = {"role": user_role_on_team}
    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="https://api.pagerduty.com/teams/{id}/users/{user_id}".format(  # noqa: UP032
            id=team_id, user_id=user_id
        ),
        method="PUT",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_template_list(
    context: ToolContext,
    filter_by_template_type: Annotated[
        str | None,
        "Specify the type of template to filter results by. Use this to narrow down the list to specific template types.",  # noqa: E501
    ] = "status_update",
    include_total_in_response: Annotated[
        bool | None,
        "Set to true to include the total count of templates in the response. This may affect response time.",  # noqa: E501
    ] = False,
    pagination_offset: Annotated[
        int | None,
        "Offset to start pagination search results. Define where the returned list should begin.",
    ] = None,
    results_per_page: Annotated[
        int | None,
        "The number of template results returned per page. Use this to control pagination size.",
    ] = None,
    search_template_query: Annotated[
        str | None, "Template name or description to search for in the templates list."
    ] = None,
    sort_by_field_and_direction: Annotated[
        str | None,
        "Specify the field ('name' or 'created_at') and direction ('asc' or 'desc') to sort results. Format: field:direction, defaulting to ascending.",  # noqa: E501
    ] = "created_at:asc",
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getTemplates'."]:
    """Retrieve a list of all templates on an account.

    This tool fetches all the templates available on a PagerDuty account. It should be called when you need to access or manage existing 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="https://api.pagerduty.com/templates",
        method="GET",
        params=remove_none_values({
            "limit": results_per_page,
            "offset": pagination_offset,
            "total": include_total_in_response,
            "query": search_template_query,
            "template_type": filter_by_template_type,
            "sort_by": sort_by_field_and_direction,
        }),
        headers=remove_none_values({
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            )
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_alert_template(
    context: ToolContext,
    email_body_html: Annotated[
        str | None,
        "The HTML body content for the email message to be sent as part of the template.",
    ] = None,
    email_subject: Annotated[
        str | None,
        "The subject line for the email template, which will appear as the email's subject.",
    ] = None,
    short_message_template: Annotated[
        str | None,
        "The short message for the template, used in SMS, Push notifications, Slack, etc.",
    ] = None,
    template_description: Annotated[
        str | None,
        "Provide a brief description of the template, outlining its purpose and use case.",
    ] = None,
    template_name: Annotated[
        str | None, "The name for the new template to be created in PagerDuty."
    ] = None,
    template_type: Annotated[
        str | None, "The type of template. Currently, only 'status_update' is supported."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'createTemplate'."]:
    """Create a new alert or incident template.

    Use this tool to create a new template in PagerDuty, which can be used for alerts or incidents. Requires OAuth with `templates.write` scope."""  # noqa: E501
    request_data: Any = {
        "template": {
            "template_type": template_type,
            "name": template_name,
            "description": template_description,
            "templated_fields": {
                "email_subject": email_subject,
                "email_body": email_body_html,
                "message": short_message_template,
            },
        }
    }
    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="https://api.pagerduty.com/templates",
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_template_details(
    context: ToolContext,
    template_id: Annotated[str, "The unique ID of the template to retrieve details for."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getTemplate'."]:
    """Retrieve details of a specific template using its ID.

    Use this tool to get detailed information about a specific template in your PagerDuty account. Ideal for checking template configurations or reviewing template 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="https://api.pagerduty.com/templates/{id}".format(id=template_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()
            )
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_template(
    context: ToolContext,
    resource_id: Annotated[str, "The unique identifier of the template to be updated."],
    email_body_html: Annotated[
        str | None, "The HTML content for the email body of the template."
    ] = None,
    email_subject: Annotated[
        str | None, "The subject of the email to be updated in the template."
    ] = None,
    short_message_template: Annotated[
        str | None,
        "The short message content for the template used in SMS, Push notifications, Slack, etc.",
    ] = None,
    template_description: Annotated[
        str | None,
        "Provide a brief description of the template. This helps to explain its purpose and content.",  # noqa: E501
    ] = None,
    template_name: Annotated[str | None, "The name of the template to update in PagerDuty."] = None,
    template_type: Annotated[
        str | None, "The type of template. Only 'status_update' is supported."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'updateTemplate'."]:
    """Update an existing template in PagerDuty.

    Use this tool to update an existing template in PagerDuty. Suitable when modifications to a template are required."""  # noqa: E501
    request_data: Any = {
        "template": {
            "template_type": template_type,
            "name": template_name,
            "description": template_description,
            "templated_fields": {
                "email_subject": email_subject,
                "email_body": email_body_html,
                "message": short_message_template,
            },
        }
    }
    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="https://api.pagerduty.com/templates/{id}".format(id=resource_id),  # noqa: UP032
        method="PUT",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def delete_template(
    context: ToolContext,
    template_id: Annotated[
        str,
        "The ID of the template resource to delete from the PagerDuty account. Required for deletion.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteTemplate'."]:
    """Delete a specific template on the PagerDuty account.

    Use this tool to delete a specified template from the account. Appropriate for managing and maintaining template resources in PagerDuty. Requires \"templates.write\" OAuth scope."""  # 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="https://api.pagerduty.com/templates/{id}".format(id=template_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()
            )
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def render_status_update_template(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    incident_id: Annotated[
        str | None,
        "The ID of the incident resource to render the template for.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'renderTemplate'."]:
    """Renders a status update template with given incident data.

    Use this tool to render a status update template by providing the incident ID and a status update message. This helps in generating formatted updates based on specific incident 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["RENDERSTATUSUPDATETEMPLATE"],
            "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 incident_id:
        missing_params.append(("incident_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["RENDERSTATUSUPDATETEMPLATE"]
                + "\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["RENDERSTATUSUPDATETEMPLATE"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/templates/{id}/render".format(id=incident_id),  # noqa: UP032
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["RENDERSTATUSUPDATETEMPLATE"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_template_fields(
    context: ToolContext,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getTemplateFields'."]:
    """Retrieve fields for account templates.

    Call this tool to obtain a list of fields that can be used on account templates in PagerDuty. Requires `templates.read` OAuth scope."""  # 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="https://api.pagerduty.com/templates/fields",
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_pagerduty_users(
    context: ToolContext,
    additional_models_to_include: Annotated[
        str | None,
        "Array of additional models to include in the response, such as 'contact_methods', 'notification_rules', 'teams', or 'subdomains'.",  # noqa: E501
    ] = None,
    include_total_in_response: Annotated[
        bool | None,
        "Set to true to include the total count in pagination responses, which may slow down the response time.",  # noqa: E501
    ] = False,
    pagination_offset: Annotated[
        int | None,
        "Offset to start pagination in search results. Specify the number of items to skip.",
    ] = None,
    results_per_page: Annotated[
        int | None, "Specify the number of user results to be returned per page."
    ] = None,
    team_ids: Annotated[
        list[str] | None,
        "An array of team IDs to filter the user results. Requires the account to have the 'teams' ability.",  # noqa: E501
    ] = None,
    user_name_filter: Annotated[
        str | None, "String to filter users by name in the PagerDuty account."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listUsers'."]:
    """Retrieve users from your PagerDuty account.

    Use this tool to list all users in your PagerDuty account, with the option to filter by a search query. Users are those who can interact with incidents and data within the 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="https://api.pagerduty.com/users",
        method="GET",
        params=remove_none_values({
            "query": user_name_filter,
            "team_ids[]": team_ids,
            "limit": results_per_page,
            "offset": pagination_offset,
            "total": include_total_in_response,
            "include[]": additional_models_to_include,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_pagerduty_user(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    requester_email: Annotated[
        str | None,
        "The email of a valid user associated with the account making the request.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'createUser'."]:
    """Create a new user in PagerDuty for account interaction.

    Use this tool to create a new user in a PagerDuty account. Users can interact with incidents and other data. Requires appropriate OAuth permissions.

    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["CREATEPAGERDUTYUSER"],
            "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["CREATEPAGERDUTYUSER"] + "\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["CREATEPAGERDUTYUSER"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/users",
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATEPAGERDUTYUSER"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "From": requester_email,
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_user_details(
    context: ToolContext,
    user_id: Annotated[
        str,
        "The unique identifier for the specific PagerDuty user whose details are to be retrieved.",
    ],
    additional_models_to_include: Annotated[
        str | None,
        "Specify additional models (e.g., 'contact_methods', 'notification_rules') to include in the response.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getUser'."]:
    """Retrieve details about a specific PagerDuty user.

    This tool is used to get detailed information about an existing user in a PagerDuty account. Useful for accessing user-specific data to manage interactions with incidents and other account activities."""  # 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="https://api.pagerduty.com/users/{id}".format(id=user_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({"include[]": additional_models_to_include}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def remove_user_from_pagerduty(
    context: ToolContext,
    user_id: Annotated[str, "The unique identifier of the user to be removed from PagerDuty."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteUser'."]:
    """Remove an existing user from PagerDuty.

    Use this tool to delete a user from PagerDuty. Ensure the user has no assigned incidents unless your pricing plan supports the offboarding feature. The incidents reassignment is asynchronous and may not complete before the API call returns. This tool is suitable for managing user accounts on PagerDuty."""  # 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="https://api.pagerduty.com/users/{id}".format(id=user_id),  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_pagerduty_user(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    user_id: Annotated[
        str | None,
        "The unique identifier for the user to be updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateUser'."]:
    """Update an existing PagerDuty user's information.

    Use this tool to update details of a user in a PagerDuty account. This is useful for modifying user permissions, contact information, or any other user-related data. Requires appropriate OAuth permissions.

    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["UPDATEPAGERDUTYUSER"],
            "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 user_id:
        missing_params.append(("user_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["UPDATEPAGERDUTYUSER"] + "\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["UPDATEPAGERDUTYUSER"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/users/{id}".format(id=user_id),  # noqa: UP032
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEPAGERDUTYUSER"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_user_audit_records(
    context: ToolContext,
    user_id: Annotated[
        str, "The unique identifier for the user whose audit records are being retrieved."
    ],
    end_date_range: Annotated[
        str | None,
        "The end date for searching audit records. Defaults to now and cannot exceed 31 days after `since`.",  # noqa: E501
    ] = None,
    pagination_cursor: Annotated[
        str | None,
        "Optional string to fetch the next set of results. Use the `next_cursor` from previous responses.",  # noqa: E501
    ] = None,
    result_limit: Annotated[
        int | None, "Specifies the maximum number of audit records to retrieve in a single request."
    ] = None,
    start_date: Annotated[
        str | None,
        "The start date for the search range. Defaults to 24 hours ago if not specified.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listUsersAuditRecords'."]:
    """Retrieve audit records for a specified user.

    This tool fetches audit records related to changes made to a specified user in PagerDuty. The records are ordered by the latest execution time. Use this tool to track changes to a user's account or settings."""  # 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="https://api.pagerduty.com/users/{id}/audit/records".format(id=user_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({
            "limit": result_limit,
            "cursor": pagination_cursor,
            "since": start_date,
            "until": end_date_range,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_user_contact_methods(
    context: ToolContext,
    user_id: Annotated[
        str, "The ID of the PagerDuty user whose contact methods are to be retrieved."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getUserContactMethods'."]:
    """Retrieve a user's contact methods from PagerDuty.

    Use this tool to list the contact methods associated with a specific PagerDuty user. This information is useful for interacting with incidents and other account 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="https://api.pagerduty.com/users/{id}/contact_methods".format(id=user_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_user_contact_method(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    user_id: Annotated[
        str | None,
        "The unique identifier of the user for whom the contact method is being created.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'createUserContactMethod'."]:
    """Create a new contact method for a PagerDuty user.

    This tool creates a new contact method for a specified user in PagerDuty. It's useful for updating user profiles with additional ways to be contacted regarding incidents and other important account interactions.

    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["CREATEUSERCONTACTMETHOD"],
            "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 user_id:
        missing_params.append(("user_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["CREATEUSERCONTACTMETHOD"] + "\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["CREATEUSERCONTACTMETHOD"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/users/{id}/contact_methods".format(id=user_id),  # noqa: UP032
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATEUSERCONTACTMETHOD"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_user_contact_method_info(
    context: ToolContext,
    resource_id: Annotated[
        str, "The ID of the user resource to retrieve contact method details for."
    ],
    user_contact_method_id: Annotated[
        str, "The unique identifier for a user's specific contact method in PagerDuty."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getUserContactMethod'."]:
    """Retrieve details about a user's contact method in PagerDuty.

    Use this tool to obtain information on a specific user's contact method in a PagerDuty account. It provides details necessary for interacting with user incidents and related account data. Requires appropriate OAuth scope."""  # 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="https://api.pagerduty.com/users/{id}/contact_methods/{contact_method_id}".format(  # noqa: UP032
            id=resource_id, contact_method_id=user_contact_method_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def remove_user_contact_method(
    context: ToolContext,
    contact_method_id: Annotated[
        str, "The identifier for the user's contact method to be removed from PagerDuty."
    ],
    user_resource_id: Annotated[
        str, "The ID of the user resource to identify which user the contact method belongs to."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteUserContactMethod'."]:
    """Remove a user's contact method from PagerDuty.

    Use this tool to delete a user's contact method in PagerDuty. Useful for maintaining or updating user information. Requires appropriate OAuth permissions."""  # 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="https://api.pagerduty.com/users/{id}/contact_methods/{contact_method_id}".format(  # noqa: UP032
            id=user_resource_id, contact_method_id=contact_method_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_user_contact_method(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The unique identifier of the user whose contact method is being updated. It should be a string representing the user's ID in PagerDuty.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    user_contact_method_id: Annotated[
        str | None,
        "The unique identifier for the user's contact method to update.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateUserContactMethod'."]:
    """Update a user's contact method on PagerDuty.

    This tool updates the contact method of a specified user in a PagerDuty account. It's used when changes to a user's contact information are needed, such as updating an email or phone number for receiving notifications. Ensure the correct permissions (`users:contact_methods.write`) are in place before making this call.

    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["UPDATEUSERCONTACTMETHOD"],
            "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 resource_id:
        missing_params.append(("resource_id", "path"))
    if not user_contact_method_id:
        missing_params.append(("user_contact_method_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["UPDATEUSERCONTACTMETHOD"] + "\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["UPDATEUSERCONTACTMETHOD"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/users/{id}/contact_methods/{contact_method_id}".format(  # noqa: UP032
            id=resource_id, contact_method_id=user_contact_method_id
        ),
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEUSERCONTACTMETHOD"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_user_license(
    context: ToolContext,
    user_id: Annotated[str, "The unique identifier of the user to fetch license information for."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getUserLicense'."]:
    """Retrieve the license allocated to a user.

    This tool fetches the license information assigned to a specific user in the PagerDuty system. It should be called when there is a need to know the license status or allocation for a particular user. Requires appropriate OAuth scope."""  # 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="https://api.pagerduty.com/users/{id}/license".format(id=user_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_user_notification_rules(
    context: ToolContext,
    user_resource_id: Annotated[
        str,
        "The unique identifier of the PagerDuty user whose notification rules are to be retrieved.",
    ],
    incident_urgency: Annotated[
        str | None,
        "Specify the incident urgency for the notification rules: 'high', 'low', or 'all'. Defaults to 'high'.",  # noqa: E501
    ] = None,
    include_additional_details: Annotated[
        str | None, "Specify additional details to include, such as 'contact_methods'."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getUserNotificationRules'."]:
    """Retrieve a PagerDuty user's notification rules.

    Use this tool to list the notification rules associated with a specific PagerDuty user. This can help you understand the methods and conditions under which users are notified about incidents and other account activities."""  # 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="https://api.pagerduty.com/users/{id}/notification_rules".format(id=user_resource_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({
            "include[]": include_additional_details,
            "urgency": incident_urgency,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_user_notification_rule(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    user_resource_id: Annotated[
        str | None,
        "The unique ID of the user resource for which the notification rule is being created.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'createUserNotificationRule'."]:
    """Create a new user notification rule in PagerDuty.

    Use this tool to create a new notification rule for a user in a PagerDuty account, allowing interaction with incidents and data. Requires OAuth permission: `users:contact_methods.write`.

    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["CREATEUSERNOTIFICATIONRULE"],
            "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 user_resource_id:
        missing_params.append(("user_resource_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["CREATEUSERNOTIFICATIONRULE"]
                + "\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["CREATEUSERNOTIFICATIONRULE"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/users/{id}/notification_rules".format(id=user_resource_id),  # noqa: UP032
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATEUSERNOTIFICATIONRULE"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_user_notification_rule(
    context: ToolContext,
    notification_rule_id: Annotated[
        str, "The unique identifier for the user's notification rule to be retrieved."
    ],
    user_id: Annotated[
        str,
        "The unique identifier of the user in PagerDuty. Required to fetch their notification rule.",  # noqa: E501
    ],
    include_additional_details: Annotated[
        str | None, "Specify additional details to include such as 'contact_methods'."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getUserNotificationRule'."]:
    """Retrieve details about a user's notification rule.

    This tool retrieves information about a user's notification rule in a PagerDuty account. It should be called when you need to understand how a user is notified regarding incidents. OAuth scope required: `users:contact_methods.read`."""  # 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="https://api.pagerduty.com/users/{id}/notification_rules/{notification_rule_id}".format(  # noqa: UP032
            id=user_id, notification_rule_id=notification_rule_id
        ),
        method="GET",
        params=remove_none_values({"include[]": include_additional_details}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def remove_user_notification_rule(
    context: ToolContext,
    notification_rule_identifier: Annotated[
        str,
        "The unique identifier for the notification rule to be removed from the user's profile.",
    ],
    resource_id: Annotated[str, "The ID of the user who owns the notification rule."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteUserNotificationRule'."]:
    """Remove a user's notification rule on PagerDuty.

    This tool removes a specific notification rule from a user's profile on PagerDuty. Useful for managing user notification settings within an account. Requires appropriate OAuth permissions."""  # 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="https://api.pagerduty.com/users/{id}/notification_rules/{notification_rule_id}".format(  # noqa: UP032
            id=resource_id, notification_rule_id=notification_rule_identifier
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_user_notification_rule(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The unique ID of the user's notification resource to be updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    notification_rule_id: Annotated[
        str | None,
        "The ID of the user's notification rule to update in PagerDuty.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateUserNotificationRule'."]:
    """Update a user's notification rule in PagerDuty.

    Use this tool to modify an existing notification rule for a user on a PagerDuty account, allowing them to manage how they receive incident 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["UPDATEUSERNOTIFICATIONRULE"],
            "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 resource_id:
        missing_params.append(("resource_id", "path"))
    if not notification_rule_id:
        missing_params.append(("notification_rule_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["UPDATEUSERNOTIFICATIONRULE"]
                + "\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["UPDATEUSERNOTIFICATIONRULE"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/users/{id}/notification_rules/{notification_rule_id}".format(  # noqa: UP032
            id=resource_id, notification_rule_id=notification_rule_id
        ),
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEUSERNOTIFICATIONRULE"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_user_notification_subscriptions(
    context: ToolContext,
    user_id: Annotated[
        str,
        "The unique identifier for the user whose notification subscriptions are being retrieved.",
    ],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'getUserNotificationSubscriptions'."
]:
    """Retrieve a user's notification subscriptions.

    Fetches the list of notification subscriptions for a specified user. Useful for checking what notifications a user is subscribed to. Requires that users be added through the appropriate endpoint beforehand and requires the 'subscribers.read' OAuth scope."""  # 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="https://api.pagerduty.com/users/{id}/notification_subscriptions".format(id=user_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_user_notification_subscriptions(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The unique identifier of the resource for which to create notification subscriptions.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'createUserNotificationSubscriptions'."
]:
    """Create new notification subscriptions for a user.

    This tool is used to create new notification subscriptions for a specified user on PagerDuty. It requires scoped OAuth with the `subscribers.write` permission.

    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["CREATEUSERNOTIFICATIONSUBSCRIPTIONS"],
            "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 resource_id:
        missing_params.append(("resource_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["CREATEUSERNOTIFICATIONSUBSCRIPTIONS"]
                + "\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["CREATEUSERNOTIFICATIONSUBSCRIPTIONS"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/users/{id}/notification_subscriptions".format(  # noqa: UP032
            id=resource_id
        ),
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATEUSERNOTIFICATIONSUBSCRIPTIONS"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def unsubscribe_user_notifications(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The unique identifier of the resource from which to unsubscribe the user.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'unsubscribeUserNotificationSubscriptions'."
]:
    """Unsubscribe a user from notification subscriptions.

    Use this tool to unsubscribe a specific user from notifications associated with certain entities in the system. Ideal for managing user notification preferences efficiently.

    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["UNSUBSCRIBEUSERNOTIFICATIONS"],
            "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 resource_id:
        missing_params.append(("resource_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["UNSUBSCRIBEUSERNOTIFICATIONS"]
                + "\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["UNSUBSCRIBEUSERNOTIFICATIONS"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/users/{id}/notification_subscriptions/unsubscribe".format(  # noqa: UP032
            id=resource_id
        ),
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UNSUBSCRIBEUSERNOTIFICATIONS"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_user_handoff_notification_rules(
    context: ToolContext,
    user_id: Annotated[
        str,
        "The unique identifier of the PagerDuty user whose handoff notification rules you want to retrieve.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getUserHandoffNotificationRules'."]:
    """List handoff notification rules for a PagerDuty user.

    Use this tool to retrieve the handoff notification rules for a specific user in a PagerDuty account. This can be helpful to understand how notifications are managed for user on-call handoffs."""  # 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="https://api.pagerduty.com/users/{id}/oncall_handoff_notification_rules".format(  # noqa: UP032
            id=user_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_handoff_notification_rule(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The unique identifier for the user or resource for which the handoff notification rule will be created.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'createUserHandoffNotificationRule'."
]:
    """Create a handoff notification rule for PagerDuty users.

    This tool allows you to create a new handoff notification rule for users in PagerDuty. It should be called when you need to set a notification rule for on-call handoff events for a specific user. Requires `users.write` OAuth scope.

    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["CREATEHANDOFFNOTIFICATIONRULE"],
            "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 resource_id:
        missing_params.append(("resource_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["CREATEHANDOFFNOTIFICATIONRULE"]
                + "\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["CREATEHANDOFFNOTIFICATIONRULE"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/users/{id}/oncall_handoff_notification_rules".format(  # noqa: UP032
            id=resource_id
        ),
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATEHANDOFFNOTIFICATIONRULE"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_user_handoff_notification_rule(
    context: ToolContext,
    oncall_handoff_notification_rule_id: Annotated[
        str, "The ID of the oncall handoff notification rule for the user."
    ],
    user_id: Annotated[
        str,
        "The unique identifier for the user whose handoff notification rule details are being retrieved. This is required to specify the target user in PagerDuty.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getUserHandoffNotifiactionRule'."]:
    """Fetch a user's handoff notification rule details.

    Use this tool to retrieve detailed information about a user's handoff notification rule in PagerDuty. It is useful for understanding user-specific notification settings related to on-call handoffs. Requires 'users.read' scope for OAuth."""  # 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="https://api.pagerduty.com/users/{id}/oncall_handoff_notification_rules/{oncall_handoff_notification_rule_id}".format(  # noqa: UP032
            id=user_id, oncall_handoff_notification_rule_id=oncall_handoff_notification_rule_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def delete_user_handoff_notification_rule(
    context: ToolContext,
    oncall_handoff_notification_rule_id: Annotated[
        str, "The unique ID of the on-call handoff notification rule to be deleted for the user."
    ],
    user_resource_id: Annotated[
        str,
        "The ID of the user resource to delete the handoff notification rule from. Required for identifying the user.",  # noqa: E501
    ],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'deleteUserHandoffNotificationRule'."
]:
    """Remove a handoff notification rule for a PagerDuty user.

    Use this tool to delete a specific on-call handoff notification rule for a user in a PagerDuty account. Requires appropriate OAuth permissions."""  # 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="https://api.pagerduty.com/users/{id}/oncall_handoff_notification_rules/{oncall_handoff_notification_rule_id}".format(  # noqa: UP032
            id=user_resource_id,
            oncall_handoff_notification_rule_id=oncall_handoff_notification_rule_id,
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_user_handoff_notification(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The unique ID of the resource to be updated, representing the user in PagerDuty.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    handoff_notification_rule_id: Annotated[
        str | None,
        "The ID of the oncall handoff notification rule to update for the user.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateUserHandoffNotification'."]:
    """Update a user's handoff notification rule in PagerDuty.

    This tool updates a user's handoff notification rule in a PagerDuty account. It should be called when changes to a user's notification preferences are needed, such as updating contact methods or schedules for handoff alerts. Requires `users.write` scope in OAuth.

    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["UPDATEUSERHANDOFFNOTIFICATION"],
            "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 resource_id:
        missing_params.append(("resource_id", "path"))
    if not handoff_notification_rule_id:
        missing_params.append(("handoff_notification_rule_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["UPDATEUSERHANDOFFNOTIFICATION"]
                + "\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["UPDATEUSERHANDOFFNOTIFICATION"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/users/{id}/oncall_handoff_notification_rules/{oncall_handoff_notification_rule_id}".format(  # noqa: UP032
            id=resource_id, oncall_handoff_notification_rule_id=handoff_notification_rule_id
        ),
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEUSERHANDOFFNOTIFICATION"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_user_active_sessions(
    context: ToolContext,
    user_id: Annotated[
        str, "The ID of the PagerDuty user whose active sessions are to be retrieved."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getUserSessions'."]:
    """List active sessions of a specified PagerDuty user.

    Use this tool to retrieve a list of active sessions for a specific PagerDuty user. Note that active sessions do not include newly issued OAuth tokens as of November 2021. This information is useful for managing and interacting with user access within a PagerDuty account. Requires proper OAuth scope: `users:sessions.read`."""  # 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="https://api.pagerduty.com/users/{id}/sessions".format(id=user_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_user_session_details(
    context: ToolContext,
    resource_id: Annotated[
        str, "The unique ID of the PagerDuty user whose session details you want to retrieve."
    ],
    session_type: Annotated[
        str,
        "Specifies the type of the user session. This information is required to identify the nature of the session for the user session ID.",  # noqa: E501
    ],
    user_session_id: Annotated[
        str, "The unique session ID for a specific PagerDuty user to retrieve session details."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getUserSession'."]:
    """Fetches details about a specific PagerDuty user session.

    Use this tool to retrieve details of a user's session in PagerDuty. Useful for understanding user access and activity, especially in managing incidents and data interaction within 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="https://api.pagerduty.com/users/{id}/sessions/{type}/{session_id}".format(  # noqa: UP032
            id=resource_id, type=session_type, session_id=user_session_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_user_notification_rules(
    context: ToolContext,
    user_id: Annotated[
        str,
        "The unique identifier for the PagerDuty user whose notification rules are to be retrieved.",  # noqa: E501
    ],
    include_additional_details: Annotated[
        str | None, "Specify additional details to include, such as 'contact_methods'."
    ] = None,
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'getUserStatusUpdateNotificationRules'."
]:
    """Retrieve status update notification rules for a PagerDuty user.

    This tool fetches the status update notification rules for a specified user on PagerDuty. Use it when you need to understand how a user is notified about status updates in 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="https://api.pagerduty.com/users/{id}/status_update_notification_rules".format(  # noqa: UP032
            id=user_id
        ),
        method="GET",
        params=remove_none_values({"include[]": include_additional_details}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_user_status_update_notification_rule(
    context: ToolContext,
    resource_id: Annotated[
        str, "The ID of the user resource for which the notification rule is being created."
    ],
    status_update_notification_rule: Annotated[
        dict[str, dict[str, dict[str, str]]] | None,
        "A JSON object representing the rule for contacting the user for incident status updates. It includes details like contact method and notification preferences.",  # noqa: E501
    ] = None,
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'createUserStatusUpdateNotificationRule'."
]:
    """Create a new status update notification rule for a user.

    This tool creates a new notification rule for a user's status updates in a PagerDuty account. It should be called when you need to set up or modify a user's notification settings for incident interactions. Requires user write permissions."""  # noqa: E501
    request_data: Any = status_update_notification_rule
    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="https://api.pagerduty.com/users/{id}/status_update_notification_rules".format(  # noqa: UP032
            id=resource_id
        ),
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_user_status_update_notification_rule(
    context: ToolContext,
    status_update_notification_rule_id: Annotated[
        str, "The ID of the user's status update notification rule to retrieve details for."
    ],
    user_id: Annotated[
        str,
        "The unique identifier of the user whose notification rule details are to be retrieved.",
    ],
    include_contact_methods: Annotated[
        str | None,
        "Specify 'contact_methods' to include additional contact method details in the response. Leave empty if no additional details are needed.",  # noqa: E501
    ] = None,
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'getUserStatusUpdateNotificationRule'."
]:
    """Get details about a user's status update notification rule.

    Call this tool to retrieve information regarding a specific user's notification settings for status updates within a PagerDuty account. Useful for managing or reviewing user-specific notification rules. Requires user's ID and the rule 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="https://api.pagerduty.com/users/{id}/status_update_notification_rules/{status_update_notification_rule_id}".format(  # noqa: UP032
            id=user_id, status_update_notification_rule_id=status_update_notification_rule_id
        ),
        method="GET",
        params=remove_none_values({"include[]": include_contact_methods}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def remove_user_status_update_notification_rule(
    context: ToolContext,
    resource_id: Annotated[
        str, "The unique identifier of the user whose notification rule is being deleted."
    ],
    status_update_notification_rule_id: Annotated[
        str, "The ID of the status update notification rule for a specific user in PagerDuty."
    ],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'deleteUserStatusUpdateNotificationRule'."
]:
    """Removes a user's status update notification rule in PagerDuty.

    Use this tool to delete a notification rule for status updates assigned to a specific user in PagerDuty. This is helpful for managing user notification preferences and ensuring up-to-date settings. OAuth permission 'users.write' is required."""  # 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="https://api.pagerduty.com/users/{id}/status_update_notification_rules/{status_update_notification_rule_id}".format(  # noqa: UP032
            id=resource_id, status_update_notification_rule_id=status_update_notification_rule_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_user_status_notification_rule(
    context: ToolContext,
    mode: Annotated[
        ToolMode,
        "Operation mode: 'get_request_schema' returns the OpenAPI spec "
        "for the request body, 'execute' performs the actual operation",
    ],
    resource_id: Annotated[
        str | None,
        "The unique identifier for the user resource to be updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    status_update_notification_rule_id: Annotated[
        str | None,
        "The ID of the user's status update notification rule to be updated.  Required when mode is 'execute', ignored when mode is 'get_request_schema'.",  # noqa: E501
    ] = None,
    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 'updateUserStatusUpdateNotificationRule'."
]:
    """Update a user's status update notification rule.

    Use this tool to modify the notification settings for a user's status updates in PagerDuty. Useful for managing how users receive notifications in an account. Requires appropriate OAuth permissions.

    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["UPDATEUSERSTATUSNOTIFICATIONRULE"],
            "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 resource_id:
        missing_params.append(("resource_id", "path"))
    if not status_update_notification_rule_id:
        missing_params.append(("status_update_notification_rule_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["UPDATEUSERSTATUSNOTIFICATIONRULE"]
                + "\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["UPDATEUSERSTATUSNOTIFICATIONRULE"]
                + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/users/{id}/status_update_notification_rules/{status_update_notification_rule_id}".format(  # noqa: UP032
            id=resource_id, status_update_notification_rule_id=status_update_notification_rule_id
        ),
        method="PUT",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["UPDATEUSERSTATUSNOTIFICATIONRULE"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_current_user_details(
    context: ToolContext,
    additional_models_to_include: Annotated[
        str | None,
        "Specifies additional models, such as contact methods or teams, to include in the response. Options: contact_methods, notification_rules, teams, subdomains.",  # noqa: E501
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getCurrentUser'."]:
    """Retrieves details about the current PagerDuty user.

    This tool fetches information about the current user logged into PagerDuty. It requires a user-level API key or an OAuth-generated key. Utilize this tool to obtain user details such as permissions and membership within the PagerDuty 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="https://api.pagerduty.com/users/me",
        method="GET",
        params=remove_none_values({"include[]": additional_models_to_include}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_all_vendors(
    context: ToolContext,
    include_total_in_pagination: Annotated[
        bool | None,
        "Set to true to populate the `total` field in pagination responses, which provides the total number of results but may affect performance.",  # noqa: E501
    ] = False,
    pagination_offset: Annotated[
        int | None, "Offset for starting pagination of the search results."
    ] = None,
    results_per_page: Annotated[
        int | None,
        "The maximum number of vendor results to return per page. Use to control pagination.",
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listVendors'."]:
    """Retrieve a list of all vendor integrations.

    Use this tool to get a list of all vendors representing specific types of integrations like AWS Cloudwatch, Splunk, and Datadog. Useful for viewing available integration options."""  # 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="https://api.pagerduty.com/vendors",
        method="GET",
        params=remove_none_values({
            "limit": results_per_page,
            "offset": pagination_offset,
            "total": include_total_in_pagination,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_vendor_details(
    context: ToolContext,
    vendor_id: Annotated[
        str, "The unique identifier for the vendor whose details are being requested."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getVendor'."]:
    """Fetch detailed information about a specific vendor on PagerDuty.

    Use this tool to retrieve details about a specific vendor integrated with PagerDuty, like AWS Cloudwatch, Splunk, or Datadog. Useful for understanding integration types."""  # 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="https://api.pagerduty.com/vendors/{id}".format(id=vendor_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_webhook_subscriptions(
    context: ToolContext,
    include_total_in_pagination: Annotated[
        bool | None,
        "Set to true to populate the `total` field in pagination responses. Useful if you need the total number of entries.",  # noqa: E501
    ] = False,
    pagination_offset: Annotated[
        int | None, "Offset to start the pagination of search results."
    ] = None,
    resource_filter_id: Annotated[
        str | None,
        "The ID of the resource to filter upon. Required if filtering by service or team.",
    ] = None,
    resource_filter_type: Annotated[
        str | None,
        "Specify the type of resource to filter webhook subscriptions by, such as 'account', 'service', or 'team'.",  # noqa: E501
    ] = None,
    results_per_page: Annotated[
        int | None, "Specify the number of webhook subscription results to return per page."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listWebhookSubscriptions'."]:
    """Retrieve existing webhook subscriptions from PagerDuty.

    Use this tool to list webhook subscriptions. It can filter subscriptions by service or team using `filter_type` and `filter_id` parameters. Useful for managing and configuring v3 webhooks. Requires 'webhook_subscriptions.read' permission."""  # 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="https://api.pagerduty.com/webhook_subscriptions",
        method="GET",
        params=remove_none_values({
            "limit": results_per_page,
            "offset": pagination_offset,
            "total": include_total_in_pagination,
            "filter_type": resource_filter_type,
            "filter_id": resource_filter_id,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_webhook_subscription(
    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 'createWebhookSubscription'."]:
    """Create a new webhook subscription in PagerDuty.

    This tool is used to create a new webhook subscription on PagerDuty. It should be invoked when you need to configure or integrate with v3 webhooks. Requires proper OAuth permissions.

    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["CREATEWEBHOOKSUBSCRIPTION"],
            "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["CREATEWEBHOOKSUBSCRIPTION"] + "\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["CREATEWEBHOOKSUBSCRIPTION"] + "\n```"
            ),
        ) from e

    response = await make_request_with_schema_validation(
        url="https://api.pagerduty.com/webhook_subscriptions",
        method="POST",
        request_data=request_data,
        schema=REQUEST_BODY_SCHEMAS["CREATEWEBHOOKSUBSCRIPTION"],
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_webhook_subscription_details(
    context: ToolContext,
    resource_id: Annotated[
        str, "The unique identifier of the webhook subscription to retrieve details for."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getWebhookSubscription'."]:
    """Retrieve details about a specific webhook subscription.

    Use this tool to get detailed information about an existing webhook subscription using its ID. Requires appropriate OAuth permissions."""  # 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="https://api.pagerduty.com/webhook_subscriptions/{id}".format(id=resource_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_webhook_subscription(
    context: ToolContext,
    resource_id: Annotated[str, "The unique identifier of the webhook subscription to be updated."],
    filter_object_id: Annotated[
        str | None,
        "The ID of the object used as the filter. Required unless the filter type is account_reference.",  # noqa: E501
    ] = None,
    filter_object_type: Annotated[
        str | None,
        "Specify the type of object used as the filter: 'account_reference', 'service_reference', or 'team_reference'.",  # noqa: E501
    ] = None,
    oauth_client_id: Annotated[
        str | None,
        "The ID of the OAuth client for authenticating webhook requests. This field is optional.",
    ] = None,
    send_webhook: Annotated[
        bool | None, "Set to true to send a webhook. Default is true. False to disable."
    ] = None,
    webhook_events: Annotated[
        list[str] | None, "List of outbound event types the subscription will receive."
    ] = None,
    webhook_subscription_description: Annotated[
        str | None, "A short description of the webhook subscription."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'updateWebhookSubscription'."]:
    """Update an existing webhook subscription.

    This tool updates an existing webhook subscription in PagerDuty. It should be called when you need to change any details of a webhook subscription, except for the `delivery_method`. Ensure you have the required OAuth scope: `webhook_subscriptions.write`."""  # noqa: E501
    request_data: Any = {
        "webhook_subscription": {
            "description": webhook_subscription_description,
            "events": webhook_events,
            "filter": {"id": filter_object_id, "type": filter_object_type},
            "active": send_webhook,
            "oauth_client_id": oauth_client_id,
        }
    }
    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="https://api.pagerduty.com/webhook_subscriptions/{id}".format(id=resource_id),  # noqa: UP032
        method="PUT",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def delete_webhook_subscription(
    context: ToolContext,
    resource_id: Annotated[
        str, "The unique identifier for the webhook subscription to be deleted."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteWebhookSubscription'."]:
    """Delete a webhook subscription in PagerDuty.

    Use this tool to delete a webhook subscription in PagerDuty when it is no longer needed. Ensure you have the necessary OAuth scope (`webhook_subscriptions.write`) to perform this operation."""  # 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="https://api.pagerduty.com/webhook_subscriptions/{id}".format(id=resource_id),  # noqa: UP032
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def enable_webhook_subscription(
    context: ToolContext,
    resource_id: Annotated[
        str, "The unique identifier for the webhook subscription to be enabled."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'enableWebhookSubscription'."]:
    """Enable a temporarily disabled webhook subscription.

    Use this tool to enable a webhook subscription that has been temporarily disabled due to repeated delivery method rejections by the server."""  # 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="https://api.pagerduty.com/webhook_subscriptions/{id}/enable".format(id=resource_id),  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def test_webhook_subscription(
    context: ToolContext,
    resource_id: Annotated[str, "The unique ID of the webhook subscription to be tested."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'testWebhookSubscription'."]:
    """Test a webhook subscription by firing a test event.

    This tool tests a webhook subscription by firing a `pagey.ping` event to the specified destination, ensuring the webhook is correctly configured. Requires appropriate OAuth scope."""  # 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="https://api.pagerduty.com/webhook_subscriptions/{id}/ping".format(id=resource_id),  # noqa: UP032
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_oauth_clients(
    context: ToolContext,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listOauthClients'."]:
    """Retrieve all OAuth clients for webhook subscriptions.

    Use this tool to list all OAuth clients associated with webhook subscriptions. Requires admin or owner role permissions and is limited to a maximum of 10 clients per 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="https://api.pagerduty.com/webhook_subscriptions/oauth_clients",
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_oauth_client(
    context: ToolContext,
    oauth_client_id: Annotated[str, "The OAuth client ID provided by the OAuth server."],
    oauth_client_name: Annotated[
        str,
        "A human-readable name for the OAuth client. It is used to identify the client in a user-friendly manner.",  # noqa: E501
    ],
    oauth_client_secret: Annotated[
        str, "The client secret provided by the OAuth server for the OAuth client."
    ],
    oauth_grant_type: Annotated[
        str, "The OAuth grant type. Currently, only 'client_credentials' is supported."
    ],
    oauth_token_endpoint_url: Annotated[
        str, "The URL for the OAuth token endpoint required to obtain an access token."
    ],
    oauth_scopes_requested: Annotated[
        str | None, "The OAuth scopes requested for this client."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'createOauthClient'."]:
    """Create a new OAuth client for webhook subscriptions.

    Creates an OAuth client for webhook subscriptions, with validation of client credentials. Requires admin or owner permissions and allows up to 10 clients per account."""  # noqa: E501
    request_data: Any = {
        "oauth_client": {
            "name": oauth_client_name,
            "client_id": oauth_client_id,
            "client_secret": oauth_client_secret,
            "scope": oauth_scopes_requested,
            "token_url": oauth_token_endpoint_url,
            "grant_type": oauth_grant_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="https://api.pagerduty.com/webhook_subscriptions/oauth_clients",
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_oauth_client_details(
    context: ToolContext,
    oauth_client_id: Annotated[
        str, "The unique identifier of the OAuth client to retrieve details for."
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getOauthClient'."]:
    """Retrieve details of a specific OAuth client by ID.

    This tool is used to obtain detailed information about a specific OAuth client using its ID. It requires admin or owner role permissions to access this 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="https://api.pagerduty.com/webhook_subscriptions/oauth_clients/{id}".format(  # noqa: UP032
            id=oauth_client_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_oauth_client(
    context: ToolContext,
    resource_id: Annotated[str, "The unique identifier for the OAuth client resource to update."],
    oauth_client_id: Annotated[
        str | None, "The OAuth client ID as provided by the OAuth server."
    ] = None,
    oauth_client_name: Annotated[str | None, "A human-readable name for the OAuth client."] = None,
    oauth_client_secret: Annotated[
        str | None, "The OAuth client secret provided by the OAuth server for authentication."
    ] = None,
    oauth_grant_type: Annotated[
        str | None,
        "Specifies the OAuth grant type to use, currently only 'client_credentials' is supported. Always use 'client_credentials' as input.",  # noqa: E501
    ] = None,
    oauth_scopes_requested: Annotated[
        str | None,
        "The OAuth scopes requested for this client. Provide as a space-separated string.",
    ] = None,
    oauth_token_endpoint_url: Annotated[
        str | None, "The URL for the OAuth token endpoint required for this client."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'updateOauthClient'."]:
    """Update an existing OAuth client configuration.

    This tool updates an existing OAuth client, triggering token validation with the OAuth server. Requires admin or owner role permissions."""  # noqa: E501
    request_data: Any = {
        "oauth_client": {
            "name": oauth_client_name,
            "client_id": oauth_client_id,
            "client_secret": oauth_client_secret,
            "scope": oauth_scopes_requested,
            "token_url": oauth_token_endpoint_url,
            "grant_type": oauth_grant_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="https://api.pagerduty.com/webhook_subscriptions/oauth_clients/{id}".format(  # noqa: UP032
            id=resource_id
        ),
        method="PUT",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Content-Type": "application/json",
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def delete_oauth_client(
    context: ToolContext,
    resource_id: Annotated[str, "The unique identifier of the OAuth client to be deleted."],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'deleteOauthClient'."]:
    """Delete an OAuth client from webhook subscriptions.

    This tool deletes an OAuth client and removes its association from any webhook subscriptions using it. It requires admin or owner role permissions to execute."""  # 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="https://api.pagerduty.com/webhook_subscriptions/oauth_clients/{id}".format(  # noqa: UP032
            id=resource_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_workflow_integrations(
    context: ToolContext,
    include_deprecated_integrations: Annotated[
        bool | None,
        "Set to true to include deprecated integrations in the response; false to exclude them.",
    ] = False,
    next_results_cursor: Annotated[
        str | None,
        "A string to request the next set of results, usually from the `next_cursor` field of the previous response. Defaults to starting at the beginning if not provided.",  # noqa: E501
    ] = None,
    result_limit: Annotated[
        int | None, "The limit on the number of workflow integrations to return in the response."
    ] = None,
) -> Annotated[dict[str, Any], "Response from the API endpoint 'listWorkflowIntegrations'."]:
    """Retrieve a list of available workflow integrations.

    Use this tool to obtain a list of available workflow integrations from PagerDuty. Requires specific OAuth permissions."""  # 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="https://api.pagerduty.com/workflows/integrations",
        method="GET",
        params=remove_none_values({
            "limit": result_limit,
            "cursor": next_results_cursor,
            "include_deprecated": include_deprecated_integrations,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_workflow_integration_details(
    context: ToolContext,
    resource_id: Annotated[
        str,
        "The unique identifier of the workflow integration resource in PagerDuty that you want to retrieve details for.",  # noqa: E501
    ],
) -> Annotated[dict[str, Any], "Response from the API endpoint 'getWorkflowIntegration'."]:
    """Retrieve details about a PagerDuty workflow integration.

    Use this tool to get detailed information about a specific workflow integration in PagerDuty. Useful for understanding integration configurations and parameters."""  # 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="https://api.pagerduty.com/workflows/integrations/{id}".format(id=resource_id),  # noqa: UP032
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def list_workflow_integration_connections(
    context: ToolContext,
    filter_by_partial_name: Annotated[
        str | None, "Filter integrations by a partial name match to narrow down the results."
    ] = None,
    next_results_cursor: Annotated[
        str | None,
        "Optional parameter to retrieve the next set of results from the API. Typically obtained from the previous request's `next_cursor` field. If not provided, the request starts from the beginning.",  # noqa: E501
    ] = None,
    response_limit: Annotated[
        int | None, "The maximum number of results to return for the request."
    ] = None,
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'listWorkflowIntegrationConnections'."
]:
    """Retrieve all workflow integration connections from PagerDuty.

    This tool is used to list all Workflow Integration Connections available in PagerDuty. It requires proper OAuth scope for access."""  # 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="https://api.pagerduty.com/workflows/integrations/connections",
        method="GET",
        params=remove_none_values({
            "limit": response_limit,
            "cursor": next_results_cursor,
            "name": filter_by_partial_name,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_workflow_connections(
    context: ToolContext,
    workflow_integration_id: Annotated[
        str, "Specify the unique ID of the workflow integration to retrieve its connections."
    ],
    filter_by_partial_name: Annotated[
        str | None,
        "Filter integrations by a partial name match. Provide part of the integration name to refine results.",  # noqa: E501
    ] = None,
    next_result_cursor: Annotated[
        str | None,
        "Request the next set of results using the cursor obtained from a previous response. Leave empty to start from the beginning.",  # noqa: E501
    ] = None,
    result_limit: Annotated[
        int | None,
        "Specifies the maximum number of results to return. It is the minimum of the request's limit or the API's maximum request size.",  # noqa: E501
    ] = None,
) -> Annotated[
    dict[str, Any],
    "Response from the API endpoint 'listWorkflowIntegrationConnectionsByIntegration'.",
]:
    """Retrieve connections for a specific workflow integration.

    Use this tool to list all workflow integration connections for a specified workflow integration. This requires the appropriate OAuth scope for access."""  # 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="https://api.pagerduty.com/workflows/integrations/{integration_id}/connections".format(  # noqa: UP032
            integration_id=workflow_integration_id
        ),
        method="GET",
        params=remove_none_values({
            "limit": result_limit,
            "cursor": next_result_cursor,
            "name": filter_by_partial_name,
        }),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def create_workflow_integration_connection(
    context: ToolContext,
    workflow_integration_id: Annotated[
        str, "The ID of the Workflow Integration to create a connection for."
    ],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'createWorkflowIntegrationConnection'."
]:
    """Create a new workflow integration connection in PagerDuty.

    Use this tool to create a new connection for a specified workflow integration in PagerDuty. Requires appropriate OAuth scope."""  # 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="https://api.pagerduty.com/workflows/integrations/{integration_id}/connections".format(  # noqa: UP032
            integration_id=workflow_integration_id
        ),
        method="POST",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def get_workflow_integration_connection_details(
    context: ToolContext,
    resource_id: Annotated[str, "The unique ID of the Workflow Integration Connection resource."],
    workflow_integration_id: Annotated[
        str, "The unique ID of the Workflow Integration to retrieve details for."
    ],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'getWorkflowIntegrationConnection'."
]:
    """Retrieve details of a Workflow Integration Connection.

    This tool fetches details about a specific Workflow Integration Connection using its ID. It's useful for obtaining information on connected workflows via PagerDuty."""  # 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="https://api.pagerduty.com/workflows/integrations/{integration_id}/connections/{id}".format(  # noqa: UP032
            integration_id=workflow_integration_id, id=resource_id
        ),
        method="GET",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def update_workflow_integration_connection(
    context: ToolContext,
    integration_id: Annotated[
        str,
        "The ID of the Workflow Integration to be updated. Required to specify which integration connection to modify.",  # noqa: E501
    ],
    resource_id: Annotated[str, "The ID of the resource to be updated."],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'updateWorkflowIntegrationConnection'."
]:
    """Update an existing Workflow Integration Connection.

    Call this tool to update the connection details of a specific workflow integration in PagerDuty. Useful for modifying existing configurations in integrations."""  # 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="https://api.pagerduty.com/workflows/integrations/{integration_id}/connections/{id}".format(  # noqa: UP032
            integration_id=integration_id, id=resource_id
        ),
        method="PATCH",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Content-Type": "application/json",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}


@tool(requires_auth=OAuth2(id="arcade-pagerduty"))
async def delete_workflow_integration_connection(
    context: ToolContext,
    resource_id: Annotated[str, "The unique identifier for the resource to be deleted."],
    workflow_integration_id: Annotated[
        str, "The unique ID of the Workflow Integration to be deleted."
    ],
) -> Annotated[
    dict[str, Any], "Response from the API endpoint 'deleteWorkflowIntegrationConnection'."
]:
    """Delete a Workflow Integration Connection on PagerDuty.

    Use this tool to remove a specific workflow integration connection from PagerDuty. Ideal for scenarios where you need to manage or clean up integration settings. Requires appropriate OAuth permissions."""  # 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="https://api.pagerduty.com/workflows/integrations/{integration_id}/connections/{id}".format(  # noqa: UP032
            integration_id=workflow_integration_id, id=resource_id
        ),
        method="DELETE",
        params=remove_none_values({}),
        headers=remove_none_values({
            "Accept": "application/vnd.pagerduty+json;version=2",
            "Authorization": "Bearer {authorization}".format(  # noqa: UP032
                authorization=context.get_auth_token_or_empty()
            ),
        }),
        content=content,
    )
    try:
        return {"response_json": response.json()}
    except Exception:
        return {"response_text": response.text}
