Skip to content

gemini.types

Types for interacting with Google's Gemini models using Mirascope.

BaseAsyncStream

Bases: Generic[BaseCallResponseChunkT, UserMessageParamT, AssistantMessageParamT, BaseToolT], ABC

A base class for async streaming responses from LLMs.

Source code in mirascope/base/types.py
class BaseAsyncStream(
    Generic[
        BaseCallResponseChunkT,
        UserMessageParamT,
        AssistantMessageParamT,
        BaseToolT,
    ],
    ABC,
):
    """A base class for async streaming responses from LLMs."""

    stream: AsyncGenerator[BaseCallResponseChunkT, None]
    message_param_type: type[AssistantMessageParamT]

    cost: Optional[float] = None
    user_message_param: Optional[UserMessageParamT] = None
    message_param: AssistantMessageParamT

    def __init__(
        self,
        stream: AsyncGenerator[BaseCallResponseChunkT, None],
        message_param_type: type[AssistantMessageParamT],
    ):
        """Initializes an instance of `BaseAsyncStream`."""
        self.stream = stream
        self.message_param_type = message_param_type

    def __aiter__(
        self,
    ) -> AsyncGenerator[tuple[BaseCallResponseChunkT, Optional[BaseToolT]], None]:
        """Iterates over the stream and stores useful information."""

        async def generator():
            content = ""
            async for chunk in self.stream:
                content += chunk.content
                if chunk.cost is not None:
                    self.cost = chunk.cost
                yield chunk, None
                self.user_message_param = chunk.user_message_param
            kwargs = {"role": "assistant"}
            if "message" in self.message_param_type.__annotations__:
                kwargs["message"] = content
            else:
                kwargs["content"] = content
            self.message_param = self.message_param_type(**kwargs)

        return generator()

BaseCallParams

Bases: BaseModel, Generic[BaseToolT]

The parameters with which to make a call.

Source code in mirascope/base/types.py
class BaseCallParams(BaseModel, Generic[BaseToolT]):
    """The parameters with which to make a call."""

    model: str
    tools: Optional[list[Union[Callable, Type[BaseToolT]]]] = None

    model_config = ConfigDict(extra="allow", arbitrary_types_allowed=True)

    def kwargs(
        self,
        tool_type: Optional[Type[BaseToolT]] = None,
        exclude: Optional[set[str]] = None,
    ) -> dict[str, Any]:
        """Returns all parameters for the call as a keyword arguments dictionary."""
        extra_exclude = {"tools"}
        exclude = extra_exclude if exclude is None else exclude.union(extra_exclude)
        kwargs = {
            key: value
            for key, value in self.model_dump(exclude=exclude).items()
            if value is not None
        }
        if not self.tools or tool_type is None:
            return kwargs
        kwargs["tools"] = [
            tool if isclass(tool) else convert_function_to_tool(tool, tool_type)
            for tool in self.tools
        ]
        return kwargs

kwargs(tool_type=None, exclude=None)

Returns all parameters for the call as a keyword arguments dictionary.

Source code in mirascope/base/types.py
def kwargs(
    self,
    tool_type: Optional[Type[BaseToolT]] = None,
    exclude: Optional[set[str]] = None,
) -> dict[str, Any]:
    """Returns all parameters for the call as a keyword arguments dictionary."""
    extra_exclude = {"tools"}
    exclude = extra_exclude if exclude is None else exclude.union(extra_exclude)
    kwargs = {
        key: value
        for key, value in self.model_dump(exclude=exclude).items()
        if value is not None
    }
    if not self.tools or tool_type is None:
        return kwargs
    kwargs["tools"] = [
        tool if isclass(tool) else convert_function_to_tool(tool, tool_type)
        for tool in self.tools
    ]
    return kwargs

BaseCallResponse

Bases: BaseModel, Generic[ResponseT, BaseToolT], ABC

A base abstract interface for LLM call responses.

Attributes:

Name Type Description
response ResponseT

The original response from whichever model response this wraps.

