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

import typing
from ..core.client_wrapper import SyncClientWrapper
from ..types.chat_messages import ChatMessages
from ..types.tool_v2 import ToolV2
from .types.v2chat_stream_request_documents_item import V2ChatStreamRequestDocumentsItem
from ..types.citation_options import CitationOptions
from ..types.response_format_v2 import ResponseFormatV2
from .types.v2chat_stream_request_safety_mode import V2ChatStreamRequestSafetyMode
from ..core.request_options import RequestOptions
from ..types.streamed_chat_response_v2 import StreamedChatResponseV2
from ..core.serialization import convert_and_respect_annotation_metadata
import httpx_sse
from ..core.unchecked_base_model import construct_type
import json
from ..errors.bad_request_error import BadRequestError
from ..errors.unauthorized_error import UnauthorizedError
from ..errors.forbidden_error import ForbiddenError
from ..errors.not_found_error import NotFoundError
from ..errors.unprocessable_entity_error import UnprocessableEntityError
from ..types.unprocessable_entity_error_body import UnprocessableEntityErrorBody
from ..errors.too_many_requests_error import TooManyRequestsError
from ..types.too_many_requests_error_body import TooManyRequestsErrorBody
from ..errors.client_closed_request_error import ClientClosedRequestError
from ..types.client_closed_request_error_body import ClientClosedRequestErrorBody
from ..errors.internal_server_error import InternalServerError
from ..errors.not_implemented_error import NotImplementedError
from ..types.not_implemented_error_body import NotImplementedErrorBody
from ..errors.service_unavailable_error import ServiceUnavailableError
from ..errors.gateway_timeout_error import GatewayTimeoutError
from ..types.gateway_timeout_error_body import GatewayTimeoutErrorBody
from json.decoder import JSONDecodeError
from ..core.api_error import ApiError
from .types.v2chat_request_documents_item import V2ChatRequestDocumentsItem
from .types.v2chat_request_safety_mode import V2ChatRequestSafetyMode
from ..types.chat_response import ChatResponse
from ..types.embed_input_type import EmbedInputType
from ..types.embedding_type import EmbeddingType
from .types.v2embed_request_truncate import V2EmbedRequestTruncate
from ..types.embed_by_type_response import EmbedByTypeResponse
from .types.v2rerank_request_documents_item import V2RerankRequestDocumentsItem
from .types.v2rerank_response import V2RerankResponse
from ..core.client_wrapper import AsyncClientWrapper

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


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

    def chat_stream(
        self,
        *,
        model: str,
        messages: ChatMessages,
        tools: typing.Optional[typing.Sequence[ToolV2]] = OMIT,
        documents: typing.Optional[typing.Sequence[V2ChatStreamRequestDocumentsItem]] = OMIT,
        citation_options: typing.Optional[CitationOptions] = OMIT,
        response_format: typing.Optional[ResponseFormatV2] = OMIT,
        safety_mode: typing.Optional[V2ChatStreamRequestSafetyMode] = OMIT,
        max_tokens: typing.Optional[int] = OMIT,
        stop_sequences: typing.Optional[typing.Sequence[str]] = OMIT,
        temperature: typing.Optional[float] = OMIT,
        seed: typing.Optional[int] = OMIT,
        frequency_penalty: typing.Optional[float] = OMIT,
        presence_penalty: typing.Optional[float] = OMIT,
        k: typing.Optional[float] = OMIT,
        p: typing.Optional[float] = OMIT,
        return_prompt: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Iterator[StreamedChatResponseV2]:
        """
        Generates a text response to a user message and streams it down, token by token. To learn how to use the Chat API with streaming follow our [Text Generation guides](https://docs.cohere.com/v2/docs/chat-api).

        Follow the [Migration Guide](https://docs.cohere.com/v2/docs/migrating-v1-to-v2) for instructions on moving from API v1 to API v2.

        Parameters
        ----------
        model : str
            The name of a compatible [Cohere model](https://docs.cohere.com/v2/docs/models) (such as command-r or command-r-plus) or the ID of a [fine-tuned](https://docs.cohere.com/v2/docs/chat-fine-tuning) model.

        messages : ChatMessages

        tools : typing.Optional[typing.Sequence[ToolV2]]
            A list of available tools (functions) that the model may suggest invoking before producing a text response.

            When `tools` is passed (without `tool_results`), the `text` content in the response will be empty and the `tool_calls` field in the response will be populated with a list of tool calls that need to be made. If no calls need to be made, the `tool_calls` array will be empty.


        documents : typing.Optional[typing.Sequence[V2ChatStreamRequestDocumentsItem]]
            A list of relevant documents that the model can cite to generate a more accurate reply. Each document is either a string or document object with content and metadata.


        citation_options : typing.Optional[CitationOptions]

        response_format : typing.Optional[ResponseFormatV2]

        safety_mode : typing.Optional[V2ChatStreamRequestSafetyMode]
            Used to select the [safety instruction](https://docs.cohere.com/v2/docs/safety-modes) inserted into the prompt. Defaults to `CONTEXTUAL`.
            When `OFF` is specified, the safety instruction will be omitted.

            Safety modes are not yet configurable in combination with `tools`, `tool_results` and `documents` parameters.

            **Note**: This parameter is only compatible with models [Command R 08-2024](https://docs.cohere.com/v2/docs/command-r#august-2024-release), [Command R+ 08-2024](https://docs.cohere.com/v2/docs/command-r-plus#august-2024-release) and newer.


        max_tokens : typing.Optional[int]
            The maximum number of tokens the model will generate as part of the response.

            **Note**: Setting a low value may result in incomplete generations.


        stop_sequences : typing.Optional[typing.Sequence[str]]
            A list of up to 5 strings that the model will use to stop generation. If the model generates a string that matches any of the strings in the list, it will stop generating tokens and return the generated text up to that point not including the stop sequence.


        temperature : typing.Optional[float]
            Defaults to `0.3`.

            A non-negative float that tunes the degree of randomness in generation. Lower temperatures mean less random generations, and higher temperatures mean more random generations.

            Randomness can be further maximized by increasing the  value of the `p` parameter.


        seed : typing.Optional[int]
            If specified, the backend will make a best effort to sample tokens
            deterministically, such that repeated requests with the same
            seed and parameters should return the same result. However,
            determinism cannot be totally guaranteed.


        frequency_penalty : typing.Optional[float]
            Defaults to `0.0`, min value of `0.0`, max value of `1.0`.
            Used to reduce repetitiveness of generated tokens. The higher the value, the stronger a penalty is applied to previously present tokens, proportional to how many times they have already appeared in the prompt or prior generation.


        presence_penalty : typing.Optional[float]
            Defaults to `0.0`, min value of `0.0`, max value of `1.0`.
            Used to reduce repetitiveness of generated tokens. Similar to `frequency_penalty`, except that this penalty is applied equally to all tokens that have already appeared, regardless of their exact frequencies.


        k : typing.Optional[float]
            Ensures only the top `k` most likely tokens are considered for generation at each step.
            Defaults to `0`, min value of `0`, max value of `500`.


        p : typing.Optional[float]
            Ensures that only the most likely tokens, with total probability mass of `p`, are considered for generation at each step. If both `k` and `p` are enabled, `p` acts after `k`.
            Defaults to `0.75`. min value of `0.01`, max value of `0.99`.


        return_prompt : typing.Optional[bool]
            Whether to return the prompt in the response.

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

        Yields
        ------
        typing.Iterator[StreamedChatResponseV2]


        Examples
        --------
        from cohere import (
            CitationOptions,
            Client,
            TextResponseFormatV2,
            ToolV2,
            ToolV2Function,
            UserChatMessageV2,
        )

        client = Client(
            client_name="YOUR_CLIENT_NAME",
            token="YOUR_TOKEN",
        )
        response = client.v2.chat_stream(
            model="string",
            messages=[
                UserChatMessageV2(
                    content="string",
                )
            ],
            tools=[
                ToolV2(
                    function=ToolV2Function(
                        name="string",
                        description="string",
                        parameters={"string": {"key": "value"}},
                    ),
                )
            ],
            documents=["string"],
            citation_options=CitationOptions(
                mode="FAST",
            ),
            response_format=TextResponseFormatV2(),
            safety_mode="CONTEXTUAL",
            max_tokens=1,
            stop_sequences=["string"],
            temperature=1.1,
            seed=1,
            frequency_penalty=1.1,
            presence_penalty=1.1,
            k=1.1,
            p=1.1,
            return_prompt=True,
        )
        for chunk in response:
            yield chunk
        """
        with self._client_wrapper.httpx_client.stream(
            "v2/chat",
            method="POST",
            json={
                "model": model,
                "messages": convert_and_respect_annotation_metadata(
                    object_=messages, annotation=ChatMessages, direction="write"
                ),
                "tools": convert_and_respect_annotation_metadata(
                    object_=tools, annotation=typing.Sequence[ToolV2], direction="write"
                ),
                "documents": convert_and_respect_annotation_metadata(
                    object_=documents, annotation=typing.Sequence[V2ChatStreamRequestDocumentsItem], direction="write"
                ),
                "citation_options": convert_and_respect_annotation_metadata(
                    object_=citation_options, annotation=CitationOptions, direction="write"
                ),
                "response_format": convert_and_respect_annotation_metadata(
                    object_=response_format, annotation=ResponseFormatV2, direction="write"
                ),
                "safety_mode": safety_mode,
                "max_tokens": max_tokens,
                "stop_sequences": stop_sequences,
                "temperature": temperature,
                "seed": seed,
                "frequency_penalty": frequency_penalty,
                "presence_penalty": presence_penalty,
                "k": k,
                "p": p,
                "return_prompt": return_prompt,
                "stream": True,
            },
            request_options=request_options,
            omit=OMIT,
        ) as _response:
            try:
                if 200 <= _response.status_code < 300:
                    _event_source = httpx_sse.EventSource(_response)
                    for _sse in _event_source.iter_sse():
                        try:
                            yield typing.cast(
                                StreamedChatResponseV2,
                                construct_type(
                                    type_=StreamedChatResponseV2,  # type: ignore
                                    object_=json.loads(_sse.data),
                                ),
                            )
                        except:
                            pass
                    return
                _response.read()
                if _response.status_code == 400:
                    raise BadRequestError(
                        typing.cast(
                            typing.Optional[typing.Any],
                            construct_type(
                                type_=typing.Optional[typing.Any],  # type: ignore
                                object_=_response.json(),
                            ),
                        )
                    )
                if _response.status_code == 401:
                    raise UnauthorizedError(
                        typing.cast(
                            typing.Optional[typing.Any],
                            construct_type(
                                type_=typing.Optional[typing.Any],  # type: ignore
                                object_=_response.json(),
                            ),
                        )
                    )
                if _response.status_code == 403:
                    raise ForbiddenError(
                        typing.cast(
                            typing.Optional[typing.Any],
                            construct_type(
                                type_=typing.Optional[typing.Any],  # type: ignore
                                object_=_response.json(),
                            ),
                        )
                    )
                if _response.status_code == 404:
                    raise NotFoundError(
                        typing.cast(
                            typing.Optional[typing.Any],
                            construct_type(
                                type_=typing.Optional[typing.Any],  # type: ignore
                                object_=_response.json(),
                            ),
                        )
                    )
                if _response.status_code == 422:
                    raise UnprocessableEntityError(
                        typing.cast(
                            UnprocessableEntityErrorBody,
                            construct_type(
                                type_=UnprocessableEntityErrorBody,  # type: ignore
                                object_=_response.json(),
                            ),
                        )
                    )
                if _response.status_code == 429:
                    raise TooManyRequestsError(
                        typing.cast(
                            TooManyRequestsErrorBody,
                            construct_type(
                                type_=TooManyRequestsErrorBody,  # type: ignore
                                object_=_response.json(),
                            ),
                        )
                    )
                if _response.status_code == 499:
                    raise ClientClosedRequestError(
                        typing.cast(
                            ClientClosedRequestErrorBody,
                            construct_type(
                                type_=ClientClosedRequestErrorBody,  # type: ignore
                                object_=_response.json(),
                            ),
                        )
                    )
                if _response.status_code == 500:
                    raise InternalServerError(
                        typing.cast(
                            typing.Optional[typing.Any],
                            construct_type(
                                type_=typing.Optional[typing.Any],  # type: ignore
                                object_=_response.json(),
                            ),
                        )
                    )
                if _response.status_code == 501:
                    raise NotImplementedError(
                        typing.cast(
                            NotImplementedErrorBody,
                            construct_type(
                                type_=NotImplementedErrorBody,  # type: ignore
                                object_=_response.json(),
                            ),
                        )
                    )
                if _response.status_code == 503:
                    raise ServiceUnavailableError(
                        typing.cast(
                            typing.Optional[typing.Any],
                            construct_type(
                                type_=typing.Optional[typing.Any],  # type: ignore
                                object_=_response.json(),
                            ),
                        )
                    )
                if _response.status_code == 504:
                    raise GatewayTimeoutError(
                        typing.cast(
                            GatewayTimeoutErrorBody,
                            construct_type(
                                type_=GatewayTimeoutErrorBody,  # type: ignore
                                object_=_response.json(),
                            ),
                        )
                    )
                _response_json = _response.json()
            except JSONDecodeError:
                raise ApiError(status_code=_response.status_code, body=_response.text)
            raise ApiError(status_code=_response.status_code, body=_response_json)

    def chat(
        self,
        *,
        model: str,
        messages: ChatMessages,
        tools: typing.Optional[typing.Sequence[ToolV2]] = OMIT,
        documents: typing.Optional[typing.Sequence[V2ChatRequestDocumentsItem]] = OMIT,
        citation_options: typing.Optional[CitationOptions] = OMIT,
        response_format: typing.Optional[ResponseFormatV2] = OMIT,
        safety_mode: typing.Optional[V2ChatRequestSafetyMode] = OMIT,
        max_tokens: typing.Optional[int] = OMIT,
        stop_sequences: typing.Optional[typing.Sequence[str]] = OMIT,
        temperature: typing.Optional[float] = OMIT,
        seed: typing.Optional[int] = OMIT,
        frequency_penalty: typing.Optional[float] = OMIT,
        presence_penalty: typing.Optional[float] = OMIT,
        k: typing.Optional[float] = OMIT,
        p: typing.Optional[float] = OMIT,
        return_prompt: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ChatResponse:
        """
        Generates a text response to a user message and streams it down, token by token. To learn how to use the Chat API with streaming follow our [Text Generation guides](https://docs.cohere.com/v2/docs/chat-api).

        Follow the [Migration Guide](https://docs.cohere.com/v2/docs/migrating-v1-to-v2) for instructions on moving from API v1 to API v2.

        Parameters
        ----------
        model : str
            The name of a compatible [Cohere model](https://docs.cohere.com/v2/docs/models) (such as command-r or command-r-plus) or the ID of a [fine-tuned](https://docs.cohere.com/v2/docs/chat-fine-tuning) model.

        messages : ChatMessages

        tools : typing.Optional[typing.Sequence[ToolV2]]
            A list of available tools (functions) that the model may suggest invoking before producing a text response.

            When `tools` is passed (without `tool_results`), the `text` content in the response will be empty and the `tool_calls` field in the response will be populated with a list of tool calls that need to be made. If no calls need to be made, the `tool_calls` array will be empty.


        documents : typing.Optional[typing.Sequence[V2ChatRequestDocumentsItem]]
            A list of relevant documents that the model can cite to generate a more accurate reply. Each document is either a string or document object with content and metadata.


        citation_options : typing.Optional[CitationOptions]

        response_format : typing.Optional[ResponseFormatV2]

        safety_mode : typing.Optional[V2ChatRequestSafetyMode]
            Used to select the [safety instruction](https://docs.cohere.com/v2/docs/safety-modes) inserted into the prompt. Defaults to `CONTEXTUAL`.
            When `OFF` is specified, the safety instruction will be omitted.

            Safety modes are not yet configurable in combination with `tools`, `tool_results` and `documents` parameters.

            **Note**: This parameter is only compatible with models [Command R 08-2024](https://docs.cohere.com/v2/docs/command-r#august-2024-release), [Command R+ 08-2024](https://docs.cohere.com/v2/docs/command-r-plus#august-2024-release) and newer.


        max_tokens : typing.Optional[int]
            The maximum number of tokens the model will generate as part of the response.

            **Note**: Setting a low value may result in incomplete generations.


        stop_sequences : typing.Optional[typing.Sequence[str]]
            A list of up to 5 strings that the model will use to stop generation. If the model generates a string that matches any of the strings in the list, it will stop generating tokens and return the generated text up to that point not including the stop sequence.


        temperature : typing.Optional[float]
            Defaults to `0.3`.

            A non-negative float that tunes the degree of randomness in generation. Lower temperatures mean less random generations, and higher temperatures mean more random generations.

            Randomness can be further maximized by increasing the  value of the `p` parameter.


        seed : typing.Optional[int]
            If specified, the backend will make a best effort to sample tokens
            deterministically, such that repeated requests with the same
            seed and parameters should return the same result. However,
            determinism cannot be totally guaranteed.


        frequency_penalty : typing.Optional[float]
            Defaults to `0.0`, min value of `0.0`, max value of `1.0`.
            Used to reduce repetitiveness of generated tokens. The higher the value, the stronger a penalty is applied to previously present tokens, proportional to how many times they have already appeared in the prompt or prior generation.


        presence_penalty : typing.Optional[float]
            Defaults to `0.0`, min value of `0.0`, max value of `1.0`.
            Used to reduce repetitiveness of generated tokens. Similar to `frequency_penalty`, except that this penalty is applied equally to all tokens that have already appeared, regardless of their exact frequencies.


        k : typing.Optional[float]
            Ensures only the top `k` most likely tokens are considered for generation at each step.
            Defaults to `0`, min value of `0`, max value of `500`.


        p : typing.Optional[float]
            Ensures that only the most likely tokens, with total probability mass of `p`, are considered for generation at each step. If both `k` and `p` are enabled, `p` acts after `k`.
            Defaults to `0.75`. min value of `0.01`, max value of `0.99`.


        return_prompt : typing.Optional[bool]
            Whether to return the prompt in the response.

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

        Returns
        -------
        ChatResponse


        Examples
        --------
        from cohere import Client, ToolChatMessageV2

        client = Client(
            client_name="YOUR_CLIENT_NAME",
            token="YOUR_TOKEN",
        )
        client.v2.chat(
            model="model",
            messages=[
                ToolChatMessageV2(
                    tool_call_id="messages",
                    content="messages",
                )
            ],
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "v2/chat",
            method="POST",
            json={
                "model": model,
                "messages": convert_and_respect_annotation_metadata(
                    object_=messages, annotation=ChatMessages, direction="write"
                ),
                "tools": convert_and_respect_annotation_metadata(
                    object_=tools, annotation=typing.Sequence[ToolV2], direction="write"
                ),
                "documents": convert_and_respect_annotation_metadata(
                    object_=documents, annotation=typing.Sequence[V2ChatRequestDocumentsItem], direction="write"
                ),
                "citation_options": convert_and_respect_annotation_metadata(
                    object_=citation_options, annotation=CitationOptions, direction="write"
                ),
                "response_format": convert_and_respect_annotation_metadata(
                    object_=response_format, annotation=ResponseFormatV2, direction="write"
                ),
                "safety_mode": safety_mode,
                "max_tokens": max_tokens,
                "stop_sequences": stop_sequences,
                "temperature": temperature,
                "seed": seed,
                "frequency_penalty": frequency_penalty,
                "presence_penalty": presence_penalty,
                "k": k,
                "p": p,
                "return_prompt": return_prompt,
                "stream": False,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ChatResponse,
                    construct_type(
                        type_=ChatResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        UnprocessableEntityErrorBody,
                        construct_type(
                            type_=UnprocessableEntityErrorBody,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        TooManyRequestsErrorBody,
                        construct_type(
                            type_=TooManyRequestsErrorBody,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 499:
                raise ClientClosedRequestError(
                    typing.cast(
                        ClientClosedRequestErrorBody,
                        construct_type(
                            type_=ClientClosedRequestErrorBody,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 501:
                raise NotImplementedError(
                    typing.cast(
                        NotImplementedErrorBody,
                        construct_type(
                            type_=NotImplementedErrorBody,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 503:
                raise ServiceUnavailableError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 504:
                raise GatewayTimeoutError(
                    typing.cast(
                        GatewayTimeoutErrorBody,
                        construct_type(
                            type_=GatewayTimeoutErrorBody,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def embed(
        self,
        *,
        model: str,
        input_type: EmbedInputType,
        embedding_types: typing.Sequence[EmbeddingType],
        texts: typing.Optional[typing.Sequence[str]] = OMIT,
        images: typing.Optional[typing.Sequence[str]] = OMIT,
        truncate: typing.Optional[V2EmbedRequestTruncate] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> EmbedByTypeResponse:
        """
        This endpoint returns text embeddings. An embedding is a list of floating point numbers that captures semantic information about the text that it represents.

        Embeddings can be used to create text classifiers as well as empower semantic search. To learn more about embeddings, see the embedding page.

        If you want to learn more how to use the embedding model, have a look at the [Semantic Search Guide](/docs/semantic-search).

        Parameters
        ----------
        model : str
            Defaults to embed-english-v2.0

            The identifier of the model. Smaller "light" models are faster, while larger models will perform better. [Custom models](/docs/training-custom-models) can also be supplied with their full ID.

            Available models and corresponding embedding dimensions:

            * `embed-english-v3.0`  1024
            * `embed-multilingual-v3.0`  1024
            * `embed-english-light-v3.0`  384
            * `embed-multilingual-light-v3.0`  384

            * `embed-english-v2.0`  4096
            * `embed-english-light-v2.0`  1024
            * `embed-multilingual-v2.0`  768

        input_type : EmbedInputType

        embedding_types : typing.Sequence[EmbeddingType]
            Specifies the types of embeddings you want to get back. Not required and default is None, which returns the Embed Floats response type. Can be one or more of the following types.

            * `"float"`: Use this when you want to get back the default float embeddings. Valid for all models.
            * `"int8"`: Use this when you want to get back signed int8 embeddings. Valid for only v3 models.
            * `"uint8"`: Use this when you want to get back unsigned int8 embeddings. Valid for only v3 models.
            * `"binary"`: Use this when you want to get back signed binary embeddings. Valid for only v3 models.
            * `"ubinary"`: Use this when you want to get back unsigned binary embeddings. Valid for only v3 models.

        texts : typing.Optional[typing.Sequence[str]]
            An array of strings for the model to embed. Maximum number of texts per call is `96`. We recommend reducing the length of each text to be under `512` tokens for optimal quality.

        images : typing.Optional[typing.Sequence[str]]
            An array of image data URIs for the model to embed. Maximum number of images per call is `1`.

            The image must be a valid [data URI](https://developer.mozilla.org/en-US/docs/Web/URI/Schemes/data). The image must be in either `image/jpeg` or `image/png` format and has a maximum size of 5MB.

        truncate : typing.Optional[V2EmbedRequestTruncate]
            One of `NONE|START|END` to specify how the API will handle inputs longer than the maximum token length.

            Passing `START` will discard the start of the input. `END` will discard the end of the input. In both cases, input is discarded until the remaining input is exactly the maximum input token length for the model.

            If `NONE` is selected, when the input exceeds the maximum input token length an error will be returned.

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

        Returns
        -------
        EmbedByTypeResponse
            OK

        Examples
        --------
        from cohere import Client

        client = Client(
            client_name="YOUR_CLIENT_NAME",
            token="YOUR_TOKEN",
        )
        client.v2.embed(
            model="model",
            input_type="search_document",
            embedding_types=["float"],
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "v2/embed",
            method="POST",
            json={
                "texts": texts,
                "images": images,
                "model": model,
                "input_type": input_type,
                "embedding_types": embedding_types,
                "truncate": truncate,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    EmbedByTypeResponse,
                    construct_type(
                        type_=EmbedByTypeResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        UnprocessableEntityErrorBody,
                        construct_type(
                            type_=UnprocessableEntityErrorBody,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        TooManyRequestsErrorBody,
                        construct_type(
                            type_=TooManyRequestsErrorBody,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 499:
                raise ClientClosedRequestError(
                    typing.cast(
                        ClientClosedRequestErrorBody,
                        construct_type(
                            type_=ClientClosedRequestErrorBody,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 501:
                raise NotImplementedError(
                    typing.cast(
                        NotImplementedErrorBody,
                        construct_type(
                            type_=NotImplementedErrorBody,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 503:
                raise ServiceUnavailableError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 504:
                raise GatewayTimeoutError(
                    typing.cast(
                        GatewayTimeoutErrorBody,
                        construct_type(
                            type_=GatewayTimeoutErrorBody,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def rerank(
        self,
        *,
        model: str,
        query: str,
        documents: typing.Sequence[V2RerankRequestDocumentsItem],
        top_n: typing.Optional[int] = OMIT,
        rank_fields: typing.Optional[typing.Sequence[str]] = OMIT,
        return_documents: typing.Optional[bool] = OMIT,
        max_chunks_per_doc: typing.Optional[int] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> V2RerankResponse:
        """
        This endpoint takes in a query and a list of texts and produces an ordered array with each text assigned a relevance score.

        Parameters
        ----------
        model : str
            The identifier of the model to use, one of : `rerank-english-v3.0`, `rerank-multilingual-v3.0`, `rerank-english-v2.0`, `rerank-multilingual-v2.0`

        query : str
            The search query

        documents : typing.Sequence[V2RerankRequestDocumentsItem]
            A list of document objects or strings to rerank.
            If a document is provided the text fields is required and all other fields will be preserved in the response.

            The total max chunks (length of documents * max_chunks_per_doc) must be less than 10000.

            We recommend a maximum of 1,000 documents for optimal endpoint performance.

        top_n : typing.Optional[int]
            The number of most relevant documents or indices to return, defaults to the length of the documents

        rank_fields : typing.Optional[typing.Sequence[str]]
            If a JSON object is provided, you can specify which keys you would like to have considered for reranking. The model will rerank based on order of the fields passed in (i.e. rank_fields=['title','author','text'] will rerank using the values in title, author, text  sequentially. If the length of title, author, and text exceeds the context length of the model, the chunking will not re-consider earlier fields). If not provided, the model will use the default text field for ranking.

        return_documents : typing.Optional[bool]
            - If false, returns results without the doc text - the api will return a list of {index, relevance score} where index is inferred from the list passed into the request.
            - If true, returns results with the doc text passed in - the api will return an ordered list of {index, text, relevance score} where index + text refers to the list passed into the request.

        max_chunks_per_doc : typing.Optional[int]
            The maximum number of chunks to produce internally from a document

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

        Returns
        -------
        V2RerankResponse
            OK

        Examples
        --------
        from cohere import Client

        client = Client(
            client_name="YOUR_CLIENT_NAME",
            token="YOUR_TOKEN",
        )
        client.v2.rerank(
            model="model",
            query="query",
            documents=["documents"],
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "v2/rerank",
            method="POST",
            json={
                "model": model,
                "query": query,
                "documents": convert_and_respect_annotation_metadata(
                    object_=documents, annotation=typing.Sequence[V2RerankRequestDocumentsItem], direction="write"
                ),
                "top_n": top_n,
                "rank_fields": rank_fields,
                "return_documents": return_documents,
                "max_chunks_per_doc": max_chunks_per_doc,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    V2RerankResponse,
                    construct_type(
                        type_=V2RerankResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        UnprocessableEntityErrorBody,
                        construct_type(
                            type_=UnprocessableEntityErrorBody,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        TooManyRequestsErrorBody,
                        construct_type(
                            type_=TooManyRequestsErrorBody,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 499:
                raise ClientClosedRequestError(
                    typing.cast(
                        ClientClosedRequestErrorBody,
                        construct_type(
                            type_=ClientClosedRequestErrorBody,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 501:
                raise NotImplementedError(
                    typing.cast(
                        NotImplementedErrorBody,
                        construct_type(
                            type_=NotImplementedErrorBody,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 503:
                raise ServiceUnavailableError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 504:
                raise GatewayTimeoutError(
                    typing.cast(
                        GatewayTimeoutErrorBody,
                        construct_type(
                            type_=GatewayTimeoutErrorBody,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)


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

    async def chat_stream(
        self,
        *,
        model: str,
        messages: ChatMessages,
        tools: typing.Optional[typing.Sequence[ToolV2]] = OMIT,
        documents: typing.Optional[typing.Sequence[V2ChatStreamRequestDocumentsItem]] = OMIT,
        citation_options: typing.Optional[CitationOptions] = OMIT,
        response_format: typing.Optional[ResponseFormatV2] = OMIT,
        safety_mode: typing.Optional[V2ChatStreamRequestSafetyMode] = OMIT,
        max_tokens: typing.Optional[int] = OMIT,
        stop_sequences: typing.Optional[typing.Sequence[str]] = OMIT,
        temperature: typing.Optional[float] = OMIT,
        seed: typing.Optional[int] = OMIT,
        frequency_penalty: typing.Optional[float] = OMIT,
        presence_penalty: typing.Optional[float] = OMIT,
        k: typing.Optional[float] = OMIT,
        p: typing.Optional[float] = OMIT,
        return_prompt: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.AsyncIterator[StreamedChatResponseV2]:
        """
        Generates a text response to a user message and streams it down, token by token. To learn how to use the Chat API with streaming follow our [Text Generation guides](https://docs.cohere.com/v2/docs/chat-api).

        Follow the [Migration Guide](https://docs.cohere.com/v2/docs/migrating-v1-to-v2) for instructions on moving from API v1 to API v2.

        Parameters
        ----------
        model : str
            The name of a compatible [Cohere model](https://docs.cohere.com/v2/docs/models) (such as command-r or command-r-plus) or the ID of a [fine-tuned](https://docs.cohere.com/v2/docs/chat-fine-tuning) model.

        messages : ChatMessages

        tools : typing.Optional[typing.Sequence[ToolV2]]
            A list of available tools (functions) that the model may suggest invoking before producing a text response.

            When `tools` is passed (without `tool_results`), the `text` content in the response will be empty and the `tool_calls` field in the response will be populated with a list of tool calls that need to be made. If no calls need to be made, the `tool_calls` array will be empty.


        documents : typing.Optional[typing.Sequence[V2ChatStreamRequestDocumentsItem]]
            A list of relevant documents that the model can cite to generate a more accurate reply. Each document is either a string or document object with content and metadata.


        citation_options : typing.Optional[CitationOptions]

        response_format : typing.Optional[ResponseFormatV2]

        safety_mode : typing.Optional[V2ChatStreamRequestSafetyMode]
            Used to select the [safety instruction](https://docs.cohere.com/v2/docs/safety-modes) inserted into the prompt. Defaults to `CONTEXTUAL`.
            When `OFF` is specified, the safety instruction will be omitted.

            Safety modes are not yet configurable in combination with `tools`, `tool_results` and `documents` parameters.

            **Note**: This parameter is only compatible with models [Command R 08-2024](https://docs.cohere.com/v2/docs/command-r#august-2024-release), [Command R+ 08-2024](https://docs.cohere.com/v2/docs/command-r-plus#august-2024-release) and newer.


        max_tokens : typing.Optional[int]
            The maximum number of tokens the model will generate as part of the response.

            **Note**: Setting a low value may result in incomplete generations.


        stop_sequences : typing.Optional[typing.Sequence[str]]
            A list of up to 5 strings that the model will use to stop generation. If the model generates a string that matches any of the strings in the list, it will stop generating tokens and return the generated text up to that point not including the stop sequence.


        temperature : typing.Optional[float]
            Defaults to `0.3`.

            A non-negative float that tunes the degree of randomness in generation. Lower temperatures mean less random generations, and higher temperatures mean more random generations.

            Randomness can be further maximized by increasing the  value of the `p` parameter.


        seed : typing.Optional[int]
            If specified, the backend will make a best effort to sample tokens
            deterministically, such that repeated requests with the same
            seed and parameters should return the same result. However,
            determinism cannot be totally guaranteed.


        frequency_penalty : typing.Optional[float]
            Defaults to `0.0`, min value of `0.0`, max value of `1.0`.
            Used to reduce repetitiveness of generated tokens. The higher the value, the stronger a penalty is applied to previously present tokens, proportional to how many times they have already appeared in the prompt or prior generation.


        presence_penalty : typing.Optional[float]
            Defaults to `0.0`, min value of `0.0`, max value of `1.0`.
            Used to reduce repetitiveness of generated tokens. Similar to `frequency_penalty`, except that this penalty is applied equally to all tokens that have already appeared, regardless of their exact frequencies.


        k : typing.Optional[float]
            Ensures only the top `k` most likely tokens are considered for generation at each step.
            Defaults to `0`, min value of `0`, max value of `500`.


        p : typing.Optional[float]
            Ensures that only the most likely tokens, with total probability mass of `p`, are considered for generation at each step. If both `k` and `p` are enabled, `p` acts after `k`.
            Defaults to `0.75`. min value of `0.01`, max value of `0.99`.


        return_prompt : typing.Optional[bool]
            Whether to return the prompt in the response.

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

        Yields
        ------
        typing.AsyncIterator[StreamedChatResponseV2]


        Examples
        --------
        import asyncio

        from cohere import (
            AsyncClient,
            CitationOptions,
            TextResponseFormatV2,
            ToolV2,
            ToolV2Function,
            UserChatMessageV2,
        )

        client = AsyncClient(
            client_name="YOUR_CLIENT_NAME",
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            response = await client.v2.chat_stream(
                model="string",
                messages=[
                    UserChatMessageV2(
                        content="string",
                    )
                ],
                tools=[
                    ToolV2(
                        function=ToolV2Function(
                            name="string",
                            description="string",
                            parameters={"string": {"key": "value"}},
                        ),
                    )
                ],
                documents=["string"],
                citation_options=CitationOptions(
                    mode="FAST",
                ),
                response_format=TextResponseFormatV2(),
                safety_mode="CONTEXTUAL",
                max_tokens=1,
                stop_sequences=["string"],
                temperature=1.1,
                seed=1,
                frequency_penalty=1.1,
                presence_penalty=1.1,
                k=1.1,
                p=1.1,
                return_prompt=True,
            )
            async for chunk in response:
                yield chunk


        asyncio.run(main())
        """
        async with self._client_wrapper.httpx_client.stream(
            "v2/chat",
            method="POST",
            json={
                "model": model,
                "messages": convert_and_respect_annotation_metadata(
                    object_=messages, annotation=ChatMessages, direction="write"
                ),
                "tools": convert_and_respect_annotation_metadata(
                    object_=tools, annotation=typing.Sequence[ToolV2], direction="write"
                ),
                "documents": convert_and_respect_annotation_metadata(
                    object_=documents, annotation=typing.Sequence[V2ChatStreamRequestDocumentsItem], direction="write"
                ),
                "citation_options": convert_and_respect_annotation_metadata(
                    object_=citation_options, annotation=CitationOptions, direction="write"
                ),
                "response_format": convert_and_respect_annotation_metadata(
                    object_=response_format, annotation=ResponseFormatV2, direction="write"
                ),
                "safety_mode": safety_mode,
                "max_tokens": max_tokens,
                "stop_sequences": stop_sequences,
                "temperature": temperature,
                "seed": seed,
                "frequency_penalty": frequency_penalty,
                "presence_penalty": presence_penalty,
                "k": k,
                "p": p,
                "return_prompt": return_prompt,
                "stream": True,
            },
            request_options=request_options,
            omit=OMIT,
        ) as _response:
            try:
                if 200 <= _response.status_code < 300:
                    _event_source = httpx_sse.EventSource(_response)
                    async for _sse in _event_source.aiter_sse():
                        try:
                            yield typing.cast(
                                StreamedChatResponseV2,
                                construct_type(
                                    type_=StreamedChatResponseV2,  # type: ignore
                                    object_=json.loads(_sse.data),
                                ),
                            )
                        except:
                            pass
                    return
                await _response.aread()
                if _response.status_code == 400:
                    raise BadRequestError(
                        typing.cast(
                            typing.Optional[typing.Any],
                            construct_type(
                                type_=typing.Optional[typing.Any],  # type: ignore
                                object_=_response.json(),
                            ),
                        )
                    )
                if _response.status_code == 401:
                    raise UnauthorizedError(
                        typing.cast(
                            typing.Optional[typing.Any],
                            construct_type(
                                type_=typing.Optional[typing.Any],  # type: ignore
                                object_=_response.json(),
                            ),
                        )
                    )
                if _response.status_code == 403:
                    raise ForbiddenError(
                        typing.cast(
                            typing.Optional[typing.Any],
                            construct_type(
                                type_=typing.Optional[typing.Any],  # type: ignore
                                object_=_response.json(),
                            ),
                        )
                    )
                if _response.status_code == 404:
                    raise NotFoundError(
                        typing.cast(
                            typing.Optional[typing.Any],
                            construct_type(
                                type_=typing.Optional[typing.Any],  # type: ignore
                                object_=_response.json(),
                            ),
                        )
                    )
                if _response.status_code == 422:
                    raise UnprocessableEntityError(
                        typing.cast(
                            UnprocessableEntityErrorBody,
                            construct_type(
                                type_=UnprocessableEntityErrorBody,  # type: ignore
                                object_=_response.json(),
                            ),
                        )
                    )
                if _response.status_code == 429:
                    raise TooManyRequestsError(
                        typing.cast(
                            TooManyRequestsErrorBody,
                            construct_type(
                                type_=TooManyRequestsErrorBody,  # type: ignore
                                object_=_response.json(),
                            ),
                        )
                    )
                if _response.status_code == 499:
                    raise ClientClosedRequestError(
                        typing.cast(
                            ClientClosedRequestErrorBody,
                            construct_type(
                                type_=ClientClosedRequestErrorBody,  # type: ignore
                                object_=_response.json(),
                            ),
                        )
                    )
                if _response.status_code == 500:
                    raise InternalServerError(
                        typing.cast(
                            typing.Optional[typing.Any],
                            construct_type(
                                type_=typing.Optional[typing.Any],  # type: ignore
                                object_=_response.json(),
                            ),
                        )
                    )
                if _response.status_code == 501:
                    raise NotImplementedError(
                        typing.cast(
                            NotImplementedErrorBody,
                            construct_type(
                                type_=NotImplementedErrorBody,  # type: ignore
                                object_=_response.json(),
                            ),
                        )
                    )
                if _response.status_code == 503:
                    raise ServiceUnavailableError(
                        typing.cast(
                            typing.Optional[typing.Any],
                            construct_type(
                                type_=typing.Optional[typing.Any],  # type: ignore
                                object_=_response.json(),
                            ),
                        )
                    )
                if _response.status_code == 504:
                    raise GatewayTimeoutError(
                        typing.cast(
                            GatewayTimeoutErrorBody,
                            construct_type(
                                type_=GatewayTimeoutErrorBody,  # type: ignore
                                object_=_response.json(),
                            ),
                        )
                    )
                _response_json = _response.json()
            except JSONDecodeError:
                raise ApiError(status_code=_response.status_code, body=_response.text)
            raise ApiError(status_code=_response.status_code, body=_response_json)

    async def chat(
        self,
        *,
        model: str,
        messages: ChatMessages,
        tools: typing.Optional[typing.Sequence[ToolV2]] = OMIT,
        documents: typing.Optional[typing.Sequence[V2ChatRequestDocumentsItem]] = OMIT,
        citation_options: typing.Optional[CitationOptions] = OMIT,
        response_format: typing.Optional[ResponseFormatV2] = OMIT,
        safety_mode: typing.Optional[V2ChatRequestSafetyMode] = OMIT,
        max_tokens: typing.Optional[int] = OMIT,
        stop_sequences: typing.Optional[typing.Sequence[str]] = OMIT,
        temperature: typing.Optional[float] = OMIT,
        seed: typing.Optional[int] = OMIT,
        frequency_penalty: typing.Optional[float] = OMIT,
        presence_penalty: typing.Optional[float] = OMIT,
        k: typing.Optional[float] = OMIT,
        p: typing.Optional[float] = OMIT,
        return_prompt: typing.Optional[bool] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ChatResponse:
        """
        Generates a text response to a user message and streams it down, token by token. To learn how to use the Chat API with streaming follow our [Text Generation guides](https://docs.cohere.com/v2/docs/chat-api).

        Follow the [Migration Guide](https://docs.cohere.com/v2/docs/migrating-v1-to-v2) for instructions on moving from API v1 to API v2.

        Parameters
        ----------
        model : str
            The name of a compatible [Cohere model](https://docs.cohere.com/v2/docs/models) (such as command-r or command-r-plus) or the ID of a [fine-tuned](https://docs.cohere.com/v2/docs/chat-fine-tuning) model.

        messages : ChatMessages

        tools : typing.Optional[typing.Sequence[ToolV2]]
            A list of available tools (functions) that the model may suggest invoking before producing a text response.

            When `tools` is passed (without `tool_results`), the `text` content in the response will be empty and the `tool_calls` field in the response will be populated with a list of tool calls that need to be made. If no calls need to be made, the `tool_calls` array will be empty.


        documents : typing.Optional[typing.Sequence[V2ChatRequestDocumentsItem]]
            A list of relevant documents that the model can cite to generate a more accurate reply. Each document is either a string or document object with content and metadata.


        citation_options : typing.Optional[CitationOptions]

        response_format : typing.Optional[ResponseFormatV2]

        safety_mode : typing.Optional[V2ChatRequestSafetyMode]
            Used to select the [safety instruction](https://docs.cohere.com/v2/docs/safety-modes) inserted into the prompt. Defaults to `CONTEXTUAL`.
            When `OFF` is specified, the safety instruction will be omitted.

            Safety modes are not yet configurable in combination with `tools`, `tool_results` and `documents` parameters.

            **Note**: This parameter is only compatible with models [Command R 08-2024](https://docs.cohere.com/v2/docs/command-r#august-2024-release), [Command R+ 08-2024](https://docs.cohere.com/v2/docs/command-r-plus#august-2024-release) and newer.


        max_tokens : typing.Optional[int]
            The maximum number of tokens the model will generate as part of the response.

            **Note**: Setting a low value may result in incomplete generations.


        stop_sequences : typing.Optional[typing.Sequence[str]]
            A list of up to 5 strings that the model will use to stop generation. If the model generates a string that matches any of the strings in the list, it will stop generating tokens and return the generated text up to that point not including the stop sequence.


        temperature : typing.Optional[float]
            Defaults to `0.3`.

            A non-negative float that tunes the degree of randomness in generation. Lower temperatures mean less random generations, and higher temperatures mean more random generations.

            Randomness can be further maximized by increasing the  value of the `p` parameter.


        seed : typing.Optional[int]
            If specified, the backend will make a best effort to sample tokens
            deterministically, such that repeated requests with the same
            seed and parameters should return the same result. However,
            determinism cannot be totally guaranteed.


        frequency_penalty : typing.Optional[float]
            Defaults to `0.0`, min value of `0.0`, max value of `1.0`.
            Used to reduce repetitiveness of generated tokens. The higher the value, the stronger a penalty is applied to previously present tokens, proportional to how many times they have already appeared in the prompt or prior generation.


        presence_penalty : typing.Optional[float]
            Defaults to `0.0`, min value of `0.0`, max value of `1.0`.
            Used to reduce repetitiveness of generated tokens. Similar to `frequency_penalty`, except that this penalty is applied equally to all tokens that have already appeared, regardless of their exact frequencies.


        k : typing.Optional[float]
            Ensures only the top `k` most likely tokens are considered for generation at each step.
            Defaults to `0`, min value of `0`, max value of `500`.


        p : typing.Optional[float]
            Ensures that only the most likely tokens, with total probability mass of `p`, are considered for generation at each step. If both `k` and `p` are enabled, `p` acts after `k`.
            Defaults to `0.75`. min value of `0.01`, max value of `0.99`.


        return_prompt : typing.Optional[bool]
            Whether to return the prompt in the response.

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

        Returns
        -------
        ChatResponse


        Examples
        --------
        import asyncio

        from cohere import AsyncClient, ToolChatMessageV2

        client = AsyncClient(
            client_name="YOUR_CLIENT_NAME",
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.v2.chat(
                model="model",
                messages=[
                    ToolChatMessageV2(
                        tool_call_id="messages",
                        content="messages",
                    )
                ],
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v2/chat",
            method="POST",
            json={
                "model": model,
                "messages": convert_and_respect_annotation_metadata(
                    object_=messages, annotation=ChatMessages, direction="write"
                ),
                "tools": convert_and_respect_annotation_metadata(
                    object_=tools, annotation=typing.Sequence[ToolV2], direction="write"
                ),
                "documents": convert_and_respect_annotation_metadata(
                    object_=documents, annotation=typing.Sequence[V2ChatRequestDocumentsItem], direction="write"
                ),
                "citation_options": convert_and_respect_annotation_metadata(
                    object_=citation_options, annotation=CitationOptions, direction="write"
                ),
                "response_format": convert_and_respect_annotation_metadata(
                    object_=response_format, annotation=ResponseFormatV2, direction="write"
                ),
                "safety_mode": safety_mode,
                "max_tokens": max_tokens,
                "stop_sequences": stop_sequences,
                "temperature": temperature,
                "seed": seed,
                "frequency_penalty": frequency_penalty,
                "presence_penalty": presence_penalty,
                "k": k,
                "p": p,
                "return_prompt": return_prompt,
                "stream": False,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ChatResponse,
                    construct_type(
                        type_=ChatResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        UnprocessableEntityErrorBody,
                        construct_type(
                            type_=UnprocessableEntityErrorBody,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        TooManyRequestsErrorBody,
                        construct_type(
                            type_=TooManyRequestsErrorBody,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 499:
                raise ClientClosedRequestError(
                    typing.cast(
                        ClientClosedRequestErrorBody,
                        construct_type(
                            type_=ClientClosedRequestErrorBody,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 501:
                raise NotImplementedError(
                    typing.cast(
                        NotImplementedErrorBody,
                        construct_type(
                            type_=NotImplementedErrorBody,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 503:
                raise ServiceUnavailableError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 504:
                raise GatewayTimeoutError(
                    typing.cast(
                        GatewayTimeoutErrorBody,
                        construct_type(
                            type_=GatewayTimeoutErrorBody,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def embed(
        self,
        *,
        model: str,
        input_type: EmbedInputType,
        embedding_types: typing.Sequence[EmbeddingType],
        texts: typing.Optional[typing.Sequence[str]] = OMIT,
        images: typing.Optional[typing.Sequence[str]] = OMIT,
        truncate: typing.Optional[V2EmbedRequestTruncate] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> EmbedByTypeResponse:
        """
        This endpoint returns text embeddings. An embedding is a list of floating point numbers that captures semantic information about the text that it represents.

        Embeddings can be used to create text classifiers as well as empower semantic search. To learn more about embeddings, see the embedding page.

        If you want to learn more how to use the embedding model, have a look at the [Semantic Search Guide](/docs/semantic-search).

        Parameters
        ----------
        model : str
            Defaults to embed-english-v2.0

            The identifier of the model. Smaller "light" models are faster, while larger models will perform better. [Custom models](/docs/training-custom-models) can also be supplied with their full ID.

            Available models and corresponding embedding dimensions:

            * `embed-english-v3.0`  1024
            * `embed-multilingual-v3.0`  1024
            * `embed-english-light-v3.0`  384
            * `embed-multilingual-light-v3.0`  384

            * `embed-english-v2.0`  4096
            * `embed-english-light-v2.0`  1024
            * `embed-multilingual-v2.0`  768

        input_type : EmbedInputType

        embedding_types : typing.Sequence[EmbeddingType]
            Specifies the types of embeddings you want to get back. Not required and default is None, which returns the Embed Floats response type. Can be one or more of the following types.

            * `"float"`: Use this when you want to get back the default float embeddings. Valid for all models.
            * `"int8"`: Use this when you want to get back signed int8 embeddings. Valid for only v3 models.
            * `"uint8"`: Use this when you want to get back unsigned int8 embeddings. Valid for only v3 models.
            * `"binary"`: Use this when you want to get back signed binary embeddings. Valid for only v3 models.
            * `"ubinary"`: Use this when you want to get back unsigned binary embeddings. Valid for only v3 models.

        texts : typing.Optional[typing.Sequence[str]]
            An array of strings for the model to embed. Maximum number of texts per call is `96`. We recommend reducing the length of each text to be under `512` tokens for optimal quality.

        images : typing.Optional[typing.Sequence[str]]
            An array of image data URIs for the model to embed. Maximum number of images per call is `1`.

            The image must be a valid [data URI](https://developer.mozilla.org/en-US/docs/Web/URI/Schemes/data). The image must be in either `image/jpeg` or `image/png` format and has a maximum size of 5MB.

        truncate : typing.Optional[V2EmbedRequestTruncate]
            One of `NONE|START|END` to specify how the API will handle inputs longer than the maximum token length.

            Passing `START` will discard the start of the input. `END` will discard the end of the input. In both cases, input is discarded until the remaining input is exactly the maximum input token length for the model.

            If `NONE` is selected, when the input exceeds the maximum input token length an error will be returned.

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

        Returns
        -------
        EmbedByTypeResponse
            OK

        Examples
        --------
        import asyncio

        from cohere import AsyncClient

        client = AsyncClient(
            client_name="YOUR_CLIENT_NAME",
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.v2.embed(
                model="model",
                input_type="search_document",
                embedding_types=["float"],
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v2/embed",
            method="POST",
            json={
                "texts": texts,
                "images": images,
                "model": model,
                "input_type": input_type,
                "embedding_types": embedding_types,
                "truncate": truncate,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    EmbedByTypeResponse,
                    construct_type(
                        type_=EmbedByTypeResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        UnprocessableEntityErrorBody,
                        construct_type(
                            type_=UnprocessableEntityErrorBody,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        TooManyRequestsErrorBody,
                        construct_type(
                            type_=TooManyRequestsErrorBody,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 499:
                raise ClientClosedRequestError(
                    typing.cast(
                        ClientClosedRequestErrorBody,
                        construct_type(
                            type_=ClientClosedRequestErrorBody,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 501:
                raise NotImplementedError(
                    typing.cast(
                        NotImplementedErrorBody,
                        construct_type(
                            type_=NotImplementedErrorBody,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 503:
                raise ServiceUnavailableError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 504:
                raise GatewayTimeoutError(
                    typing.cast(
                        GatewayTimeoutErrorBody,
                        construct_type(
                            type_=GatewayTimeoutErrorBody,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def rerank(
        self,
        *,
        model: str,
        query: str,
        documents: typing.Sequence[V2RerankRequestDocumentsItem],
        top_n: typing.Optional[int] = OMIT,
        rank_fields: typing.Optional[typing.Sequence[str]] = OMIT,
        return_documents: typing.Optional[bool] = OMIT,
        max_chunks_per_doc: typing.Optional[int] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> V2RerankResponse:
        """
        This endpoint takes in a query and a list of texts and produces an ordered array with each text assigned a relevance score.

        Parameters
        ----------
        model : str
            The identifier of the model to use, one of : `rerank-english-v3.0`, `rerank-multilingual-v3.0`, `rerank-english-v2.0`, `rerank-multilingual-v2.0`

        query : str
            The search query

        documents : typing.Sequence[V2RerankRequestDocumentsItem]
            A list of document objects or strings to rerank.
            If a document is provided the text fields is required and all other fields will be preserved in the response.

            The total max chunks (length of documents * max_chunks_per_doc) must be less than 10000.

            We recommend a maximum of 1,000 documents for optimal endpoint performance.

        top_n : typing.Optional[int]
            The number of most relevant documents or indices to return, defaults to the length of the documents

        rank_fields : typing.Optional[typing.Sequence[str]]
            If a JSON object is provided, you can specify which keys you would like to have considered for reranking. The model will rerank based on order of the fields passed in (i.e. rank_fields=['title','author','text'] will rerank using the values in title, author, text  sequentially. If the length of title, author, and text exceeds the context length of the model, the chunking will not re-consider earlier fields). If not provided, the model will use the default text field for ranking.

        return_documents : typing.Optional[bool]
            - If false, returns results without the doc text - the api will return a list of {index, relevance score} where index is inferred from the list passed into the request.
            - If true, returns results with the doc text passed in - the api will return an ordered list of {index, text, relevance score} where index + text refers to the list passed into the request.

        max_chunks_per_doc : typing.Optional[int]
            The maximum number of chunks to produce internally from a document

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

        Returns
        -------
        V2RerankResponse
            OK

        Examples
        --------
        import asyncio

        from cohere import AsyncClient

        client = AsyncClient(
            client_name="YOUR_CLIENT_NAME",
            token="YOUR_TOKEN",
        )


        async def main() -> None:
            await client.v2.rerank(
                model="model",
                query="query",
                documents=["documents"],
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v2/rerank",
            method="POST",
            json={
                "model": model,
                "query": query,
                "documents": convert_and_respect_annotation_metadata(
                    object_=documents, annotation=typing.Sequence[V2RerankRequestDocumentsItem], direction="write"
                ),
                "top_n": top_n,
                "rank_fields": rank_fields,
                "return_documents": return_documents,
                "max_chunks_per_doc": max_chunks_per_doc,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    V2RerankResponse,
                    construct_type(
                        type_=V2RerankResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequestError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFoundError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        UnprocessableEntityErrorBody,
                        construct_type(
                            type_=UnprocessableEntityErrorBody,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    typing.cast(
                        TooManyRequestsErrorBody,
                        construct_type(
                            type_=TooManyRequestsErrorBody,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 499:
                raise ClientClosedRequestError(
                    typing.cast(
                        ClientClosedRequestErrorBody,
                        construct_type(
                            type_=ClientClosedRequestErrorBody,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 501:
                raise NotImplementedError(
                    typing.cast(
                        NotImplementedErrorBody,
                        construct_type(
                            type_=NotImplementedErrorBody,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 503:
                raise ServiceUnavailableError(
                    typing.cast(
                        typing.Optional[typing.Any],
                        construct_type(
                            type_=typing.Optional[typing.Any],  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 504:
                raise GatewayTimeoutError(
                    typing.cast(
                        GatewayTimeoutErrorBody,
                        construct_type(
                            type_=GatewayTimeoutErrorBody,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)
