# This file was auto-generated by Fern from our API Definition.

import datetime as dt
import typing
from json.decoder import JSONDecodeError

from ..core.api_error import ApiError
from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ..core.datetime_utils import serialize_datetime
from ..core.http_response import AsyncHttpResponse, HttpResponse
from ..core.jsonable_encoder import jsonable_encoder
from ..core.pydantic_utilities import parse_obj_as
from ..core.request_options import RequestOptions
from ..core.serialization import convert_and_respect_annotation_metadata
from ..errors.unprocessable_entity_error import UnprocessableEntityError
from ..types.auth_schema_response import AuthSchemaResponse
from ..types.authorization_response import AuthorizationResponse
from ..types.available_connectors_response import AvailableConnectorsResponse
from ..types.complete_o_auth_response import CompleteOAuthResponse
from ..types.connections_response import ConnectionsResponse
from ..types.connector_info import ConnectorInfo
from ..types.connector_response import ConnectorResponse
from ..types.connector_tools_response import ConnectorToolsResponse
from ..types.credential_health_status import CredentialHealthStatus
from ..types.credential_test_request import CredentialTestRequest
from ..types.credential_test_result import CredentialTestResult
from ..types.delete_connection_response import DeleteConnectionResponse
from ..types.execution_logs_response import ExecutionLogsResponse
from ..types.imap_connection_response import ImapConnectionResponse
from ..types.imap_footer_response import ImapFooterResponse
from ..types.o_auth_credentials_response import OAuthCredentialsResponse
from ..types.rename_connection_response import RenameConnectionResponse
from ..types.toggle_connection_response import ToggleConnectionResponse

# this is used as the default value for optional parameters
OMIT = typing.cast(typing.Any, ...)


class RawPersonalConnectorsClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._client_wrapper = client_wrapper

    def list_available_connectors(
        self,
        *,
        organization_id: typing.Optional[str] = None,
        q: typing.Optional[str] = None,
        category: typing.Optional[str] = None,
        limit: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[AvailableConnectorsResponse]:
        """
        List all available connector types that can be connected.

        Returns all available connector types from the synced catalog.
        When authenticated, shows per-user connection status.

        Parameters
        ----------
        organization_id : typing.Optional[str]
            Organization ID

        q : typing.Optional[str]
            Search by tool_key or display_name

        category : typing.Optional[str]
            Filter by category

        limit : typing.Optional[int]
            Max connectors returned

        offset : typing.Optional[int]
            Pagination offset

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[AvailableConnectorsResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/personal-connectors/available",
            method="GET",
            params={
                "organization_id": organization_id,
                "q": q,
                "category": category,
                "limit": limit,
                "offset": offset,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    AvailableConnectorsResponse,
                    parse_obj_as(
                        type_=AvailableConnectorsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def get_connector_details(
        self,
        tool_key: str,
        *,
        organization_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[ConnectorInfo]:
        """
        Get details of a specific connector by tool_key.

        Returns connector information including connection status if authenticated.

        Parameters
        ----------
        tool_key : str

        organization_id : typing.Optional[str]
            Organization ID

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[ConnectorInfo]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/available/{jsonable_encoder(tool_key)}",
            method="GET",
            params={
                "organization_id": organization_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ConnectorInfo,
                    parse_obj_as(
                        type_=ConnectorInfo,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def get_auth_schema(
        self, connector_type: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[AuthSchemaResponse]:
        """
        Get authentication schema for a connector type.

        Returns the auth type (oauth or credentials) and required fields.

        Parameters
        ----------
        connector_type : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[AuthSchemaResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/auth-schema/{jsonable_encoder(connector_type)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    AuthSchemaResponse,
                    parse_obj_as(
                        type_=AuthSchemaResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def initiate_oauth(
        self,
        *,
        organization_id: str,
        connector_type: str,
        integration_params: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[AuthorizationResponse]:
        """
        Initiate authorization flow for a connector.

        For OAuth connectors: starts standard OAuth flow.
        For credential connectors (e.g. IMAP): returns URL to a hosted credentials form.

        Parameters
        ----------
        organization_id : str
            Organization ID

        connector_type : str
            Connector type to authorize

        integration_params : typing.Optional[typing.Dict[str, typing.Any]]
            Optional integration-specific parameters

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[AuthorizationResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/personal-connectors/authorize",
            method="POST",
            params={
                "organization_id": organization_id,
            },
            json={
                "connector_type": connector_type,
                "integration_params": integration_params,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    AuthorizationResponse,
                    parse_obj_as(
                        type_=AuthorizationResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def list_connected_connectors(
        self, *, organization_id: str, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[typing.List[ConnectorResponse]]:
        """
        List user's connected personal connectors.

        Parameters
        ----------
        organization_id : str
            Organization ID

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[typing.List[ConnectorResponse]]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/personal-connectors/",
            method="GET",
            params={
                "organization_id": organization_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.List[ConnectorResponse],
                    parse_obj_as(
                        type_=typing.List[ConnectorResponse],  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def get_tool_connections(
        self,
        tool_key: str,
        *,
        organization_id: str,
        application_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[ConnectionsResponse]:
        """
        Get user's connected accounts for a specific tool.

        Parameters
        ----------
        tool_key : str

        organization_id : str
            Organization ID

        application_id : typing.Optional[str]
            Application scope

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[ConnectionsResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/connections/{jsonable_encoder(tool_key)}",
            method="GET",
            params={
                "organization_id": organization_id,
                "application_id": application_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ConnectionsResponse,
                    parse_obj_as(
                        type_=ConnectionsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def complete_oauth(
        self, *, organization_id: str, state_token: str, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[CompleteOAuthResponse]:
        """
        Complete an OAuth flow by polling the connector service for connection status.

        Parameters
        ----------
        organization_id : str
            Organization ID

        state_token : str
            The OAuth state token (ostate_xxx) returned from /authorize

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[CompleteOAuthResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/personal-connectors/complete-oauth",
            method="POST",
            params={
                "organization_id": organization_id,
            },
            json={
                "state_token": state_token,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CompleteOAuthResponse,
                    parse_obj_as(
                        type_=CompleteOAuthResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def delete_connection(
        self, credential_id: str, *, organization_id: str, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[DeleteConnectionResponse]:
        """
        Delete a user's connection/credential.

        Parameters
        ----------
        credential_id : str

        organization_id : str
            Organization ID

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[DeleteConnectionResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/connections/{jsonable_encoder(credential_id)}",
            method="DELETE",
            params={
                "organization_id": organization_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    DeleteConnectionResponse,
                    parse_obj_as(
                        type_=DeleteConnectionResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def rename_connection(
        self,
        credential_id: str,
        *,
        organization_id: str,
        credential_name: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[RenameConnectionResponse]:
        """
        Rename a user's connection/credential.

        Parameters
        ----------
        credential_id : str

        organization_id : str
            Organization ID

        credential_name : str
            New name for the credential

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[RenameConnectionResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/connections/{jsonable_encoder(credential_id)}",
            method="PATCH",
            params={
                "organization_id": organization_id,
            },
            json={
                "credential_name": credential_name,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    RenameConnectionResponse,
                    parse_obj_as(
                        type_=RenameConnectionResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def toggle_connection_active(
        self,
        credential_id: str,
        *,
        organization_id: str,
        is_active: bool,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[ToggleConnectionResponse]:
        """
        Enable or disable a personal connector credential.

        Parameters
        ----------
        credential_id : str

        organization_id : str
            Organization ID

        is_active : bool
            Whether the connection should be active

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[ToggleConnectionResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/connections/{jsonable_encoder(credential_id)}/active",
            method="PATCH",
            params={
                "organization_id": organization_id,
            },
            json={
                "is_active": is_active,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ToggleConnectionResponse,
                    parse_obj_as(
                        type_=ToggleConnectionResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def connect_imap(
        self,
        *,
        organization_id: str,
        email_address: str,
        password: str,
        imap_host: str,
        smtp_host: str,
        imap_port: typing.Optional[int] = OMIT,
        smtp_port: typing.Optional[int] = OMIT,
        use_ssl: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[ImapConnectionResponse]:
        """
        Connect IMAP/SMTP email account with username/password authentication.

        Parameters
        ----------
        organization_id : str
            Organization ID

        email_address : str
            Email address

        password : str
            Email password

        imap_host : str
            IMAP server hostname

        smtp_host : str
            SMTP server hostname

        imap_port : typing.Optional[int]
            IMAP port (993 for SSL, 143 for STARTTLS)

        smtp_port : typing.Optional[int]
            SMTP port (465 for SSL, 587 for STARTTLS)

        use_ssl : typing.Optional[bool]
            Use SSL/TLS connection

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[ImapConnectionResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/personal-connectors/connect-imap",
            method="POST",
            params={
                "organization_id": organization_id,
            },
            json={
                "email_address": email_address,
                "password": password,
                "imap_host": imap_host,
                "imap_port": imap_port,
                "smtp_host": smtp_host,
                "smtp_port": smtp_port,
                "use_ssl": use_ssl,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ImapConnectionResponse,
                    parse_obj_as(
                        type_=ImapConnectionResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def set_imap_footer(
        self,
        *,
        organization_id: str,
        footer_html: typing.Optional[str] = OMIT,
        footer_text: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[ImapFooterResponse]:
        """
        Set custom email footer for IMAP account.

        Parameters
        ----------
        organization_id : str
            Organization ID

        footer_html : typing.Optional[str]
            HTML footer content

        footer_text : typing.Optional[str]
            Plain text footer content

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[ImapFooterResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/personal-connectors/imap-footer",
            method="POST",
            params={
                "organization_id": organization_id,
            },
            json={
                "footer_html": footer_html,
                "footer_text": footer_text,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ImapFooterResponse,
                    parse_obj_as(
                        type_=ImapFooterResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def oauth_proxy_callback(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[typing.Any]:
        """
        Proxy endpoint for OAuth provider callbacks.

        Forwards all query params server-side so the provider consent screen
        shows our domain, not a third party's.

        Parameters
        ----------
        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[typing.Any]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/personal-connectors/oauth-proxy",
            method="GET",
            request_options=request_options,
        )
        try:
            if _response is None or not _response.text.strip():
                return HttpResponse(response=_response, data=None)
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.Any,
                    parse_obj_as(
                        type_=typing.Any,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def oauth_proxy_callback_v1personal_connectors_oauth_proxy_get(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[typing.Any]:
        """
        Proxy endpoint for OAuth provider callbacks.

        Forwards all query params server-side so the provider consent screen
        shows our domain, not a third party's.

        Parameters
        ----------
        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[typing.Any]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/personal-connectors/oauth-proxy",
            method="POST",
            request_options=request_options,
        )
        try:
            if _response is None or not _response.text.strip():
                return HttpResponse(response=_response, data=None)
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.Any,
                    parse_obj_as(
                        type_=typing.Any,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def retry_connector(
        self, *, connector: str, organization_id: str, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[None]:
        """
        Render a page that lets the user re-initiate a connector authorization.

        Parameters
        ----------
        connector : str
            Connector tool key

        organization_id : str
            Organization ID

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[None]
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/personal-connectors/retry",
            method="GET",
            params={
                "connector": connector,
                "organization_id": organization_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return HttpResponse(response=_response, data=None)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def oauth_callback(
        self,
        *,
        code: typing.Optional[str] = None,
        state: typing.Optional[str] = None,
        error: typing.Optional[str] = None,
        status: typing.Optional[str] = None,
        connected_account_id: typing.Optional[str] = None,
        app_name: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[None]:
        """
        Handle OAuth callback from third-party services.

        Parameters
        ----------
        code : typing.Optional[str]
            OAuth authorization code

        state : typing.Optional[str]
            OAuth state token

        error : typing.Optional[str]
            OAuth error parameter

        status : typing.Optional[str]
            Connection status

        connected_account_id : typing.Optional[str]
            Connected account ID

        app_name : typing.Optional[str]
            Connected app name

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[None]
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/personal-connectors/callback",
            method="GET",
            params={
                "code": code,
                "state": state,
                "error": error,
                "status": status,
                "connected_account_id": connected_account_id,
                "app_name": app_name,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return HttpResponse(response=_response, data=None)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def credentials_form_page(
        self, state_token: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[typing.Any]:
        """
        Render hosted credentials form for non-OAuth connectors.

        Parameters
        ----------
        state_token : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[typing.Any]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/credentials-form/{jsonable_encoder(state_token)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if _response is None or not _response.text.strip():
                return HttpResponse(response=_response, data=None)
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.Any,
                    parse_obj_as(
                        type_=typing.Any,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def credentials_form_submit(
        self,
        state_token: str,
        *,
        test_only: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[typing.Dict[str, typing.Any]]:
        """
        Handle credential form submission (test or save).

        Parameters
        ----------
        state_token : str

        test_only : typing.Optional[bool]
            Only test, don't save

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[typing.Dict[str, typing.Any]]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/credentials-form/{jsonable_encoder(state_token)}",
            method="POST",
            params={
                "test_only": test_only,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.Dict[str, typing.Any],
                    parse_obj_as(
                        type_=typing.Dict[str, typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def pre_oauth_form_page(
        self, state_token: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[typing.Any]:
        """
        Render a hosted form for connectors that need fields before OAuth.

        Parameters
        ----------
        state_token : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[typing.Any]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/pre-oauth-form/{jsonable_encoder(state_token)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if _response is None or not _response.text.strip():
                return HttpResponse(response=_response, data=None)
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.Any,
                    parse_obj_as(
                        type_=typing.Any,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def pre_oauth_form_submit(
        self, state_token: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[typing.Any]:
        """
        Handle pre-OAuth form submission.

        Parameters
        ----------
        state_token : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[typing.Any]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/pre-oauth-form/{jsonable_encoder(state_token)}",
            method="POST",
            request_options=request_options,
        )
        try:
            if _response is None or not _response.text.strip():
                return HttpResponse(response=_response, data=None)
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.Any,
                    parse_obj_as(
                        type_=typing.Any,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def redirect_to_auth(
        self, connection_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[typing.Any]:
        """
        Redirect to the actual OAuth authorization URL.

        Supports both state_token (ostate_*) and connection_id lookups.

        Parameters
        ----------
        connection_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[typing.Any]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/auth/{jsonable_encoder(connection_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if _response is None or not _response.text.strip():
                return HttpResponse(response=_response, data=None)
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.Any,
                    parse_obj_as(
                        type_=typing.Any,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def list_execution_logs(
        self,
        *,
        organization_id: str,
        credential_id: typing.Optional[str] = None,
        status: typing.Optional[str] = None,
        start_date: typing.Optional[dt.datetime] = None,
        end_date: typing.Optional[dt.datetime] = None,
        limit: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[ExecutionLogsResponse]:
        """
        List tool execution logs for the authenticated user.

        Parameters
        ----------
        organization_id : str
            Organization ID

        credential_id : typing.Optional[str]
            Filter by credential ID

        status : typing.Optional[str]
            Filter by status

        start_date : typing.Optional[dt.datetime]
            Filter logs from this date

        end_date : typing.Optional[dt.datetime]
            Filter logs until this date

        limit : typing.Optional[int]
            Max logs to return

        offset : typing.Optional[int]
            Pagination offset

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[ExecutionLogsResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/personal-connectors/logs",
            method="GET",
            params={
                "organization_id": organization_id,
                "credential_id": credential_id,
                "status": status,
                "start_date": serialize_datetime(start_date) if start_date is not None else None,
                "end_date": serialize_datetime(end_date) if end_date is not None else None,
                "limit": limit,
                "offset": offset,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ExecutionLogsResponse,
                    parse_obj_as(
                        type_=ExecutionLogsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def get_connector_credentials(
        self,
        credential_id: str,
        *,
        flowplate_key: typing.Optional[str] = None,
        aitronos_hub_key: typing.Optional[str] = None,
        api_key: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[OAuthCredentialsResponse]:
        """
        Get OAuth credentials for a connector credential (admin only).

        Parameters
        ----------
        credential_id : str

        flowplate_key : typing.Optional[str]
            Flowplate Master API Key

        aitronos_hub_key : typing.Optional[str]
            Aitronos Hub Master API Key

        api_key : typing.Optional[str]
            Pipeline Connector API Key

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[OAuthCredentialsResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/admin/credentials/{jsonable_encoder(credential_id)}",
            method="GET",
            headers={
                "X-Flowplate-Key": str(flowplate_key) if flowplate_key is not None else None,
                "X-Aitronos-Hub-Key": str(aitronos_hub_key) if aitronos_hub_key is not None else None,
                "X-API-Key": str(api_key) if api_key is not None else None,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    OAuthCredentialsResponse,
                    parse_obj_as(
                        type_=OAuthCredentialsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def get_credentials_by_connection_id(
        self,
        connection_id: str,
        *,
        flowplate_key: typing.Optional[str] = None,
        aitronos_hub_key: typing.Optional[str] = None,
        api_key: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[OAuthCredentialsResponse]:
        """
        Get OAuth credentials directly by connector connection ID (admin only).

        Parameters
        ----------
        connection_id : str

        flowplate_key : typing.Optional[str]
            Flowplate Master API Key

        aitronos_hub_key : typing.Optional[str]
            Aitronos Hub Master API Key

        api_key : typing.Optional[str]
            Pipeline Connector API Key

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[OAuthCredentialsResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/admin/credentials/by-connection/{jsonable_encoder(connection_id)}",
            method="GET",
            headers={
                "X-Flowplate-Key": str(flowplate_key) if flowplate_key is not None else None,
                "X-Aitronos-Hub-Key": str(aitronos_hub_key) if aitronos_hub_key is not None else None,
                "X-API-Key": str(api_key) if api_key is not None else None,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    OAuthCredentialsResponse,
                    parse_obj_as(
                        type_=OAuthCredentialsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def check_credential_health(
        self, credential_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[CredentialHealthStatus]:
        """
        Check the health status of a credential.

        Parameters
        ----------
        credential_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[CredentialHealthStatus]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/{jsonable_encoder(credential_id)}/health",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CredentialHealthStatus,
                    parse_obj_as(
                        type_=CredentialHealthStatus,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def test_credential(
        self,
        credential_id: str,
        *,
        request: typing.Optional[CredentialTestRequest] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[CredentialTestResult]:
        """
        Test a credential by executing a controlled read-only action.

        Parameters
        ----------
        credential_id : str

        request : typing.Optional[CredentialTestRequest]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[CredentialTestResult]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/{jsonable_encoder(credential_id)}/test",
            method="POST",
            json=convert_and_respect_annotation_metadata(
                object_=request, annotation=typing.Optional[CredentialTestRequest], direction="write"
            ),
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CredentialTestResult,
                    parse_obj_as(
                        type_=CredentialTestResult,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def disconnect_connector(
        self, connector_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[None]:
        """
        Disconnect a personal connector (soft delete).

        Parameters
        ----------
        connector_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[None]
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/{jsonable_encoder(connector_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return HttpResponse(response=_response, data=None)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def update_connector(
        self, connector_id: str, *, is_active: bool, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[ConnectorResponse]:
        """
        Update a personal connector's status (enable/disable).

        Parameters
        ----------
        connector_id : str

        is_active : bool
            Whether connector should be active

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[ConnectorResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/{jsonable_encoder(connector_id)}",
            method="PATCH",
            json={
                "is_active": is_active,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ConnectorResponse,
                    parse_obj_as(
                        type_=ConnectorResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def list_connector_tools(
        self, connector_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[ConnectorToolsResponse]:
        """
        List available tools for a personal connector.

        Parameters
        ----------
        connector_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[ConnectorToolsResponse]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/{jsonable_encoder(connector_id)}/tools",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ConnectorToolsResponse,
                    parse_obj_as(
                        type_=ConnectorToolsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def update_connector_tools(
        self,
        connector_id: str,
        *,
        enabled: bool,
        allowed_tools: typing.Optional[typing.Sequence[str]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[typing.Dict[str, typing.Any]]:
        """
        Update tool configuration for a personal connector.

        Parameters
        ----------
        connector_id : str

        enabled : bool
            Enable/disable all tools

        allowed_tools : typing.Optional[typing.Sequence[str]]
            List of allowed tool names (None = all allowed)

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[typing.Dict[str, typing.Any]]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/{jsonable_encoder(connector_id)}/tools",
            method="PATCH",
            json={
                "enabled": enabled,
                "allowed_tools": allowed_tools,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.Dict[str, typing.Any],
                    parse_obj_as(
                        type_=typing.Dict[str, typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def disconnect_connector_credential(
        self, credential_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[None]:
        """
        Disconnect a connector credential (soft delete).

        Parameters
        ----------
        credential_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[None]
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/composio/{jsonable_encoder(credential_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return HttpResponse(response=_response, data=None)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def list_credential_actions(
        self, credential_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> HttpResponse[typing.Any]:
        """
        List available actions for a connected tool credential.

        Parameters
        ----------
        credential_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[typing.Any]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/{jsonable_encoder(credential_id)}/actions",
            method="GET",
            request_options=request_options,
        )
        try:
            if _response is None or not _response.text.strip():
                return HttpResponse(response=_response, data=None)
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.Any,
                    parse_obj_as(
                        type_=typing.Any,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def get_connector_comments(
        self,
        connector: str,
        item_id: str,
        *,
        limit: typing.Optional[int] = None,
        owner: typing.Optional[str] = None,
        repo: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[typing.Dict[str, typing.Any]]:
        """
        Fetch comments for a connector item.

        Parameters
        ----------
        connector : str

        item_id : str

        limit : typing.Optional[int]
            Max comments to return

        owner : typing.Optional[str]
            Repository owner (required for GitHub)

        repo : typing.Optional[str]
            Repository name (required for GitHub)

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[typing.Dict[str, typing.Any]]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/{jsonable_encoder(connector)}/items/{jsonable_encoder(item_id)}/comments",
            method="GET",
            params={
                "limit": limit,
                "owner": owner,
                "repo": repo,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.Dict[str, typing.Any],
                    parse_obj_as(
                        type_=typing.Dict[str, typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    def add_connector_comment(
        self,
        connector: str,
        item_id: str,
        *,
        text: str,
        owner: typing.Optional[str] = None,
        repo: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[typing.Dict[str, typing.Any]]:
        """
        Add a comment/reply to a connector item (issue, task, ticket).

        Parameters
        ----------
        connector : str

        item_id : str

        text : str
            Comment body text

        owner : typing.Optional[str]
            Repository owner (required for GitHub)

        repo : typing.Optional[str]
            Repository name (required for GitHub)

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        HttpResponse[typing.Dict[str, typing.Any]]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/{jsonable_encoder(connector)}/items/{jsonable_encoder(item_id)}/comments",
            method="POST",
            params={
                "owner": owner,
                "repo": repo,
            },
            json={
                "text": text,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.Dict[str, typing.Any],
                    parse_obj_as(
                        type_=typing.Dict[str, typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)


class AsyncRawPersonalConnectorsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def list_available_connectors(
        self,
        *,
        organization_id: typing.Optional[str] = None,
        q: typing.Optional[str] = None,
        category: typing.Optional[str] = None,
        limit: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[AvailableConnectorsResponse]:
        """
        List all available connector types that can be connected.

        Returns all available connector types from the synced catalog.
        When authenticated, shows per-user connection status.

        Parameters
        ----------
        organization_id : typing.Optional[str]
            Organization ID

        q : typing.Optional[str]
            Search by tool_key or display_name

        category : typing.Optional[str]
            Filter by category

        limit : typing.Optional[int]
            Max connectors returned

        offset : typing.Optional[int]
            Pagination offset

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[AvailableConnectorsResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/personal-connectors/available",
            method="GET",
            params={
                "organization_id": organization_id,
                "q": q,
                "category": category,
                "limit": limit,
                "offset": offset,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    AvailableConnectorsResponse,
                    parse_obj_as(
                        type_=AvailableConnectorsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def get_connector_details(
        self,
        tool_key: str,
        *,
        organization_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[ConnectorInfo]:
        """
        Get details of a specific connector by tool_key.

        Returns connector information including connection status if authenticated.

        Parameters
        ----------
        tool_key : str

        organization_id : typing.Optional[str]
            Organization ID

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[ConnectorInfo]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/available/{jsonable_encoder(tool_key)}",
            method="GET",
            params={
                "organization_id": organization_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ConnectorInfo,
                    parse_obj_as(
                        type_=ConnectorInfo,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def get_auth_schema(
        self, connector_type: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[AuthSchemaResponse]:
        """
        Get authentication schema for a connector type.

        Returns the auth type (oauth or credentials) and required fields.

        Parameters
        ----------
        connector_type : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[AuthSchemaResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/auth-schema/{jsonable_encoder(connector_type)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    AuthSchemaResponse,
                    parse_obj_as(
                        type_=AuthSchemaResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def initiate_oauth(
        self,
        *,
        organization_id: str,
        connector_type: str,
        integration_params: typing.Optional[typing.Dict[str, typing.Any]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[AuthorizationResponse]:
        """
        Initiate authorization flow for a connector.

        For OAuth connectors: starts standard OAuth flow.
        For credential connectors (e.g. IMAP): returns URL to a hosted credentials form.

        Parameters
        ----------
        organization_id : str
            Organization ID

        connector_type : str
            Connector type to authorize

        integration_params : typing.Optional[typing.Dict[str, typing.Any]]
            Optional integration-specific parameters

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[AuthorizationResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/personal-connectors/authorize",
            method="POST",
            params={
                "organization_id": organization_id,
            },
            json={
                "connector_type": connector_type,
                "integration_params": integration_params,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    AuthorizationResponse,
                    parse_obj_as(
                        type_=AuthorizationResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def list_connected_connectors(
        self, *, organization_id: str, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[typing.List[ConnectorResponse]]:
        """
        List user's connected personal connectors.

        Parameters
        ----------
        organization_id : str
            Organization ID

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[typing.List[ConnectorResponse]]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/personal-connectors/",
            method="GET",
            params={
                "organization_id": organization_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.List[ConnectorResponse],
                    parse_obj_as(
                        type_=typing.List[ConnectorResponse],  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def get_tool_connections(
        self,
        tool_key: str,
        *,
        organization_id: str,
        application_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[ConnectionsResponse]:
        """
        Get user's connected accounts for a specific tool.

        Parameters
        ----------
        tool_key : str

        organization_id : str
            Organization ID

        application_id : typing.Optional[str]
            Application scope

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[ConnectionsResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/connections/{jsonable_encoder(tool_key)}",
            method="GET",
            params={
                "organization_id": organization_id,
                "application_id": application_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ConnectionsResponse,
                    parse_obj_as(
                        type_=ConnectionsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def complete_oauth(
        self, *, organization_id: str, state_token: str, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[CompleteOAuthResponse]:
        """
        Complete an OAuth flow by polling the connector service for connection status.

        Parameters
        ----------
        organization_id : str
            Organization ID

        state_token : str
            The OAuth state token (ostate_xxx) returned from /authorize

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[CompleteOAuthResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/personal-connectors/complete-oauth",
            method="POST",
            params={
                "organization_id": organization_id,
            },
            json={
                "state_token": state_token,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CompleteOAuthResponse,
                    parse_obj_as(
                        type_=CompleteOAuthResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def delete_connection(
        self, credential_id: str, *, organization_id: str, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[DeleteConnectionResponse]:
        """
        Delete a user's connection/credential.

        Parameters
        ----------
        credential_id : str

        organization_id : str
            Organization ID

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[DeleteConnectionResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/connections/{jsonable_encoder(credential_id)}",
            method="DELETE",
            params={
                "organization_id": organization_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    DeleteConnectionResponse,
                    parse_obj_as(
                        type_=DeleteConnectionResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def rename_connection(
        self,
        credential_id: str,
        *,
        organization_id: str,
        credential_name: str,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[RenameConnectionResponse]:
        """
        Rename a user's connection/credential.

        Parameters
        ----------
        credential_id : str

        organization_id : str
            Organization ID

        credential_name : str
            New name for the credential

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[RenameConnectionResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/connections/{jsonable_encoder(credential_id)}",
            method="PATCH",
            params={
                "organization_id": organization_id,
            },
            json={
                "credential_name": credential_name,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    RenameConnectionResponse,
                    parse_obj_as(
                        type_=RenameConnectionResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def toggle_connection_active(
        self,
        credential_id: str,
        *,
        organization_id: str,
        is_active: bool,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[ToggleConnectionResponse]:
        """
        Enable or disable a personal connector credential.

        Parameters
        ----------
        credential_id : str

        organization_id : str
            Organization ID

        is_active : bool
            Whether the connection should be active

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[ToggleConnectionResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/connections/{jsonable_encoder(credential_id)}/active",
            method="PATCH",
            params={
                "organization_id": organization_id,
            },
            json={
                "is_active": is_active,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ToggleConnectionResponse,
                    parse_obj_as(
                        type_=ToggleConnectionResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def connect_imap(
        self,
        *,
        organization_id: str,
        email_address: str,
        password: str,
        imap_host: str,
        smtp_host: str,
        imap_port: typing.Optional[int] = OMIT,
        smtp_port: typing.Optional[int] = OMIT,
        use_ssl: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[ImapConnectionResponse]:
        """
        Connect IMAP/SMTP email account with username/password authentication.

        Parameters
        ----------
        organization_id : str
            Organization ID

        email_address : str
            Email address

        password : str
            Email password

        imap_host : str
            IMAP server hostname

        smtp_host : str
            SMTP server hostname

        imap_port : typing.Optional[int]
            IMAP port (993 for SSL, 143 for STARTTLS)

        smtp_port : typing.Optional[int]
            SMTP port (465 for SSL, 587 for STARTTLS)

        use_ssl : typing.Optional[bool]
            Use SSL/TLS connection

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[ImapConnectionResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/personal-connectors/connect-imap",
            method="POST",
            params={
                "organization_id": organization_id,
            },
            json={
                "email_address": email_address,
                "password": password,
                "imap_host": imap_host,
                "imap_port": imap_port,
                "smtp_host": smtp_host,
                "smtp_port": smtp_port,
                "use_ssl": use_ssl,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ImapConnectionResponse,
                    parse_obj_as(
                        type_=ImapConnectionResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def set_imap_footer(
        self,
        *,
        organization_id: str,
        footer_html: typing.Optional[str] = OMIT,
        footer_text: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[ImapFooterResponse]:
        """
        Set custom email footer for IMAP account.

        Parameters
        ----------
        organization_id : str
            Organization ID

        footer_html : typing.Optional[str]
            HTML footer content

        footer_text : typing.Optional[str]
            Plain text footer content

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[ImapFooterResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/personal-connectors/imap-footer",
            method="POST",
            params={
                "organization_id": organization_id,
            },
            json={
                "footer_html": footer_html,
                "footer_text": footer_text,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ImapFooterResponse,
                    parse_obj_as(
                        type_=ImapFooterResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def oauth_proxy_callback(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[typing.Any]:
        """
        Proxy endpoint for OAuth provider callbacks.

        Forwards all query params server-side so the provider consent screen
        shows our domain, not a third party's.

        Parameters
        ----------
        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[typing.Any]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/personal-connectors/oauth-proxy",
            method="GET",
            request_options=request_options,
        )
        try:
            if _response is None or not _response.text.strip():
                return AsyncHttpResponse(response=_response, data=None)
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.Any,
                    parse_obj_as(
                        type_=typing.Any,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def oauth_proxy_callback_v1personal_connectors_oauth_proxy_get(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[typing.Any]:
        """
        Proxy endpoint for OAuth provider callbacks.

        Forwards all query params server-side so the provider consent screen
        shows our domain, not a third party's.

        Parameters
        ----------
        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[typing.Any]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/personal-connectors/oauth-proxy",
            method="POST",
            request_options=request_options,
        )
        try:
            if _response is None or not _response.text.strip():
                return AsyncHttpResponse(response=_response, data=None)
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.Any,
                    parse_obj_as(
                        type_=typing.Any,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def retry_connector(
        self, *, connector: str, organization_id: str, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[None]:
        """
        Render a page that lets the user re-initiate a connector authorization.

        Parameters
        ----------
        connector : str
            Connector tool key

        organization_id : str
            Organization ID

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[None]
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/personal-connectors/retry",
            method="GET",
            params={
                "connector": connector,
                "organization_id": organization_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return AsyncHttpResponse(response=_response, data=None)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def oauth_callback(
        self,
        *,
        code: typing.Optional[str] = None,
        state: typing.Optional[str] = None,
        error: typing.Optional[str] = None,
        status: typing.Optional[str] = None,
        connected_account_id: typing.Optional[str] = None,
        app_name: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[None]:
        """
        Handle OAuth callback from third-party services.

        Parameters
        ----------
        code : typing.Optional[str]
            OAuth authorization code

        state : typing.Optional[str]
            OAuth state token

        error : typing.Optional[str]
            OAuth error parameter

        status : typing.Optional[str]
            Connection status

        connected_account_id : typing.Optional[str]
            Connected account ID

        app_name : typing.Optional[str]
            Connected app name

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[None]
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/personal-connectors/callback",
            method="GET",
            params={
                "code": code,
                "state": state,
                "error": error,
                "status": status,
                "connected_account_id": connected_account_id,
                "app_name": app_name,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return AsyncHttpResponse(response=_response, data=None)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def credentials_form_page(
        self, state_token: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[typing.Any]:
        """
        Render hosted credentials form for non-OAuth connectors.

        Parameters
        ----------
        state_token : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[typing.Any]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/credentials-form/{jsonable_encoder(state_token)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if _response is None or not _response.text.strip():
                return AsyncHttpResponse(response=_response, data=None)
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.Any,
                    parse_obj_as(
                        type_=typing.Any,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def credentials_form_submit(
        self,
        state_token: str,
        *,
        test_only: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[typing.Dict[str, typing.Any]]:
        """
        Handle credential form submission (test or save).

        Parameters
        ----------
        state_token : str

        test_only : typing.Optional[bool]
            Only test, don't save

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[typing.Dict[str, typing.Any]]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/credentials-form/{jsonable_encoder(state_token)}",
            method="POST",
            params={
                "test_only": test_only,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.Dict[str, typing.Any],
                    parse_obj_as(
                        type_=typing.Dict[str, typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def pre_oauth_form_page(
        self, state_token: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[typing.Any]:
        """
        Render a hosted form for connectors that need fields before OAuth.

        Parameters
        ----------
        state_token : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[typing.Any]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/pre-oauth-form/{jsonable_encoder(state_token)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if _response is None or not _response.text.strip():
                return AsyncHttpResponse(response=_response, data=None)
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.Any,
                    parse_obj_as(
                        type_=typing.Any,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def pre_oauth_form_submit(
        self, state_token: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[typing.Any]:
        """
        Handle pre-OAuth form submission.

        Parameters
        ----------
        state_token : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[typing.Any]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/pre-oauth-form/{jsonable_encoder(state_token)}",
            method="POST",
            request_options=request_options,
        )
        try:
            if _response is None or not _response.text.strip():
                return AsyncHttpResponse(response=_response, data=None)
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.Any,
                    parse_obj_as(
                        type_=typing.Any,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def redirect_to_auth(
        self, connection_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[typing.Any]:
        """
        Redirect to the actual OAuth authorization URL.

        Supports both state_token (ostate_*) and connection_id lookups.

        Parameters
        ----------
        connection_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[typing.Any]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/auth/{jsonable_encoder(connection_id)}",
            method="GET",
            request_options=request_options,
        )
        try:
            if _response is None or not _response.text.strip():
                return AsyncHttpResponse(response=_response, data=None)
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.Any,
                    parse_obj_as(
                        type_=typing.Any,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def list_execution_logs(
        self,
        *,
        organization_id: str,
        credential_id: typing.Optional[str] = None,
        status: typing.Optional[str] = None,
        start_date: typing.Optional[dt.datetime] = None,
        end_date: typing.Optional[dt.datetime] = None,
        limit: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[ExecutionLogsResponse]:
        """
        List tool execution logs for the authenticated user.

        Parameters
        ----------
        organization_id : str
            Organization ID

        credential_id : typing.Optional[str]
            Filter by credential ID

        status : typing.Optional[str]
            Filter by status

        start_date : typing.Optional[dt.datetime]
            Filter logs from this date

        end_date : typing.Optional[dt.datetime]
            Filter logs until this date

        limit : typing.Optional[int]
            Max logs to return

        offset : typing.Optional[int]
            Pagination offset

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[ExecutionLogsResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/personal-connectors/logs",
            method="GET",
            params={
                "organization_id": organization_id,
                "credential_id": credential_id,
                "status": status,
                "start_date": serialize_datetime(start_date) if start_date is not None else None,
                "end_date": serialize_datetime(end_date) if end_date is not None else None,
                "limit": limit,
                "offset": offset,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ExecutionLogsResponse,
                    parse_obj_as(
                        type_=ExecutionLogsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def get_connector_credentials(
        self,
        credential_id: str,
        *,
        flowplate_key: typing.Optional[str] = None,
        aitronos_hub_key: typing.Optional[str] = None,
        api_key: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[OAuthCredentialsResponse]:
        """
        Get OAuth credentials for a connector credential (admin only).

        Parameters
        ----------
        credential_id : str

        flowplate_key : typing.Optional[str]
            Flowplate Master API Key

        aitronos_hub_key : typing.Optional[str]
            Aitronos Hub Master API Key

        api_key : typing.Optional[str]
            Pipeline Connector API Key

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[OAuthCredentialsResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/admin/credentials/{jsonable_encoder(credential_id)}",
            method="GET",
            headers={
                "X-Flowplate-Key": str(flowplate_key) if flowplate_key is not None else None,
                "X-Aitronos-Hub-Key": str(aitronos_hub_key) if aitronos_hub_key is not None else None,
                "X-API-Key": str(api_key) if api_key is not None else None,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    OAuthCredentialsResponse,
                    parse_obj_as(
                        type_=OAuthCredentialsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def get_credentials_by_connection_id(
        self,
        connection_id: str,
        *,
        flowplate_key: typing.Optional[str] = None,
        aitronos_hub_key: typing.Optional[str] = None,
        api_key: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[OAuthCredentialsResponse]:
        """
        Get OAuth credentials directly by connector connection ID (admin only).

        Parameters
        ----------
        connection_id : str

        flowplate_key : typing.Optional[str]
            Flowplate Master API Key

        aitronos_hub_key : typing.Optional[str]
            Aitronos Hub Master API Key

        api_key : typing.Optional[str]
            Pipeline Connector API Key

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[OAuthCredentialsResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/admin/credentials/by-connection/{jsonable_encoder(connection_id)}",
            method="GET",
            headers={
                "X-Flowplate-Key": str(flowplate_key) if flowplate_key is not None else None,
                "X-Aitronos-Hub-Key": str(aitronos_hub_key) if aitronos_hub_key is not None else None,
                "X-API-Key": str(api_key) if api_key is not None else None,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    OAuthCredentialsResponse,
                    parse_obj_as(
                        type_=OAuthCredentialsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def check_credential_health(
        self, credential_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[CredentialHealthStatus]:
        """
        Check the health status of a credential.

        Parameters
        ----------
        credential_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[CredentialHealthStatus]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/{jsonable_encoder(credential_id)}/health",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CredentialHealthStatus,
                    parse_obj_as(
                        type_=CredentialHealthStatus,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def test_credential(
        self,
        credential_id: str,
        *,
        request: typing.Optional[CredentialTestRequest] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[CredentialTestResult]:
        """
        Test a credential by executing a controlled read-only action.

        Parameters
        ----------
        credential_id : str

        request : typing.Optional[CredentialTestRequest]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[CredentialTestResult]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/{jsonable_encoder(credential_id)}/test",
            method="POST",
            json=convert_and_respect_annotation_metadata(
                object_=request, annotation=typing.Optional[CredentialTestRequest], direction="write"
            ),
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    CredentialTestResult,
                    parse_obj_as(
                        type_=CredentialTestResult,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def disconnect_connector(
        self, connector_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[None]:
        """
        Disconnect a personal connector (soft delete).

        Parameters
        ----------
        connector_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[None]
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/{jsonable_encoder(connector_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return AsyncHttpResponse(response=_response, data=None)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def update_connector(
        self, connector_id: str, *, is_active: bool, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[ConnectorResponse]:
        """
        Update a personal connector's status (enable/disable).

        Parameters
        ----------
        connector_id : str

        is_active : bool
            Whether connector should be active

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[ConnectorResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/{jsonable_encoder(connector_id)}",
            method="PATCH",
            json={
                "is_active": is_active,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ConnectorResponse,
                    parse_obj_as(
                        type_=ConnectorResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def list_connector_tools(
        self, connector_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[ConnectorToolsResponse]:
        """
        List available tools for a personal connector.

        Parameters
        ----------
        connector_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[ConnectorToolsResponse]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/{jsonable_encoder(connector_id)}/tools",
            method="GET",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    ConnectorToolsResponse,
                    parse_obj_as(
                        type_=ConnectorToolsResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def update_connector_tools(
        self,
        connector_id: str,
        *,
        enabled: bool,
        allowed_tools: typing.Optional[typing.Sequence[str]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[typing.Dict[str, typing.Any]]:
        """
        Update tool configuration for a personal connector.

        Parameters
        ----------
        connector_id : str

        enabled : bool
            Enable/disable all tools

        allowed_tools : typing.Optional[typing.Sequence[str]]
            List of allowed tool names (None = all allowed)

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[typing.Dict[str, typing.Any]]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/{jsonable_encoder(connector_id)}/tools",
            method="PATCH",
            json={
                "enabled": enabled,
                "allowed_tools": allowed_tools,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.Dict[str, typing.Any],
                    parse_obj_as(
                        type_=typing.Dict[str, typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def disconnect_connector_credential(
        self, credential_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[None]:
        """
        Disconnect a connector credential (soft delete).

        Parameters
        ----------
        credential_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[None]
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/composio/{jsonable_encoder(credential_id)}",
            method="DELETE",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return AsyncHttpResponse(response=_response, data=None)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def list_credential_actions(
        self, credential_id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> AsyncHttpResponse[typing.Any]:
        """
        List available actions for a connected tool credential.

        Parameters
        ----------
        credential_id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[typing.Any]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/{jsonable_encoder(credential_id)}/actions",
            method="GET",
            request_options=request_options,
        )
        try:
            if _response is None or not _response.text.strip():
                return AsyncHttpResponse(response=_response, data=None)
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.Any,
                    parse_obj_as(
                        type_=typing.Any,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def get_connector_comments(
        self,
        connector: str,
        item_id: str,
        *,
        limit: typing.Optional[int] = None,
        owner: typing.Optional[str] = None,
        repo: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[typing.Dict[str, typing.Any]]:
        """
        Fetch comments for a connector item.

        Parameters
        ----------
        connector : str

        item_id : str

        limit : typing.Optional[int]
            Max comments to return

        owner : typing.Optional[str]
            Repository owner (required for GitHub)

        repo : typing.Optional[str]
            Repository name (required for GitHub)

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[typing.Dict[str, typing.Any]]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/{jsonable_encoder(connector)}/items/{jsonable_encoder(item_id)}/comments",
            method="GET",
            params={
                "limit": limit,
                "owner": owner,
                "repo": repo,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.Dict[str, typing.Any],
                    parse_obj_as(
                        type_=typing.Dict[str, typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)

    async def add_connector_comment(
        self,
        connector: str,
        item_id: str,
        *,
        text: str,
        owner: typing.Optional[str] = None,
        repo: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[typing.Dict[str, typing.Any]]:
        """
        Add a comment/reply to a connector item (issue, task, ticket).

        Parameters
        ----------
        connector : str

        item_id : str

        text : str
            Comment body text

        owner : typing.Optional[str]
            Repository owner (required for GitHub)

        repo : typing.Optional[str]
            Repository name (required for GitHub)

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncHttpResponse[typing.Dict[str, typing.Any]]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/personal-connectors/{jsonable_encoder(connector)}/items/{jsonable_encoder(item_id)}/comments",
            method="POST",
            params={
                "owner": owner,
                "repo": repo,
            },
            json={
                "text": text,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    typing.Dict[str, typing.Any],
                    parse_obj_as(
                        type_=typing.Dict[str, typing.Any],  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