Source code in mirascope/base/types.py
class BaseCallResponse(BaseModel, Generic[ResponseT, BaseToolT], ABC):
    """A base abstract interface for LLM call responses.

    Attributes:
        response: The original response from whichever model response this wraps.
    """

    response: ResponseT
    user_message_param: Optional[Any] = None
    tool_types: Optional[list[Type[BaseToolT]]] = None
    start_time: float  # The start time of the completion in ms
    end_time: float  # The end time of the completion in ms
    cost: Optional[float] = None  # The cost of the completion in dollars

    model_config = ConfigDict(extra="allow", arbitrary_types_allowed=True)

    @property
    @abstractmethod
    def message_param(self) -> Any:
        """Returns the assistant's response as a message parameter."""
        ...  # pragma: no cover

    @property
    @abstractmethod
    def tools(self) -> Optional[list[BaseToolT]]:
        """Returns the tools for the 0th choice message."""
        ...  # pragma: no cover

    @property
    @abstractmethod
    def tool(self) -> Optional[BaseToolT]:
        """Returns the 0th tool for the 0th choice message."""
        ...  # pragma: no cover

    @classmethod
    @abstractmethod
    def tool_message_params(
        cls, tools_and_outputs: list[tuple[BaseToolT, Any]]
    ) -> list[Any]:
        """Returns the tool message parameters for tool call results."""
        ...  # pragma: no cover

    @property
    @abstractmethod
    def content(self) -> str:
        """Should return the string content of the response.

        If there are multiple choices in a response, this method should select the 0th
        choice and return it's string content.

        If there is no string content (e.g. when using tools), this method must return
        the empty string.
        """
        ...  # pragma: no cover

    @property
    @abstractmethod
    def finish_reasons(self) -> Union[None, list[str]]:
        """Should return the finish reasons of the response.

        If there is no finish reason, this method must return None.
        """
        ...  # pragma: no cover

    @property
    @abstractmethod
    def model(self) -> Optional[str]:
        """Should return the name of the response model."""
        ...  # pragma: no cover

    @property
    @abstractmethod
    def id(self) -> Optional[str]:
        """Should return the id of the response."""
        ...  # pragma: no cover

    @property
    @abstractmethod
    def usage(self) -> Any:
        """Should return the usage of the response.

        If there is no usage, this method must return None.
        """
        ...  # pragma: no cover

    @property
    @abstractmethod
    def input_tokens(self) -> Optional[Union[int, float]]:
        """Should return the number of input tokens.

        If there is no input_tokens, this method must return None.
        """
        ...  # pragma: no cover

    @property
    @abstractmethod
    def output_tokens(self) -> Optional[Union[int, float]]:
        """Should return the number of output tokens.

        If there is no output_tokens, this method must return None.
        """
        ...  # pragma: no cover

content: str abstractmethod property

Should return the string content of the response.

If there are multiple choices in a response, this method should select the 0th choice and return it's string content.

If there is no string content (e.g. when using tools), this method must return the empty string.

finish_reasons: Union[None, list[str]] abstractmethod property

Should return the finish reasons of the response.

If there is no finish reason, this method must return None.

id: Optional[str] abstractmethod property

Should return the id of the response.

input_tokens: Optional[Union[int, float]] abstractmethod property

Should return the number of input tokens.

If there is no input_tokens, this method must return None.

message_param: Any abstractmethod property

Returns the assistant's response as a message parameter.

model: Optional[str] abstractmethod property

Should return the name of the response model.

output_tokens: Optional[Union[int, float]] abstractmethod property

Should return the number of output tokens.

If there is no output_tokens, this method must return None.

tool: Optional[BaseToolT] abstractmethod property

Returns the 0th tool for the 0th choice message.

tools: Optional[list[BaseToolT]] abstractmethod property

Returns the tools for the 0th choice message.

usage: Any abstractmethod property

Should return the usage of the response.

If there is no usage, this method must return None.

tool_message_params(tools_and_outputs) abstractmethod classmethod

Returns the tool message parameters for tool call results.

Source code in mirascope/base/types.py
@classmethod
@abstractmethod
def tool_message_params(
    cls, tools_and_outputs: list[tuple[BaseToolT, Any]]
) -> list[Any]:
    """Returns the tool message parameters for tool call results."""
    ...  # pragma: no cover

BaseCallResponseChunk

Bases: BaseModel, Generic[ChunkT, BaseToolT], ABC

A base abstract interface for LLM streaming response chunks.

Attributes:

Name Type Description
response

The original response chunk from whichever model response this wraps.

Source code in mirascope/base/types.py
class BaseCallResponseChunk(BaseModel, Generic[ChunkT, BaseToolT], ABC):
    """A base abstract interface for LLM streaming response chunks.

    Attributes:
        response: The original response chunk from whichever model response this wraps.
    """

    chunk: ChunkT
    user_message_param: Optional[Any] = None
    tool_types: Optional[list[Type[BaseToolT]]] = None
    cost: Optional[float] = None  # The cost of the completion in dollars
    model_config = ConfigDict(extra="allow", arbitrary_types_allowed=True)

    @property
    @abstractmethod
    def content(self) -> str:
        """Should return the string content of the response chunk.

        If there are multiple choices in a chunk, this method should select the 0th
        choice and return it's string content.

        If there is no string content (e.g. when using tools), this method must return
        the empty string.
        """
        ...  # pragma: no cover

    @property
    @abstractmethod
    def model(self) -> Optional[str]:
        """Should return the name of the response model."""
        ...  # pragma: no cover

    @property
    @abstractmethod
    def id(self) -> Optional[str]:
        """Should return the id of the response."""
        ...  # pragma: no cover

    @property
    @abstractmethod
    def finish_reasons(self) -> Union[None, list[str]]:
        """Should return the finish reasons of the response.

        If there is no finish reason, this method must return None.
        """
        ...  # pragma: no cover

    @property
    @abstractmethod
    def usage(self) -> Any:
        """Should return the usage of the response.

        If there is no usage, this method must return None.
        """
        ...  # pragma: no cover

    @property
    @abstractmethod
    def input_tokens(self) -> Optional[Union[int, float]]:
        """Should return the number of input tokens.

        If there is no input_tokens, this method must return None.
        """
        ...  # pragma: no cover

    @property
    @abstractmethod
    def output_tokens(self) -> Optional[Union[int, float]]:
        """Should return the number of output tokens.

        If there is no output_tokens, this method must return None.
        """
        ...  # pragma: no cover

content: str abstractmethod property

Should return the string content of the response chunk.

If there are multiple choices in a chunk, this method should select the 0th choice and return it's string content.

If there is no string content (e.g. when using tools), this method must return the empty string.

finish_reasons: Union[None, list[str]] abstractmethod property

Should return the finish reasons of the response.

If there is no finish reason, this method must return None.

id: Optional[str] abstractmethod property

Should return the id of the response.

input_tokens: Optional[Union[int, float]] abstractmethod property

Should return the number of input tokens.

If there is no input_tokens, this method must return None.

model: Optional[str] abstractmethod property

Should return the name of the response model.

output_tokens: Optional[Union[int, float]] abstractmethod property

Should return the number of output tokens.

If there is no output_tokens, this method must return None.

usage: Any abstractmethod property

Should return the usage of the response.

If there is no usage, this method must return None.

BaseStream

Bases: Generic[BaseCallResponseChunkT, UserMessageParamT, AssistantMessageParamT, BaseToolT], ABC

A base class for streaming responses from LLMs.

Source code in mirascope/base/types.py
class BaseStream(
    Generic[
        BaseCallResponseChunkT,
        UserMessageParamT,
        AssistantMessageParamT,
        BaseToolT,
    ],
    ABC,
):
    """A base class for streaming responses from LLMs."""

    stream: Generator[BaseCallResponseChunkT, None, None]
    message_param_type: type[AssistantMessageParamT]

    cost: Optional[float] = None
    user_message_param: Optional[UserMessageParamT] = None
    message_param: AssistantMessageParamT

    def __init__(
        self,
        stream: Generator[BaseCallResponseChunkT, None, None],
        message_param_type: type[AssistantMessageParamT],
    ):
        """Initializes an instance of `BaseStream`."""
        self.stream = stream
        self.message_param_type = message_param_type

    def __iter__(
        self,
    ) -> Generator[tuple[BaseCallResponseChunkT, Optional[BaseToolT]], None, None]:
        """Iterator over the stream and stores useful information."""
        content = ""
        for chunk in self.stream:
            content += chunk.content
            if chunk.cost is not None:
                self.cost = chunk.cost
            yield chunk, None
            self.user_message_param = chunk.user_message_param
        kwargs = {"role": "assistant"}
        if "message" in self.message_param_type.__annotations__:
            kwargs["message"] = content
        else:
            kwargs["content"] = content
        self.message_param = self.message_param_type(**kwargs)

BaseTool

Bases: BaseModel, Generic[ToolCallT], ABC

A base class for easy use of tools with prompts.

BaseTool is an abstract class interface and should not be used directly. When implementing a class that extends BaseTool, you must include the original tool_call from which this till was instantiated. Make sure to skip tool_call when generating the schema by annotating it with SkipJsonSchema.

Source code in mirascope/base/tools.py
class BaseTool(BaseModel, Generic[ToolCallT], ABC):
    """A base class for easy use of tools with prompts.

    `BaseTool` is an abstract class interface and should not be used directly. When
    implementing a class that extends `BaseTool`, you must include the original
    `tool_call` from which this till was instantiated. Make sure to skip `tool_call`
    when generating the schema by annotating it with `SkipJsonSchema`.
    """

    tool_call: SkipJsonSchema[ToolCallT]

    model_config = ConfigDict(arbitrary_types_allowed=True)

    @classmethod
    def name(cls) -> str:
        """Returns the name of the tool."""
        return cls.__name__

    @classmethod
    def description(cls) -> str:
        """Returns the description of the tool."""
        return inspect.cleandoc(cls.__doc__) if cls.__doc__ else DEFAULT_TOOL_DOCSTRING

    @property
    def args(self) -> dict[str, Any]:
        """The arguments of the tool as a dictionary."""
        return {
            field: getattr(self, field)
            for field in self.model_fields
            if field != "tool_call"
        }

    @property
    def fn(self) -> Callable[..., str]:
        """Returns the function that the tool describes."""
        raise RuntimeError("Tool does not have an attached function.")

    def call(self) -> str:
        """Calls the tool's `fn` with the tool's `args`."""
        return self.fn(**self.args)

    @classmethod
    def tool_schema(cls) -> Any:
        """Constructs a JSON Schema tool schema from the `BaseModel` schema defined."""
        model_schema = cls.model_json_schema()
        model_schema.pop("title", None)
        model_schema.pop("description", None)

        fn = {"name": cls.name(), "description": cls.description()}
        if model_schema["properties"]:
            fn["parameters"] = model_schema  # type: ignore

        return fn

    @classmethod
    @abstractmethod
    def from_tool_call(cls, tool_call: ToolCallT) -> BaseTool:
        """Extracts an instance of the tool constructed from a tool call response."""
        ...  # pragma: no cover

    @classmethod
    @abstractmethod
    def from_model(cls, model: type[BaseModel]) -> type[BaseTool]:
        """Constructs a `BaseTool` type from a `BaseModel` type."""
        ...  # pragma: no cover

    @classmethod
    @abstractmethod
    def from_fn(cls, fn: Callable) -> type[BaseTool]:
        """Constructs a `BaseTool` type from a function."""
        ...  # pragma: no cover

    @classmethod
    @abstractmethod
    def from_base_type(cls, base_type: type[BaseType]) -> type[BaseTool]:
        """Constructs a `BaseTool` type from a `BaseType` type."""
        ...  # pragma: no cover

args: dict[str, Any] property

The arguments of the tool as a dictionary.

fn: Callable[..., str] property

Returns the function that the tool describes.

call()

Calls the tool's fn with the tool's args.

Source code in mirascope/base/tools.py
def call(self) -> str:
    """Calls the tool's `fn` with the tool's `args`."""
    return self.fn(**self.args)

description() classmethod

Returns the description of the tool.

Source code in mirascope/base/tools.py
@classmethod
def description(cls) -> str:
    """Returns the description of the tool."""
    return inspect.cleandoc(cls.__doc__) if cls.__doc__ else DEFAULT_TOOL_DOCSTRING

from_base_type(base_type) abstractmethod classmethod

Constructs a BaseTool type from a BaseType type.

Source code in mirascope/base/tools.py
@classmethod
@abstractmethod
def from_base_type(cls, base_type: type[BaseType]) -> type[BaseTool]:
    """Constructs a `BaseTool` type from a `BaseType` type."""
    ...  # pragma: no cover

from_fn(fn) abstractmethod classmethod

Constructs a BaseTool type from a function.

Source code in mirascope/base/tools.py
@classmethod
@abstractmethod
def from_fn(cls, fn: Callable) -> type[BaseTool]:
    """Constructs a `BaseTool` type from a function."""
    ...  # pragma: no cover

from_model(model) abstractmethod classmethod

Constructs a BaseTool type from a BaseModel type.

Source code in mirascope/base/tools.py
@classmethod
@abstractmethod
def from_model(cls, model: type[BaseModel]) -> type[BaseTool]:
    """Constructs a `BaseTool` type from a `BaseModel` type."""
    ...  # pragma: no cover

from_tool_call(tool_call) abstractmethod classmethod

Extracts an instance of the tool constructed from a tool call response.

Source code in mirascope/base/tools.py
@classmethod
@abstractmethod
def from_tool_call(cls, tool_call: ToolCallT) -> BaseTool:
    """Extracts an instance of the tool constructed from a tool call response."""
    ...  # pragma: no cover

name() classmethod

Returns the name of the tool.

Source code in mirascope/base/tools.py
@classmethod
def name(cls) -> str:
    """Returns the name of the tool."""
    return cls.__name__

tool_schema() classmethod

Constructs a JSON Schema tool schema from the BaseModel schema defined.

Source code in mirascope/base/tools.py
@classmethod
def tool_schema(cls) -> Any:
    """Constructs a JSON Schema tool schema from the `BaseModel` schema defined."""
    model_schema = cls.model_json_schema()
    model_schema.pop("title", None)
    model_schema.pop("description", None)

    fn = {"name": cls.name(), "description": cls.description()}
    if model_schema["properties"]:
        fn["parameters"] = model_schema  # type: ignore

    return fn

GeminiAsyncStream

Bases: BaseAsyncStream[GeminiCallResponseChunk, ContentDict, ContentDict, GeminiTool]

A class for streaming responses from Google's Gemini API.

Source code in mirascope/gemini/types.py
class GeminiAsyncStream(
    BaseAsyncStream[
        GeminiCallResponseChunk,
        ContentDict,
        ContentDict,
        GeminiTool,
    ]
):
    """A class for streaming responses from Google's Gemini API."""

    def __init__(self, stream: AsyncGenerator[GeminiCallResponseChunk, None]):
        """Initializes an instance of `GeminiAsyncStream`."""
        super().__init__(stream, ContentDict)

GeminiCallParams

Bases: BaseCallParams[GeminiTool]

The parameters to use when calling the Gemini API calls.

Example:

from mirascope.gemini import GeminiCall, GeminiCallParams


class BookRecommendation(GeminiPrompt):
    prompt_template = "Please recommend a {genre} book"

    genre: str

    call_params = GeminiCallParams(
        model="gemini-1.0-pro-001",
        generation_config={"candidate_count": 2},
    )


response = BookRecommender(genre="fantasy").call()
print(response.content)
#> The Name of the Wind
Source code in mirascope/gemini/types.py
class GeminiCallParams(BaseCallParams[GeminiTool]):
    """The parameters to use when calling the Gemini API calls.

    Example:

    ```python
    from mirascope.gemini import GeminiCall, GeminiCallParams


    class BookRecommendation(GeminiPrompt):
        prompt_template = "Please recommend a {genre} book"

        genre: str

        call_params = GeminiCallParams(
            model="gemini-1.0-pro-001",
            generation_config={"candidate_count": 2},
        )


    response = BookRecommender(genre="fantasy").call()
    print(response.content)
    #> The Name of the Wind
    ```
    """

    model: str = "gemini-1.0-pro"
    generation_config: Optional[dict[str, Any]] = {"candidate_count": 1}
    safety_settings: Optional[Any] = None
    request_options: Optional[dict[str, Any]] = None

GeminiCallResponse

Bases: BaseCallResponse[Union[GenerateContentResponse, AsyncGenerateContentResponse], GeminiTool]

Convenience wrapper around Gemini's GenerateContentResponse.

When using Mirascope's convenience wrappers to interact with Gemini models via GeminiCall, responses using GeminiCall.call() will return a GeminiCallResponse, whereby the implemented properties allow for simpler syntax and a convenient developer experience.

Example:

from mirascope.gemini import GeminiPrompt


class BookRecommender(GeminiPrompt):
    prompt_template = "Please recommend a {genre} book"

    genre: str


response = BookRecommender(genre="fantasy").call()
print(response.content)
#> The Lord of the Rings
Source code in mirascope/gemini/types.py
class GeminiCallResponse(
    BaseCallResponse[
        Union[GenerateContentResponse, AsyncGenerateContentResponse], GeminiTool
    ]
):
    """Convenience wrapper around Gemini's `GenerateContentResponse`.

    When using Mirascope's convenience wrappers to interact with Gemini models via
    `GeminiCall`, responses using `GeminiCall.call()` will return a
    `GeminiCallResponse`, whereby the implemented properties allow for simpler syntax
    and a convenient developer experience.

    Example:

    ```python
    from mirascope.gemini import GeminiPrompt


    class BookRecommender(GeminiPrompt):
        prompt_template = "Please recommend a {genre} book"

        genre: str


    response = BookRecommender(genre="fantasy").call()
    print(response.content)
    #> The Lord of the Rings
    ```
    """

    user_message_param: Optional[ContentDict] = None

    @property
    def message_param(self) -> ContentDict:
        """Returns the models's response as a message parameter."""
        return {"role": "model", "parts": self.response.parts}

    @property
    def tools(self) -> Optional[list[GeminiTool]]:
        """Returns the list of tools for the 0th candidate's 0th content part."""
        if self.tool_types is None:
            return None

        if self.response.candidates[0].finish_reason != 1:  # STOP = 1
            raise RuntimeError(
                "Generation stopped before the stop sequence. "
                "This is likely due to a limit on output tokens that is too low. "
                "Note that this could also indicate no tool is beind called, so we "
                "recommend that you check the output of the call to confirm."
                f"Finish Reason: {self.response.candidates[0].finish_reason}"
            )

        tool_calls = [
            part.function_call for part in self.response.candidates[0].content.parts
        ]

        extracted_tools = []
        for tool_call in tool_calls:
            for tool_type in self.tool_types:
                if tool_call.name == tool_type.name():
                    extracted_tools.append(tool_type.from_tool_call(tool_call))
                    break

        return extracted_tools

    @property
    def tool(self) -> Optional[GeminiTool]:
        """Returns the 0th tool for the 0th candidate's 0th content part.

        Raises:
            ValidationError: if the tool call doesn't match the tool's schema.
        """
        tools = self.tools
        if tools:
            return tools[0]
        return None

    @classmethod
    def tool_message_params(
        self, tools_and_outputs: list[tuple[GeminiTool, object]]
    ) -> list[FunctionResponse]:
        """Returns the tool message parameters for tool call results."""
        return [
            FunctionResponse(name=tool.name(), response={"result": output})
            for tool, output in tools_and_outputs
        ]

    @property
    def content(self) -> str:
        """Returns the contained string content for the 0th choice."""
        return self.response.candidates[0].content.parts[0].text

    @property
    def id(self) -> Optional[str]:
        """Returns the id of the response.

        google.generativeai does not return an id
        """
        return None

    @property
    def finish_reasons(self) -> list[str]:
        """Returns the finish reasons of the response."""
        finish_reasons = [
            "FINISH_REASON_UNSPECIFIED",
            "STOP",
            "MAX_TOKENS",
            "SAFETY",
            "RECITATION",
            "OTHER",
        ]

        return [
            finish_reasons[candidate.finish_reason]
            for candidate in self.response.candidates
        ]

    @property
    def model(self) -> None:
        """Returns the model name.

        google.generativeai does not return model, so we return None
        """
        return None

    @property
    def usage(self) -> None:
        """Returns the usage of the chat completion.

        google.generativeai does not have Usage, so we return None
        """
        return None

    @property
    def input_tokens(self) -> None:
        """Returns the number of input tokens."""
        return None

    @property
    def output_tokens(self) -> None:
        """Returns the number of output tokens."""
        return None

    def dump(self) -> dict[str, Any]:
        """Dumps the response to a dictionary."""
        return {
            "start_time": self.start_time,
            "end_time": self.end_time,
            "output": str(self.response),
            "cost": self.cost,
        }

content: str property

Returns the contained string content for the 0th choice.

finish_reasons: list[str] property

Returns the finish reasons of the response.

id: Optional[str] property

Returns the id of the response.

google.generativeai does not return an id

input_tokens: None property

Returns the number of input tokens.

message_param: ContentDict property

Returns the models's response as a message parameter.

model: None property

Returns the model name.

google.generativeai does not return model, so we return None

output_tokens: None property

Returns the number of output tokens.

tool: Optional[GeminiTool] property

Returns the 0th tool for the 0th candidate's 0th content part.

Raises:

Type Description
ValidationError

if the tool call doesn't match the tool's schema.

tools: Optional[list[GeminiTool]] property

Returns the list of tools for the 0th candidate's 0th content part.

usage: None property

Returns the usage of the chat completion.

google.generativeai does not have Usage, so we return None

dump()

Dumps the response to a dictionary.

Source code in mirascope/gemini/types.py
def dump(self) -> dict[str, Any]:
    """Dumps the response to a dictionary."""
    return {
        "start_time": self.start_time,
        "end_time": self.end_time,
        "output": str(self.response),
        "cost": self.cost,
    }

tool_message_params(tools_and_outputs) classmethod

Returns the tool message parameters for tool call results.

Source code in mirascope/gemini/types.py
@classmethod
def tool_message_params(
    self, tools_and_outputs: list[tuple[GeminiTool, object]]
) -> list[FunctionResponse]:
    """Returns the tool message parameters for tool call results."""
    return [
        FunctionResponse(name=tool.name(), response={"result": output})
        for tool, output in tools_and_outputs
    ]

GeminiCallResponseChunk

Bases: BaseCallResponseChunk[GenerateContentResponse, GeminiTool]

Convenience wrapper around chat completion streaming chunks.

When using Mirascope's convenience wrappers to interact with Gemini models via GeminiCall, responses using GeminiCall.stream() will return a GeminiCallResponseChunk, whereby the implemented properties allow for simpler syntax and a convenient developer experience.

Example:

from mirascope.gemini import GeminiCall


class Math(GeminiCall):
    prompt_template = "What is 1 + 2?"


content = ""
for chunk in Math().stream():
    content += chunk.content
    print(content)
#> 1
#  1 +
#  1 + 2
#  1 + 2 equals
#  1 + 2 equals
#  1 + 2 equals 3
#  1 + 2 equals 3.
Source code in mirascope/gemini/types.py
class GeminiCallResponseChunk(
    BaseCallResponseChunk[GenerateContentResponse, GeminiTool]
):
    """Convenience wrapper around chat completion streaming chunks.

    When using Mirascope's convenience wrappers to interact with Gemini models via
    `GeminiCall`, responses using `GeminiCall.stream()` will return a
    `GeminiCallResponseChunk`, whereby the implemented properties allow for simpler
    syntax and a convenient developer experience.

    Example:

    ```python
    from mirascope.gemini import GeminiCall


    class Math(GeminiCall):
        prompt_template = "What is 1 + 2?"


    content = ""
    for chunk in Math().stream():
        content += chunk.content
        print(content)
    #> 1
    #  1 +
    #  1 + 2
    #  1 + 2 equals
    #  1 + 2 equals
    #  1 + 2 equals 3
    #  1 + 2 equals 3.
    ```
    """

    user_message_param: Optional[ContentDict] = None

    @property
    def content(self) -> str:
        """Returns the chunk content for the 0th choice."""
        return self.chunk.candidates[0].content.parts[0].text

    @property
    def id(self) -> Optional[str]:
        """Returns the id of the response.

        google.generativeai does not return an id
        """
        return None

    @property
    def finish_reasons(self) -> list[str]:
        """Returns the finish reasons of the response."""
        finish_reasons = [
            "FINISH_REASON_UNSPECIFIED",
            "STOP",
            "MAX_TOKENS",
            "SAFETY",
            "RECITATION",
            "OTHER",
        ]

        return [
            finish_reasons[candidate.finish_reason]
            for candidate in self.chunk.candidates
        ]

    @property
    def model(self) -> None:
        """Returns the model name.

        google.generativeai does not return model, so we return None
        """
        return None

    @property
    def usage(self) -> None:
        """Returns the usage of the chat completion.

        google.generativeai does not have Usage, so we return None
        """
        return None

    @property
    def input_tokens(self) -> None:
        """Returns the number of input tokens."""
        return None

    @property
    def output_tokens(self) -> None:
        """Returns the number of output tokens."""
        return None

content: str property

Returns the chunk content for the 0th choice.

finish_reasons: list[str] property

Returns the finish reasons of the response.

id: Optional[str] property

Returns the id of the response.

google.generativeai does not return an id

input_tokens: None property

Returns the number of input tokens.

model: None property

Returns the model name.

google.generativeai does not return model, so we return None

output_tokens: None property

Returns the number of output tokens.

usage: None property

Returns the usage of the chat completion.

google.generativeai does not have Usage, so we return None

GeminiStream

Bases: BaseStream[GeminiCallResponseChunk, ContentDict, ContentDict, GeminiTool]

A class for streaming responses from Google's Gemini API.

Source code in mirascope/gemini/types.py
class GeminiStream(
    BaseStream[
        GeminiCallResponseChunk,
        ContentDict,
        ContentDict,
        GeminiTool,
    ]
):
    """A class for streaming responses from Google's Gemini API."""

    def __init__(self, stream: Generator[GeminiCallResponseChunk, None, None]):
        """Initializes an instance of `GeminiStream`."""
        super().__init__(stream, ContentDict)

GeminiTool

Bases: BaseTool[FunctionCall]

A base class for easy use of tools with the Gemini API.

GeminiTool internally handles the logic that allows you to use tools with simple calls such as GeminiCompletion.tool or GeminiTool.fn, as seen in the examples below.

Example:

from mirascope.gemini import GeminiCall, GeminiCallParams, GeminiTool


class CurrentWeather(GeminiTool):
    """A tool for getting the current weather in a location."""

    location: str


class WeatherForecast(GeminiPrompt):
    prompt_template = "What is the current weather in {city}?"

    city: str

    call_params = GeminiCallParams(
        model="gemini-pro",
        tools=[CurrentWeather],
    )


prompt = WeatherPrompt()
forecast = WeatherForecast(city="Tokyo").call().tool
print(forecast.location)
#> Tokyo
Source code in mirascope/gemini/tools.py
class GeminiTool(BaseTool[FunctionCall]):
    '''A base class for easy use of tools with the Gemini API.

    `GeminiTool` internally handles the logic that allows you to use tools with simple
    calls such as `GeminiCompletion.tool` or `GeminiTool.fn`, as seen in the
    examples below.

    Example:

    ```python
    from mirascope.gemini import GeminiCall, GeminiCallParams, GeminiTool


    class CurrentWeather(GeminiTool):
        """A tool for getting the current weather in a location."""

        location: str


    class WeatherForecast(GeminiPrompt):
        prompt_template = "What is the current weather in {city}?"

        city: str

        call_params = GeminiCallParams(
            model="gemini-pro",
            tools=[CurrentWeather],
        )


    prompt = WeatherPrompt()
    forecast = WeatherForecast(city="Tokyo").call().tool
    print(forecast.location)
    #> Tokyo
    ```
    '''

    model_config = ConfigDict(arbitrary_types_allowed=True)

    @classmethod
    def tool_schema(cls) -> Tool:
        """Constructs a tool schema for use with the Gemini API.

        A Mirascope `GeminiTool` is deconstructed into a `Tool` schema for use with the
        Gemini API.

        Returns:
            The constructed `Tool` schema.
        """
        tool_schema = super().tool_schema()
        if "parameters" in tool_schema:
            if "$defs" in tool_schema["parameters"]:
                raise ValueError(
                    "Unfortunately Google's Gemini API cannot handle nested structures "
                    "with $defs."
                )
            tool_schema["parameters"]["properties"] = {
                prop: {
                    key: value for key, value in prop_schema.items() if key != "title"
                }
                for prop, prop_schema in tool_schema["parameters"]["properties"].items()
            }
        return Tool(function_declarations=[FunctionDeclaration(**tool_schema)])

    @classmethod
    def from_tool_call(cls, tool_call: FunctionCall) -> GeminiTool:
        """Extracts an instance of the tool constructed from a tool call response.

        Given a `GenerateContentResponse` from a Gemini chat completion response, this
        method extracts the tool call and constructs an instance of the tool.

        Args:
            tool_call: The `GenerateContentResponse` from which to extract the tool.

        Returns:
            An instance of the tool constructed from the tool call.

        Raises:
            ValueError: if the tool call doesn't have any arguments.
            ValidationError: if the tool call doesn't match the tool schema.
        """
        if not tool_call.args:
            raise ValueError("Tool call doesn't have any arguments.")
        model_json = {key: value for key, value in tool_call.args.items()}
        model_json["tool_call"] = tool_call
        return cls.model_validate(model_json)

    @classmethod
    def from_model(cls, model: Type[BaseModel]) -> Type[GeminiTool]:
        """Constructs a `GeminiTool` type from a `BaseModel` type."""
        return convert_base_model_to_tool(model, GeminiTool)

    @classmethod
    def from_fn(cls, fn: Callable) -> Type[GeminiTool]:
        """Constructs a `GeminiTool` type from a function."""
        return convert_function_to_tool(fn, GeminiTool)

    @classmethod
    def from_base_type(cls, base_type: Type[BaseType]) -> Type[GeminiTool]:
        """Constructs a `GeminiTool` type from a `BaseType` type."""
        return convert_base_type_to_tool(base_type, GeminiTool)

from_base_type(base_type) classmethod

Constructs a GeminiTool type from a BaseType type.

Source code in mirascope/gemini/tools.py
@classmethod
def from_base_type(cls, base_type: Type[BaseType]) -> Type[GeminiTool]:
    """Constructs a `GeminiTool` type from a `BaseType` type."""
    return convert_base_type_to_tool(base_type, GeminiTool)

from_fn(fn) classmethod

Constructs a GeminiTool type from a function.

Source code in mirascope/gemini/tools.py
@classmethod
def from_fn(cls, fn: Callable) -> Type[GeminiTool]:
    """Constructs a `GeminiTool` type from a function."""
    return convert_function_to_tool(fn, GeminiTool)

from_model(model) classmethod

Constructs a GeminiTool type from a BaseModel type.

Source code in mirascope/gemini/tools.py
@classmethod
def from_model(cls, model: Type[BaseModel]) -> Type[GeminiTool]:
    """Constructs a `GeminiTool` type from a `BaseModel` type."""
    return convert_base_model_to_tool(model, GeminiTool)

from_tool_call(tool_call) classmethod

Extracts an instance of the tool constructed from a tool call response.

Given a GenerateContentResponse from a Gemini chat completion response, this method extracts the tool call and constructs an instance of the tool.

Parameters:

Name Type Description Default
tool_call FunctionCall

The GenerateContentResponse from which to extract the tool.

required

Returns:

Type Description
GeminiTool

An instance of the tool constructed from the tool call.

Raises:

Type Description
ValueError

if the tool call doesn't have any arguments.

ValidationError

if the tool call doesn't match the tool schema.

Source code in mirascope/gemini/tools.py
@classmethod
def from_tool_call(cls, tool_call: FunctionCall) -> GeminiTool:
    """Extracts an instance of the tool constructed from a tool call response.

    Given a `GenerateContentResponse` from a Gemini chat completion response, this
    method extracts the tool call and constructs an instance of the tool.

    Args:
        tool_call: The `GenerateContentResponse` from which to extract the tool.

    Returns:
        An instance of the tool constructed from the tool call.

    Raises:
        ValueError: if the tool call doesn't have any arguments.
        ValidationError: if the tool call doesn't match the tool schema.
    """
    if not tool_call.args:
        raise ValueError("Tool call doesn't have any arguments.")
    model_json = {key: value for key, value in tool_call.args.items()}
    model_json["tool_call"] = tool_call
    return cls.model_validate(model_json)

tool_schema() classmethod

Constructs a tool schema for use with the Gemini API.

A Mirascope GeminiTool is deconstructed into a Tool schema for use with the Gemini API.

Returns:

Type Description
Tool

The constructed Tool schema.

Source code in mirascope/gemini/tools.py
@classmethod
def tool_schema(cls) -> Tool:
    """Constructs a tool schema for use with the Gemini API.

    A Mirascope `GeminiTool` is deconstructed into a `Tool` schema for use with the
    Gemini API.

    Returns:
        The constructed `Tool` schema.
    """
    tool_schema = super().tool_schema()
    if "parameters" in tool_schema:
        if "$defs" in tool_schema["parameters"]:
            raise ValueError(
                "Unfortunately Google's Gemini API cannot handle nested structures "
                "with $defs."
            )
        tool_schema["parameters"]["properties"] = {
            prop: {
                key: value for key, value in prop_schema.items() if key != "title"
            }
            for prop, prop_schema in tool_schema["parameters"]["properties"].items()
        }
    return Tool(function_declarations=[FunctionDeclaration(**tool_schema)])