mirascope 1.25.7__py3-none-any.whl → 2.0.0a0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mirascope/__init__.py +3 -59
- mirascope/graphs/__init__.py +22 -0
- mirascope/{experimental/graphs → graphs}/finite_state_machine.py +70 -159
- mirascope/llm/__init__.py +206 -16
- mirascope/llm/agents/__init__.py +15 -0
- mirascope/llm/agents/agent.py +97 -0
- mirascope/llm/agents/agent_template.py +45 -0
- mirascope/llm/agents/decorator.py +176 -0
- mirascope/llm/calls/__init__.py +16 -0
- mirascope/llm/calls/base_call.py +33 -0
- mirascope/llm/calls/calls.py +315 -0
- mirascope/llm/calls/decorator.py +255 -0
- mirascope/llm/clients/__init__.py +34 -0
- mirascope/llm/clients/anthropic/__init__.py +11 -0
- mirascope/llm/clients/anthropic/_utils/__init__.py +13 -0
- mirascope/llm/clients/anthropic/_utils/decode.py +244 -0
- mirascope/llm/clients/anthropic/_utils/encode.py +243 -0
- mirascope/llm/clients/anthropic/clients.py +819 -0
- mirascope/llm/clients/anthropic/model_ids.py +8 -0
- mirascope/llm/clients/base/__init__.py +15 -0
- mirascope/llm/clients/base/_utils.py +192 -0
- mirascope/llm/clients/base/client.py +1256 -0
- mirascope/llm/clients/base/kwargs.py +12 -0
- mirascope/llm/clients/base/params.py +93 -0
- mirascope/llm/clients/google/__init__.py +6 -0
- mirascope/llm/clients/google/_utils/__init__.py +13 -0
- mirascope/llm/clients/google/_utils/decode.py +231 -0
- mirascope/llm/clients/google/_utils/encode.py +279 -0
- mirascope/llm/clients/google/clients.py +853 -0
- mirascope/llm/clients/google/message.py +7 -0
- mirascope/llm/clients/google/model_ids.py +15 -0
- mirascope/llm/clients/openai/__init__.py +25 -0
- mirascope/llm/clients/openai/completions/__init__.py +9 -0
- mirascope/llm/clients/openai/completions/_utils/__init__.py +13 -0
- mirascope/llm/clients/openai/completions/_utils/decode.py +187 -0
- mirascope/llm/clients/openai/completions/_utils/encode.py +358 -0
- mirascope/llm/clients/openai/completions/_utils/model_features.py +81 -0
- mirascope/llm/clients/openai/completions/clients.py +833 -0
- mirascope/llm/clients/openai/completions/model_ids.py +8 -0
- mirascope/llm/clients/openai/responses/__init__.py +9 -0
- mirascope/llm/clients/openai/responses/_utils/__init__.py +13 -0
- mirascope/llm/clients/openai/responses/_utils/decode.py +194 -0
- mirascope/llm/clients/openai/responses/_utils/encode.py +333 -0
- mirascope/llm/clients/openai/responses/_utils/model_features.py +87 -0
- mirascope/llm/clients/openai/responses/clients.py +832 -0
- mirascope/llm/clients/openai/responses/model_ids.py +8 -0
- mirascope/llm/clients/openai/shared/__init__.py +7 -0
- mirascope/llm/clients/openai/shared/_utils.py +55 -0
- mirascope/llm/clients/providers.py +175 -0
- mirascope/llm/content/__init__.py +70 -0
- mirascope/llm/content/audio.py +173 -0
- mirascope/llm/content/document.py +94 -0
- mirascope/llm/content/image.py +206 -0
- mirascope/llm/content/text.py +47 -0
- mirascope/llm/content/thought.py +58 -0
- mirascope/llm/content/tool_call.py +63 -0
- mirascope/llm/content/tool_output.py +26 -0
- mirascope/llm/context/__init__.py +6 -0
- mirascope/llm/context/_utils.py +28 -0
- mirascope/llm/context/context.py +24 -0
- mirascope/llm/exceptions.py +105 -0
- mirascope/llm/formatting/__init__.py +22 -0
- mirascope/llm/formatting/_utils.py +74 -0
- mirascope/llm/formatting/format.py +104 -0
- mirascope/llm/formatting/from_call_args.py +30 -0
- mirascope/llm/formatting/partial.py +58 -0
- mirascope/llm/formatting/types.py +109 -0
- mirascope/llm/mcp/__init__.py +5 -0
- mirascope/llm/mcp/client.py +118 -0
- mirascope/llm/messages/__init__.py +32 -0
- mirascope/llm/messages/message.py +182 -0
- mirascope/llm/models/__init__.py +16 -0
- mirascope/llm/models/models.py +1243 -0
- mirascope/llm/prompts/__init__.py +33 -0
- mirascope/llm/prompts/_utils.py +60 -0
- mirascope/llm/prompts/decorator.py +286 -0
- mirascope/llm/prompts/protocols.py +99 -0
- mirascope/llm/responses/__init__.py +57 -0
- mirascope/llm/responses/_utils.py +56 -0
- mirascope/llm/responses/base_response.py +91 -0
- mirascope/llm/responses/base_stream_response.py +697 -0
- mirascope/llm/responses/finish_reason.py +27 -0
- mirascope/llm/responses/response.py +345 -0
- mirascope/llm/responses/root_response.py +177 -0
- mirascope/llm/responses/stream_response.py +572 -0
- mirascope/llm/responses/streams.py +363 -0
- mirascope/llm/tools/__init__.py +40 -0
- mirascope/llm/tools/_utils.py +25 -0
- mirascope/llm/tools/decorator.py +175 -0
- mirascope/llm/tools/protocols.py +96 -0
- mirascope/llm/tools/tool_schema.py +246 -0
- mirascope/llm/tools/toolkit.py +152 -0
- mirascope/llm/tools/tools.py +169 -0
- mirascope/llm/types/__init__.py +22 -0
- mirascope/llm/types/dataclass.py +9 -0
- mirascope/llm/types/jsonable.py +44 -0
- mirascope/llm/types/type_vars.py +19 -0
- mirascope-2.0.0a0.dist-info/METADATA +117 -0
- mirascope-2.0.0a0.dist-info/RECORD +101 -0
- mirascope/beta/__init__.py +0 -3
- mirascope/beta/openai/__init__.py +0 -17
- mirascope/beta/openai/realtime/__init__.py +0 -13
- mirascope/beta/openai/realtime/_utils/__init__.py +0 -3
- mirascope/beta/openai/realtime/_utils/_audio.py +0 -74
- mirascope/beta/openai/realtime/_utils/_protocols.py +0 -50
- mirascope/beta/openai/realtime/realtime.py +0 -500
- mirascope/beta/openai/realtime/recording.py +0 -98
- mirascope/beta/openai/realtime/tool.py +0 -113
- mirascope/beta/rag/__init__.py +0 -24
- mirascope/beta/rag/base/__init__.py +0 -22
- mirascope/beta/rag/base/chunkers/__init__.py +0 -2
- mirascope/beta/rag/base/chunkers/base_chunker.py +0 -37
- mirascope/beta/rag/base/chunkers/text_chunker.py +0 -33
- mirascope/beta/rag/base/config.py +0 -8
- mirascope/beta/rag/base/document.py +0 -11
- mirascope/beta/rag/base/embedders.py +0 -35
- mirascope/beta/rag/base/embedding_params.py +0 -18
- mirascope/beta/rag/base/embedding_response.py +0 -30
- mirascope/beta/rag/base/query_results.py +0 -7
- mirascope/beta/rag/base/vectorstore_params.py +0 -18
- mirascope/beta/rag/base/vectorstores.py +0 -37
- mirascope/beta/rag/chroma/__init__.py +0 -11
- mirascope/beta/rag/chroma/types.py +0 -62
- mirascope/beta/rag/chroma/vectorstores.py +0 -121
- mirascope/beta/rag/cohere/__init__.py +0 -11
- mirascope/beta/rag/cohere/embedders.py +0 -87
- mirascope/beta/rag/cohere/embedding_params.py +0 -29
- mirascope/beta/rag/cohere/embedding_response.py +0 -29
- mirascope/beta/rag/cohere/py.typed +0 -0
- mirascope/beta/rag/openai/__init__.py +0 -11
- mirascope/beta/rag/openai/embedders.py +0 -144
- mirascope/beta/rag/openai/embedding_params.py +0 -18
- mirascope/beta/rag/openai/embedding_response.py +0 -14
- mirascope/beta/rag/openai/py.typed +0 -0
- mirascope/beta/rag/pinecone/__init__.py +0 -19
- mirascope/beta/rag/pinecone/types.py +0 -143
- mirascope/beta/rag/pinecone/vectorstores.py +0 -148
- mirascope/beta/rag/weaviate/__init__.py +0 -6
- mirascope/beta/rag/weaviate/types.py +0 -92
- mirascope/beta/rag/weaviate/vectorstores.py +0 -103
- mirascope/core/__init__.py +0 -109
- mirascope/core/anthropic/__init__.py +0 -31
- mirascope/core/anthropic/_call.py +0 -67
- mirascope/core/anthropic/_call_kwargs.py +0 -13
- mirascope/core/anthropic/_thinking.py +0 -70
- mirascope/core/anthropic/_utils/__init__.py +0 -16
- mirascope/core/anthropic/_utils/_convert_common_call_params.py +0 -25
- mirascope/core/anthropic/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -21
- mirascope/core/anthropic/_utils/_convert_message_params.py +0 -102
- mirascope/core/anthropic/_utils/_get_json_output.py +0 -31
- mirascope/core/anthropic/_utils/_handle_stream.py +0 -113
- mirascope/core/anthropic/_utils/_message_param_converter.py +0 -154
- mirascope/core/anthropic/_utils/_setup_call.py +0 -146
- mirascope/core/anthropic/call_params.py +0 -44
- mirascope/core/anthropic/call_response.py +0 -226
- mirascope/core/anthropic/call_response_chunk.py +0 -152
- mirascope/core/anthropic/dynamic_config.py +0 -40
- mirascope/core/anthropic/py.typed +0 -0
- mirascope/core/anthropic/stream.py +0 -204
- mirascope/core/anthropic/tool.py +0 -101
- mirascope/core/azure/__init__.py +0 -31
- mirascope/core/azure/_call.py +0 -67
- mirascope/core/azure/_call_kwargs.py +0 -13
- mirascope/core/azure/_utils/__init__.py +0 -14
- mirascope/core/azure/_utils/_convert_common_call_params.py +0 -26
- mirascope/core/azure/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -21
- mirascope/core/azure/_utils/_convert_message_params.py +0 -121
- mirascope/core/azure/_utils/_get_credential.py +0 -33
- mirascope/core/azure/_utils/_get_json_output.py +0 -27
- mirascope/core/azure/_utils/_handle_stream.py +0 -130
- mirascope/core/azure/_utils/_message_param_converter.py +0 -117
- mirascope/core/azure/_utils/_setup_call.py +0 -183
- mirascope/core/azure/call_params.py +0 -59
- mirascope/core/azure/call_response.py +0 -215
- mirascope/core/azure/call_response_chunk.py +0 -105
- mirascope/core/azure/dynamic_config.py +0 -30
- mirascope/core/azure/py.typed +0 -0
- mirascope/core/azure/stream.py +0 -147
- mirascope/core/azure/tool.py +0 -93
- mirascope/core/base/__init__.py +0 -86
- mirascope/core/base/_call_factory.py +0 -256
- mirascope/core/base/_create.py +0 -253
- mirascope/core/base/_extract.py +0 -175
- mirascope/core/base/_extract_with_tools.py +0 -189
- mirascope/core/base/_partial.py +0 -95
- mirascope/core/base/_utils/__init__.py +0 -92
- mirascope/core/base/_utils/_base_message_param_converter.py +0 -22
- mirascope/core/base/_utils/_base_type.py +0 -26
- mirascope/core/base/_utils/_convert_base_model_to_base_tool.py +0 -48
- mirascope/core/base/_utils/_convert_base_type_to_base_tool.py +0 -24
- mirascope/core/base/_utils/_convert_function_to_base_tool.py +0 -139
- mirascope/core/base/_utils/_convert_messages_to_message_params.py +0 -178
- mirascope/core/base/_utils/_convert_provider_finish_reason_to_finish_reason.py +0 -20
- mirascope/core/base/_utils/_default_tool_docstring.py +0 -6
- mirascope/core/base/_utils/_extract_tool_return.py +0 -42
- mirascope/core/base/_utils/_fn_is_async.py +0 -24
- mirascope/core/base/_utils/_format_template.py +0 -32
- mirascope/core/base/_utils/_get_audio_type.py +0 -18
- mirascope/core/base/_utils/_get_common_usage.py +0 -20
- mirascope/core/base/_utils/_get_create_fn_or_async_create_fn.py +0 -137
- mirascope/core/base/_utils/_get_document_type.py +0 -7
- mirascope/core/base/_utils/_get_dynamic_configuration.py +0 -69
- mirascope/core/base/_utils/_get_fields_from_call_args.py +0 -34
- mirascope/core/base/_utils/_get_fn_args.py +0 -23
- mirascope/core/base/_utils/_get_image_dimensions.py +0 -39
- mirascope/core/base/_utils/_get_image_type.py +0 -26
- mirascope/core/base/_utils/_get_metadata.py +0 -17
- mirascope/core/base/_utils/_get_possible_user_message_param.py +0 -21
- mirascope/core/base/_utils/_get_prompt_template.py +0 -28
- mirascope/core/base/_utils/_get_template_values.py +0 -51
- mirascope/core/base/_utils/_get_template_variables.py +0 -38
- mirascope/core/base/_utils/_get_unsupported_tool_config_keys.py +0 -10
- mirascope/core/base/_utils/_is_prompt_template.py +0 -24
- mirascope/core/base/_utils/_json_mode_content.py +0 -17
- mirascope/core/base/_utils/_messages_decorator.py +0 -121
- mirascope/core/base/_utils/_parse_content_template.py +0 -323
- mirascope/core/base/_utils/_parse_prompt_messages.py +0 -63
- mirascope/core/base/_utils/_pil_image_to_bytes.py +0 -13
- mirascope/core/base/_utils/_protocols.py +0 -901
- mirascope/core/base/_utils/_setup_call.py +0 -79
- mirascope/core/base/_utils/_setup_extract_tool.py +0 -30
- mirascope/core/base/call_kwargs.py +0 -13
- mirascope/core/base/call_params.py +0 -36
- mirascope/core/base/call_response.py +0 -338
- mirascope/core/base/call_response_chunk.py +0 -130
- mirascope/core/base/dynamic_config.py +0 -82
- mirascope/core/base/from_call_args.py +0 -30
- mirascope/core/base/merge_decorators.py +0 -59
- mirascope/core/base/message_param.py +0 -175
- mirascope/core/base/messages.py +0 -116
- mirascope/core/base/metadata.py +0 -13
- mirascope/core/base/prompt.py +0 -497
- mirascope/core/base/response_model_config_dict.py +0 -9
- mirascope/core/base/stream.py +0 -479
- mirascope/core/base/stream_config.py +0 -11
- mirascope/core/base/structured_stream.py +0 -296
- mirascope/core/base/tool.py +0 -214
- mirascope/core/base/toolkit.py +0 -176
- mirascope/core/base/types.py +0 -344
- mirascope/core/bedrock/__init__.py +0 -34
- mirascope/core/bedrock/_call.py +0 -68
- mirascope/core/bedrock/_call_kwargs.py +0 -12
- mirascope/core/bedrock/_types.py +0 -104
- mirascope/core/bedrock/_utils/__init__.py +0 -14
- mirascope/core/bedrock/_utils/_convert_common_call_params.py +0 -39
- mirascope/core/bedrock/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -23
- mirascope/core/bedrock/_utils/_convert_message_params.py +0 -111
- mirascope/core/bedrock/_utils/_get_json_output.py +0 -30
- mirascope/core/bedrock/_utils/_handle_stream.py +0 -104
- mirascope/core/bedrock/_utils/_message_param_converter.py +0 -172
- mirascope/core/bedrock/_utils/_setup_call.py +0 -258
- mirascope/core/bedrock/call_params.py +0 -38
- mirascope/core/bedrock/call_response.py +0 -248
- mirascope/core/bedrock/call_response_chunk.py +0 -111
- mirascope/core/bedrock/dynamic_config.py +0 -37
- mirascope/core/bedrock/py.typed +0 -0
- mirascope/core/bedrock/stream.py +0 -154
- mirascope/core/bedrock/tool.py +0 -100
- mirascope/core/cohere/__init__.py +0 -30
- mirascope/core/cohere/_call.py +0 -67
- mirascope/core/cohere/_call_kwargs.py +0 -11
- mirascope/core/cohere/_types.py +0 -20
- mirascope/core/cohere/_utils/__init__.py +0 -14
- mirascope/core/cohere/_utils/_convert_common_call_params.py +0 -26
- mirascope/core/cohere/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -24
- mirascope/core/cohere/_utils/_convert_message_params.py +0 -32
- mirascope/core/cohere/_utils/_get_json_output.py +0 -30
- mirascope/core/cohere/_utils/_handle_stream.py +0 -35
- mirascope/core/cohere/_utils/_message_param_converter.py +0 -54
- mirascope/core/cohere/_utils/_setup_call.py +0 -150
- mirascope/core/cohere/call_params.py +0 -62
- mirascope/core/cohere/call_response.py +0 -205
- mirascope/core/cohere/call_response_chunk.py +0 -125
- mirascope/core/cohere/dynamic_config.py +0 -32
- mirascope/core/cohere/py.typed +0 -0
- mirascope/core/cohere/stream.py +0 -113
- mirascope/core/cohere/tool.py +0 -93
- mirascope/core/costs/__init__.py +0 -5
- mirascope/core/costs/_anthropic_calculate_cost.py +0 -219
- mirascope/core/costs/_azure_calculate_cost.py +0 -11
- mirascope/core/costs/_bedrock_calculate_cost.py +0 -15
- mirascope/core/costs/_cohere_calculate_cost.py +0 -44
- mirascope/core/costs/_gemini_calculate_cost.py +0 -67
- mirascope/core/costs/_google_calculate_cost.py +0 -427
- mirascope/core/costs/_groq_calculate_cost.py +0 -156
- mirascope/core/costs/_litellm_calculate_cost.py +0 -11
- mirascope/core/costs/_mistral_calculate_cost.py +0 -64
- mirascope/core/costs/_openai_calculate_cost.py +0 -416
- mirascope/core/costs/_vertex_calculate_cost.py +0 -67
- mirascope/core/costs/_xai_calculate_cost.py +0 -104
- mirascope/core/costs/calculate_cost.py +0 -86
- mirascope/core/gemini/__init__.py +0 -40
- mirascope/core/gemini/_call.py +0 -67
- mirascope/core/gemini/_call_kwargs.py +0 -12
- mirascope/core/gemini/_utils/__init__.py +0 -14
- mirascope/core/gemini/_utils/_convert_common_call_params.py +0 -39
- mirascope/core/gemini/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -23
- mirascope/core/gemini/_utils/_convert_message_params.py +0 -156
- mirascope/core/gemini/_utils/_get_json_output.py +0 -35
- mirascope/core/gemini/_utils/_handle_stream.py +0 -33
- mirascope/core/gemini/_utils/_message_param_converter.py +0 -209
- mirascope/core/gemini/_utils/_setup_call.py +0 -149
- mirascope/core/gemini/call_params.py +0 -52
- mirascope/core/gemini/call_response.py +0 -216
- mirascope/core/gemini/call_response_chunk.py +0 -100
- mirascope/core/gemini/dynamic_config.py +0 -26
- mirascope/core/gemini/stream.py +0 -120
- mirascope/core/gemini/tool.py +0 -104
- mirascope/core/google/__init__.py +0 -29
- mirascope/core/google/_call.py +0 -67
- mirascope/core/google/_call_kwargs.py +0 -13
- mirascope/core/google/_utils/__init__.py +0 -14
- mirascope/core/google/_utils/_convert_common_call_params.py +0 -38
- mirascope/core/google/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -27
- mirascope/core/google/_utils/_convert_message_params.py +0 -297
- mirascope/core/google/_utils/_get_json_output.py +0 -37
- mirascope/core/google/_utils/_handle_stream.py +0 -58
- mirascope/core/google/_utils/_message_param_converter.py +0 -200
- mirascope/core/google/_utils/_setup_call.py +0 -201
- mirascope/core/google/_utils/_validate_media_type.py +0 -58
- mirascope/core/google/call_params.py +0 -22
- mirascope/core/google/call_response.py +0 -255
- mirascope/core/google/call_response_chunk.py +0 -135
- mirascope/core/google/dynamic_config.py +0 -26
- mirascope/core/google/stream.py +0 -199
- mirascope/core/google/tool.py +0 -146
- mirascope/core/groq/__init__.py +0 -30
- mirascope/core/groq/_call.py +0 -67
- mirascope/core/groq/_call_kwargs.py +0 -13
- mirascope/core/groq/_utils/__init__.py +0 -14
- mirascope/core/groq/_utils/_convert_common_call_params.py +0 -26
- mirascope/core/groq/_utils/_convert_message_params.py +0 -112
- mirascope/core/groq/_utils/_get_json_output.py +0 -27
- mirascope/core/groq/_utils/_handle_stream.py +0 -123
- mirascope/core/groq/_utils/_message_param_converter.py +0 -89
- mirascope/core/groq/_utils/_setup_call.py +0 -132
- mirascope/core/groq/call_params.py +0 -52
- mirascope/core/groq/call_response.py +0 -213
- mirascope/core/groq/call_response_chunk.py +0 -104
- mirascope/core/groq/dynamic_config.py +0 -29
- mirascope/core/groq/py.typed +0 -0
- mirascope/core/groq/stream.py +0 -135
- mirascope/core/groq/tool.py +0 -80
- mirascope/core/litellm/__init__.py +0 -28
- mirascope/core/litellm/_call.py +0 -67
- mirascope/core/litellm/_utils/__init__.py +0 -5
- mirascope/core/litellm/_utils/_setup_call.py +0 -109
- mirascope/core/litellm/call_params.py +0 -10
- mirascope/core/litellm/call_response.py +0 -24
- mirascope/core/litellm/call_response_chunk.py +0 -14
- mirascope/core/litellm/dynamic_config.py +0 -8
- mirascope/core/litellm/py.typed +0 -0
- mirascope/core/litellm/stream.py +0 -86
- mirascope/core/litellm/tool.py +0 -13
- mirascope/core/mistral/__init__.py +0 -36
- mirascope/core/mistral/_call.py +0 -65
- mirascope/core/mistral/_call_kwargs.py +0 -19
- mirascope/core/mistral/_utils/__init__.py +0 -14
- mirascope/core/mistral/_utils/_convert_common_call_params.py +0 -24
- mirascope/core/mistral/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -22
- mirascope/core/mistral/_utils/_convert_message_params.py +0 -122
- mirascope/core/mistral/_utils/_get_json_output.py +0 -34
- mirascope/core/mistral/_utils/_handle_stream.py +0 -139
- mirascope/core/mistral/_utils/_message_param_converter.py +0 -176
- mirascope/core/mistral/_utils/_setup_call.py +0 -164
- mirascope/core/mistral/call_params.py +0 -36
- mirascope/core/mistral/call_response.py +0 -205
- mirascope/core/mistral/call_response_chunk.py +0 -105
- mirascope/core/mistral/dynamic_config.py +0 -33
- mirascope/core/mistral/py.typed +0 -0
- mirascope/core/mistral/stream.py +0 -120
- mirascope/core/mistral/tool.py +0 -81
- mirascope/core/openai/__init__.py +0 -31
- mirascope/core/openai/_call.py +0 -67
- mirascope/core/openai/_call_kwargs.py +0 -13
- mirascope/core/openai/_utils/__init__.py +0 -14
- mirascope/core/openai/_utils/_convert_common_call_params.py +0 -26
- mirascope/core/openai/_utils/_convert_message_params.py +0 -148
- mirascope/core/openai/_utils/_get_json_output.py +0 -31
- mirascope/core/openai/_utils/_handle_stream.py +0 -138
- mirascope/core/openai/_utils/_message_param_converter.py +0 -105
- mirascope/core/openai/_utils/_setup_call.py +0 -155
- mirascope/core/openai/call_params.py +0 -92
- mirascope/core/openai/call_response.py +0 -273
- mirascope/core/openai/call_response_chunk.py +0 -139
- mirascope/core/openai/dynamic_config.py +0 -34
- mirascope/core/openai/py.typed +0 -0
- mirascope/core/openai/stream.py +0 -185
- mirascope/core/openai/tool.py +0 -101
- mirascope/core/py.typed +0 -0
- mirascope/core/vertex/__init__.py +0 -45
- mirascope/core/vertex/_call.py +0 -62
- mirascope/core/vertex/_call_kwargs.py +0 -12
- mirascope/core/vertex/_utils/__init__.py +0 -14
- mirascope/core/vertex/_utils/_convert_common_call_params.py +0 -37
- mirascope/core/vertex/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -23
- mirascope/core/vertex/_utils/_convert_message_params.py +0 -171
- mirascope/core/vertex/_utils/_get_json_output.py +0 -36
- mirascope/core/vertex/_utils/_handle_stream.py +0 -33
- mirascope/core/vertex/_utils/_message_param_converter.py +0 -133
- mirascope/core/vertex/_utils/_setup_call.py +0 -160
- mirascope/core/vertex/call_params.py +0 -24
- mirascope/core/vertex/call_response.py +0 -206
- mirascope/core/vertex/call_response_chunk.py +0 -99
- mirascope/core/vertex/dynamic_config.py +0 -28
- mirascope/core/vertex/stream.py +0 -119
- mirascope/core/vertex/tool.py +0 -101
- mirascope/core/xai/__init__.py +0 -28
- mirascope/core/xai/_call.py +0 -67
- mirascope/core/xai/_utils/__init__.py +0 -5
- mirascope/core/xai/_utils/_setup_call.py +0 -113
- mirascope/core/xai/call_params.py +0 -10
- mirascope/core/xai/call_response.py +0 -16
- mirascope/core/xai/call_response_chunk.py +0 -14
- mirascope/core/xai/dynamic_config.py +0 -8
- mirascope/core/xai/py.typed +0 -0
- mirascope/core/xai/stream.py +0 -57
- mirascope/core/xai/tool.py +0 -13
- mirascope/experimental/graphs/__init__.py +0 -5
- mirascope/integrations/__init__.py +0 -16
- mirascope/integrations/_middleware_factory.py +0 -403
- mirascope/integrations/langfuse/__init__.py +0 -3
- mirascope/integrations/langfuse/_utils.py +0 -114
- mirascope/integrations/langfuse/_with_langfuse.py +0 -70
- mirascope/integrations/logfire/__init__.py +0 -3
- mirascope/integrations/logfire/_utils.py +0 -225
- mirascope/integrations/logfire/_with_logfire.py +0 -63
- mirascope/integrations/otel/__init__.py +0 -10
- mirascope/integrations/otel/_utils.py +0 -270
- mirascope/integrations/otel/_with_hyperdx.py +0 -60
- mirascope/integrations/otel/_with_otel.py +0 -59
- mirascope/integrations/tenacity.py +0 -14
- mirascope/llm/_call.py +0 -401
- mirascope/llm/_context.py +0 -384
- mirascope/llm/_override.py +0 -3639
- mirascope/llm/_protocols.py +0 -500
- mirascope/llm/_response_metaclass.py +0 -31
- mirascope/llm/call_response.py +0 -158
- mirascope/llm/call_response_chunk.py +0 -66
- mirascope/llm/stream.py +0 -162
- mirascope/llm/tool.py +0 -64
- mirascope/mcp/__init__.py +0 -7
- mirascope/mcp/_utils.py +0 -288
- mirascope/mcp/client.py +0 -167
- mirascope/mcp/server.py +0 -356
- mirascope/mcp/tools.py +0 -110
- mirascope/py.typed +0 -0
- mirascope/retries/__init__.py +0 -11
- mirascope/retries/fallback.py +0 -131
- mirascope/retries/tenacity.py +0 -50
- mirascope/tools/__init__.py +0 -37
- mirascope/tools/base.py +0 -98
- mirascope/tools/system/__init__.py +0 -0
- mirascope/tools/system/_docker_operation.py +0 -166
- mirascope/tools/system/_file_system.py +0 -267
- mirascope/tools/web/__init__.py +0 -0
- mirascope/tools/web/_duckduckgo.py +0 -111
- mirascope/tools/web/_httpx.py +0 -125
- mirascope/tools/web/_parse_url_content.py +0 -94
- mirascope/tools/web/_requests.py +0 -54
- mirascope/v0/__init__.py +0 -43
- mirascope/v0/anthropic.py +0 -54
- mirascope/v0/base/__init__.py +0 -12
- mirascope/v0/base/calls.py +0 -118
- mirascope/v0/base/extractors.py +0 -122
- mirascope/v0/base/ops_utils.py +0 -207
- mirascope/v0/base/prompts.py +0 -48
- mirascope/v0/base/types.py +0 -14
- mirascope/v0/base/utils.py +0 -21
- mirascope/v0/openai.py +0 -54
- mirascope-1.25.7.dist-info/METADATA +0 -169
- mirascope-1.25.7.dist-info/RECORD +0 -378
- {mirascope-1.25.7.dist-info → mirascope-2.0.0a0.dist-info}/WHEEL +0 -0
- {mirascope-1.25.7.dist-info → mirascope-2.0.0a0.dist-info}/licenses/LICENSE +0 -0
mirascope/core/gemini/tool.py
DELETED
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
"""The `GeminiTool` class for easy tool usage with Google's Gemini LLM calls.
|
|
2
|
-
|
|
3
|
-
usage docs: learn/tools.md
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
from __future__ import annotations
|
|
7
|
-
|
|
8
|
-
from typing import Any
|
|
9
|
-
|
|
10
|
-
from google.ai.generativelanguage import FunctionCall
|
|
11
|
-
from google.generativeai.types import (
|
|
12
|
-
FunctionDeclaration,
|
|
13
|
-
Tool,
|
|
14
|
-
)
|
|
15
|
-
from pydantic.json_schema import SkipJsonSchema
|
|
16
|
-
|
|
17
|
-
from ..base import BaseTool
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
class GeminiTool(BaseTool):
|
|
21
|
-
"""A class for defining tools for Gemini LLM calls.
|
|
22
|
-
|
|
23
|
-
Example:
|
|
24
|
-
|
|
25
|
-
```python
|
|
26
|
-
from mirascope.core import prompt_template
|
|
27
|
-
from mirascope.core.gemini import gemini_call
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
def format_book(title: str, author: str) -> str:
|
|
31
|
-
return f"{title} by {author}"
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
@gemini_call("gemini-1.5-flash", tools=[format_book])
|
|
35
|
-
def recommend_book(genre: str) -> str:
|
|
36
|
-
return f"Recommend a {genre} book"
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
response = recommend_book("fantasy")
|
|
40
|
-
if tool := response.tool: # returns an `GeminiTool` instance
|
|
41
|
-
print(tool.call())
|
|
42
|
-
```
|
|
43
|
-
"""
|
|
44
|
-
|
|
45
|
-
__provider__ = "gemini"
|
|
46
|
-
|
|
47
|
-
tool_call: SkipJsonSchema[FunctionCall]
|
|
48
|
-
|
|
49
|
-
@classmethod
|
|
50
|
-
def tool_schema(cls) -> Tool:
|
|
51
|
-
"""Constructs a JSON Schema tool schema from the `BaseModel` schema defined.
|
|
52
|
-
|
|
53
|
-
Example:
|
|
54
|
-
```python
|
|
55
|
-
from mirascope.core.gemini import GeminiTool
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
def format_book(title: str, author: str) -> str:
|
|
59
|
-
return f"{title} by {author}"
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
tool_type = GeminiTool.type_from_fn(format_book)
|
|
63
|
-
print(tool_type.tool_schema()) # prints the Gemini-specific tool schema
|
|
64
|
-
```
|
|
65
|
-
"""
|
|
66
|
-
model_schema = cls.model_json_schema()
|
|
67
|
-
fn: dict[str, Any] = {"name": cls._name(), "description": cls._description()}
|
|
68
|
-
|
|
69
|
-
if model_schema["properties"]:
|
|
70
|
-
fn["parameters"] = model_schema
|
|
71
|
-
|
|
72
|
-
if "parameters" in fn:
|
|
73
|
-
if "$defs" in fn["parameters"]:
|
|
74
|
-
raise ValueError(
|
|
75
|
-
"Unfortunately Google's Gemini API cannot handle nested structures "
|
|
76
|
-
"with $defs."
|
|
77
|
-
)
|
|
78
|
-
|
|
79
|
-
def handle_enum_schema(prop_schema: dict[str, Any]) -> dict[str, Any]:
|
|
80
|
-
if "enum" in prop_schema:
|
|
81
|
-
prop_schema["format"] = "enum"
|
|
82
|
-
return prop_schema
|
|
83
|
-
|
|
84
|
-
fn["parameters"]["properties"] = {
|
|
85
|
-
prop: {
|
|
86
|
-
key: value
|
|
87
|
-
for key, value in handle_enum_schema(prop_schema).items()
|
|
88
|
-
if key != "default"
|
|
89
|
-
}
|
|
90
|
-
for prop, prop_schema in fn["parameters"]["properties"].items()
|
|
91
|
-
}
|
|
92
|
-
return Tool(function_declarations=[FunctionDeclaration(**fn)])
|
|
93
|
-
|
|
94
|
-
@classmethod
|
|
95
|
-
def from_tool_call(cls, tool_call: FunctionCall) -> GeminiTool:
|
|
96
|
-
"""Constructs an `GeminiTool` instance from a `tool_call`.
|
|
97
|
-
|
|
98
|
-
Args:
|
|
99
|
-
tool_call: The Gemini tool call from which to construct this tool instance.
|
|
100
|
-
"""
|
|
101
|
-
model_json = {"tool_call": tool_call}
|
|
102
|
-
if tool_call.args:
|
|
103
|
-
model_json |= dict(tool_call.args.items())
|
|
104
|
-
return cls.model_validate(model_json)
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
"""The Mirascope Google Module."""
|
|
2
|
-
|
|
3
|
-
from typing import TypeAlias
|
|
4
|
-
|
|
5
|
-
from google.genai.types import ContentDict, FunctionResponse
|
|
6
|
-
|
|
7
|
-
from ..base import BaseMessageParam
|
|
8
|
-
from ._call import google_call
|
|
9
|
-
from ._call import google_call as call
|
|
10
|
-
from .call_params import GoogleCallParams
|
|
11
|
-
from .call_response import GoogleCallResponse
|
|
12
|
-
from .call_response_chunk import GoogleCallResponseChunk
|
|
13
|
-
from .dynamic_config import GoogleDynamicConfig
|
|
14
|
-
from .stream import GoogleStream
|
|
15
|
-
from .tool import GoogleTool
|
|
16
|
-
|
|
17
|
-
GoogleMessageParam: TypeAlias = ContentDict | FunctionResponse | BaseMessageParam
|
|
18
|
-
|
|
19
|
-
__all__ = [
|
|
20
|
-
"GoogleCallParams",
|
|
21
|
-
"GoogleCallResponse",
|
|
22
|
-
"GoogleCallResponseChunk",
|
|
23
|
-
"GoogleDynamicConfig",
|
|
24
|
-
"GoogleMessageParam",
|
|
25
|
-
"GoogleStream",
|
|
26
|
-
"GoogleTool",
|
|
27
|
-
"call",
|
|
28
|
-
"google_call",
|
|
29
|
-
]
|
mirascope/core/google/_call.py
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
"""The `google_call` decorator for functions as LLM calls."""
|
|
2
|
-
|
|
3
|
-
from ..base import call_factory
|
|
4
|
-
from ._utils import (
|
|
5
|
-
get_json_output,
|
|
6
|
-
handle_stream,
|
|
7
|
-
handle_stream_async,
|
|
8
|
-
setup_call,
|
|
9
|
-
)
|
|
10
|
-
from .call_params import GoogleCallParams
|
|
11
|
-
from .call_response import GoogleCallResponse
|
|
12
|
-
from .call_response_chunk import GoogleCallResponseChunk
|
|
13
|
-
from .stream import GoogleStream
|
|
14
|
-
from .tool import GoogleTool
|
|
15
|
-
|
|
16
|
-
google_call = call_factory(
|
|
17
|
-
TCallResponse=GoogleCallResponse,
|
|
18
|
-
TCallResponseChunk=GoogleCallResponseChunk,
|
|
19
|
-
TStream=GoogleStream,
|
|
20
|
-
TToolType=GoogleTool,
|
|
21
|
-
default_call_params=GoogleCallParams(),
|
|
22
|
-
setup_call=setup_call,
|
|
23
|
-
get_json_output=get_json_output,
|
|
24
|
-
handle_stream=handle_stream, # pyright: ignore [reportArgumentType]
|
|
25
|
-
handle_stream_async=handle_stream_async, # pyright: ignore [reportArgumentType]
|
|
26
|
-
)
|
|
27
|
-
"""A decorator for calling the Google API with a typed function.
|
|
28
|
-
|
|
29
|
-
usage docs: learn/calls.md
|
|
30
|
-
|
|
31
|
-
This decorator is used to wrap a typed function that calls the Google API. It parses
|
|
32
|
-
the prompt template of the wrapped function as the messages array and templates the input
|
|
33
|
-
arguments for the function into each message's template.
|
|
34
|
-
|
|
35
|
-
Example:
|
|
36
|
-
|
|
37
|
-
```python
|
|
38
|
-
from mirascope.core import prompt_template
|
|
39
|
-
from mirascope.core.google import google_call
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
@google_call("google-1.5-flash")
|
|
43
|
-
def recommend_book(genre: str) -> str:
|
|
44
|
-
return f"Recommend a {genre} book"
|
|
45
|
-
|
|
46
|
-
response = recommend_book("fantasy")
|
|
47
|
-
print(response.content)
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
Args:
|
|
51
|
-
model (str): The Google model to use in the API call.
|
|
52
|
-
stream (bool): Whether to stream the response from the API call.
|
|
53
|
-
tools (list[BaseTool | Callable]): The tools to use in the Google API call.
|
|
54
|
-
response_model (BaseModel | BaseType): The response model into which the response
|
|
55
|
-
should be structured.
|
|
56
|
-
output_parser (Callable[[GoogleCallResponse | ResponseModelT], Any]): A function
|
|
57
|
-
for parsing the call response whose value will be returned in place of the
|
|
58
|
-
original call response.
|
|
59
|
-
json_modem (bool): Whether to use JSON Mode.
|
|
60
|
-
client (object): An optional custom client to use in place of the default client.
|
|
61
|
-
call_params (GoogleCallParams): The `GoogleCallParams` call parameters to use in the
|
|
62
|
-
API call.
|
|
63
|
-
|
|
64
|
-
Returns:
|
|
65
|
-
decorator (Callable): The decorator for turning a typed function into a Google API
|
|
66
|
-
call.
|
|
67
|
-
"""
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
"""This module contains the type definition for the Google call keyword arguments."""
|
|
2
|
-
|
|
3
|
-
from collections.abc import Sequence
|
|
4
|
-
|
|
5
|
-
from google.genai.types import ContentOrDict, Tool
|
|
6
|
-
|
|
7
|
-
from ..base import BaseCallKwargs
|
|
8
|
-
from .call_params import GoogleCallParams
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class GoogleCallKwargs(GoogleCallParams, BaseCallKwargs[Tool]):
|
|
12
|
-
model: str
|
|
13
|
-
contents: Sequence[ContentOrDict]
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
"""Google utilities for decorator factories."""
|
|
2
|
-
|
|
3
|
-
from ._convert_message_params import convert_message_params
|
|
4
|
-
from ._get_json_output import get_json_output
|
|
5
|
-
from ._handle_stream import handle_stream, handle_stream_async
|
|
6
|
-
from ._setup_call import setup_call
|
|
7
|
-
|
|
8
|
-
__all__ = [
|
|
9
|
-
"convert_message_params",
|
|
10
|
-
"get_json_output",
|
|
11
|
-
"handle_stream",
|
|
12
|
-
"handle_stream_async",
|
|
13
|
-
"setup_call",
|
|
14
|
-
]
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
from typing import cast
|
|
2
|
-
|
|
3
|
-
from google.genai.types import GenerateContentConfig
|
|
4
|
-
|
|
5
|
-
from ...base.call_params import CommonCallParams
|
|
6
|
-
from ..call_params import GoogleCallParams
|
|
7
|
-
|
|
8
|
-
GOOGLE_PARAM_MAPPING = {
|
|
9
|
-
"temperature": "temperature",
|
|
10
|
-
"max_tokens": "max_output_tokens",
|
|
11
|
-
"top_p": "top_p",
|
|
12
|
-
"stop": "stop_sequences",
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
def convert_common_call_params(common_params: CommonCallParams) -> GoogleCallParams:
|
|
17
|
-
"""Convert CommonCallParams to Google parameters."""
|
|
18
|
-
config = GenerateContentConfig()
|
|
19
|
-
|
|
20
|
-
for key, value in common_params.items():
|
|
21
|
-
if key not in GOOGLE_PARAM_MAPPING or value is None:
|
|
22
|
-
continue
|
|
23
|
-
|
|
24
|
-
if key == "stop":
|
|
25
|
-
# Google API expects a list of strings for stop sequences
|
|
26
|
-
if isinstance(value, str):
|
|
27
|
-
config.stop_sequences = [value]
|
|
28
|
-
elif isinstance(value, list):
|
|
29
|
-
config.stop_sequences = value
|
|
30
|
-
else:
|
|
31
|
-
target_attr = GOOGLE_PARAM_MAPPING[key]
|
|
32
|
-
setattr(config, target_attr, value)
|
|
33
|
-
|
|
34
|
-
default_config = GenerateContentConfig()
|
|
35
|
-
if config == default_config:
|
|
36
|
-
return cast(GoogleCallParams, {})
|
|
37
|
-
|
|
38
|
-
return cast(GoogleCallParams, {"config": config})
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
from mirascope.core.base._utils._convert_provider_finish_reason_to_finish_reason import (
|
|
2
|
-
FinishReasonMappingValue,
|
|
3
|
-
_convert_finish_reasons_to_common_finish_reasons_from_mapping,
|
|
4
|
-
)
|
|
5
|
-
from mirascope.core.base.types import FinishReason
|
|
6
|
-
|
|
7
|
-
_FinishReasonMapping: dict[str, FinishReasonMappingValue] = {
|
|
8
|
-
"FINISH_REASON_UNSPECIFIED": "stop",
|
|
9
|
-
"STOP": "stop",
|
|
10
|
-
"MAX_TOKENS": "length",
|
|
11
|
-
"SAFETY": "content_filter",
|
|
12
|
-
"RECITATION": "stop",
|
|
13
|
-
"OTHER": "stop",
|
|
14
|
-
"BLOCKLIST": "stop",
|
|
15
|
-
"PROHIBITED_CONTENT": "stop",
|
|
16
|
-
"SPII": "stop",
|
|
17
|
-
"MALFORMED_FUNCTION_CALL": "stop",
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
def _convert_finish_reasons_to_common_finish_reasons(
|
|
22
|
-
finish_reasons: list[str],
|
|
23
|
-
) -> list[FinishReason] | None:
|
|
24
|
-
"""Provider-agnostic finish reasons."""
|
|
25
|
-
return _convert_finish_reasons_to_common_finish_reasons_from_mapping(
|
|
26
|
-
finish_reasons, _FinishReasonMapping
|
|
27
|
-
)
|
|
@@ -1,297 +0,0 @@
|
|
|
1
|
-
"""Utility for converting `BaseMessageParam` to `ContentsType`"""
|
|
2
|
-
|
|
3
|
-
import asyncio
|
|
4
|
-
import base64
|
|
5
|
-
import io
|
|
6
|
-
from concurrent.futures import ThreadPoolExecutor
|
|
7
|
-
|
|
8
|
-
from google.genai import Client
|
|
9
|
-
from google.genai.types import (
|
|
10
|
-
BlobDict,
|
|
11
|
-
ContentDict,
|
|
12
|
-
FileDataDict,
|
|
13
|
-
FunctionCallDict,
|
|
14
|
-
FunctionResponseDict,
|
|
15
|
-
PartDict,
|
|
16
|
-
)
|
|
17
|
-
|
|
18
|
-
from ...base import BaseMessageParam
|
|
19
|
-
from ...base._utils import get_audio_type, get_document_type, get_image_type
|
|
20
|
-
from ...base._utils._parse_content_template import _load_media
|
|
21
|
-
from ._validate_media_type import (
|
|
22
|
-
_check_audio_media_type,
|
|
23
|
-
_check_document_media_type,
|
|
24
|
-
_check_image_media_type,
|
|
25
|
-
)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
def _over_file_size_limit(size: int) -> bool:
|
|
29
|
-
"""Check if the total file size exceeds the limit (10mb).
|
|
30
|
-
|
|
31
|
-
Google limit is 20MB but base64 adds 33% to the size.
|
|
32
|
-
"""
|
|
33
|
-
return size > 10 * 1024 * 1024 # 10MB
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
async def _convert_message_params_async(
|
|
37
|
-
message_params: list[BaseMessageParam | ContentDict], client: Client
|
|
38
|
-
) -> list[ContentDict]:
|
|
39
|
-
converted_message_params = []
|
|
40
|
-
total_payload_size = 0
|
|
41
|
-
for message_param in message_params:
|
|
42
|
-
if not isinstance(message_param, BaseMessageParam):
|
|
43
|
-
converted_message_params.append(message_param)
|
|
44
|
-
elif (role := message_param.role) == "system":
|
|
45
|
-
if not isinstance(message_param.content, str):
|
|
46
|
-
raise ValueError(
|
|
47
|
-
"System message content must be a single text string."
|
|
48
|
-
) # pragma: no cover
|
|
49
|
-
converted_message_params += [
|
|
50
|
-
{
|
|
51
|
-
"role": "system",
|
|
52
|
-
"parts": [PartDict(text=message_param.content)],
|
|
53
|
-
}
|
|
54
|
-
]
|
|
55
|
-
elif isinstance((content := message_param.content), str):
|
|
56
|
-
converted_message_params.append(
|
|
57
|
-
{
|
|
58
|
-
"role": role if role == "user" else "model",
|
|
59
|
-
"parts": [PartDict(text=content)],
|
|
60
|
-
}
|
|
61
|
-
)
|
|
62
|
-
else:
|
|
63
|
-
converted_content = []
|
|
64
|
-
must_upload: dict[int, BlobDict] = {}
|
|
65
|
-
for index, part in enumerate(content):
|
|
66
|
-
if part.type == "text":
|
|
67
|
-
converted_content.append(PartDict(text=part.text))
|
|
68
|
-
elif part.type == "tool_call":
|
|
69
|
-
converted_content.append(
|
|
70
|
-
PartDict(
|
|
71
|
-
function_call=FunctionCallDict(
|
|
72
|
-
name=part.name, args=part.args, id=part.id
|
|
73
|
-
)
|
|
74
|
-
)
|
|
75
|
-
)
|
|
76
|
-
elif part.type == "tool_result":
|
|
77
|
-
converted_content.append(
|
|
78
|
-
PartDict(
|
|
79
|
-
function_response=FunctionResponseDict(
|
|
80
|
-
name=part.name,
|
|
81
|
-
response={"content": part.content},
|
|
82
|
-
id=part.id,
|
|
83
|
-
)
|
|
84
|
-
)
|
|
85
|
-
)
|
|
86
|
-
elif part.type == "image":
|
|
87
|
-
_check_image_media_type(part.media_type)
|
|
88
|
-
blob_dict = BlobDict(data=part.image, mime_type=part.media_type)
|
|
89
|
-
converted_content.append(PartDict(inline_data=blob_dict))
|
|
90
|
-
image_size = len(part.image)
|
|
91
|
-
total_payload_size += image_size
|
|
92
|
-
if (
|
|
93
|
-
_over_file_size_limit(total_payload_size)
|
|
94
|
-
and not client.vertexai
|
|
95
|
-
):
|
|
96
|
-
must_upload[index] = blob_dict
|
|
97
|
-
total_payload_size -= image_size
|
|
98
|
-
elif part.type == "image_url":
|
|
99
|
-
if (
|
|
100
|
-
client.vertexai
|
|
101
|
-
or not part.url.startswith(("https://", "http://"))
|
|
102
|
-
or "generativelanguage.googleapis.com" in part.url
|
|
103
|
-
):
|
|
104
|
-
converted_content.append(
|
|
105
|
-
PartDict(
|
|
106
|
-
file_data=FileDataDict(
|
|
107
|
-
file_uri=part.url, mime_type=None
|
|
108
|
-
)
|
|
109
|
-
)
|
|
110
|
-
)
|
|
111
|
-
else:
|
|
112
|
-
downloaded_image = _load_media(part.url)
|
|
113
|
-
media_type = f"image/{get_image_type(downloaded_image)}"
|
|
114
|
-
_check_image_media_type(media_type)
|
|
115
|
-
blob_dict = BlobDict(
|
|
116
|
-
data=downloaded_image, mime_type=media_type
|
|
117
|
-
)
|
|
118
|
-
converted_content.append(PartDict(inline_data=blob_dict))
|
|
119
|
-
image_size = len(downloaded_image)
|
|
120
|
-
total_payload_size += image_size
|
|
121
|
-
if (
|
|
122
|
-
_over_file_size_limit(total_payload_size)
|
|
123
|
-
and not client.vertexai
|
|
124
|
-
):
|
|
125
|
-
must_upload[index] = blob_dict
|
|
126
|
-
total_payload_size -= image_size
|
|
127
|
-
elif part.type == "audio":
|
|
128
|
-
_check_audio_media_type(part.media_type)
|
|
129
|
-
audio_data = (
|
|
130
|
-
part.audio
|
|
131
|
-
if isinstance(part.audio, bytes)
|
|
132
|
-
else base64.b64decode(part.audio)
|
|
133
|
-
)
|
|
134
|
-
blob_dict = BlobDict(data=audio_data, mime_type=part.media_type)
|
|
135
|
-
converted_content.append(PartDict(inline_data=blob_dict))
|
|
136
|
-
audio_size = len(audio_data)
|
|
137
|
-
total_payload_size += audio_size
|
|
138
|
-
if (
|
|
139
|
-
_over_file_size_limit(total_payload_size)
|
|
140
|
-
and not client.vertexai
|
|
141
|
-
):
|
|
142
|
-
must_upload[index] = blob_dict
|
|
143
|
-
total_payload_size -= audio_size
|
|
144
|
-
elif part.type == "audio_url":
|
|
145
|
-
if (
|
|
146
|
-
client.vertexai
|
|
147
|
-
or not part.url.startswith(("https://", "http://"))
|
|
148
|
-
or "generativelanguage.googleapis.com" in part.url
|
|
149
|
-
):
|
|
150
|
-
converted_content.append(
|
|
151
|
-
PartDict(
|
|
152
|
-
file_data=FileDataDict(
|
|
153
|
-
file_uri=part.url, mime_type=None
|
|
154
|
-
)
|
|
155
|
-
)
|
|
156
|
-
)
|
|
157
|
-
else:
|
|
158
|
-
downloaded_audio = _load_media(part.url)
|
|
159
|
-
media_type = f"audio/{get_audio_type(downloaded_audio)}"
|
|
160
|
-
_check_audio_media_type(media_type)
|
|
161
|
-
blob_dict = BlobDict(
|
|
162
|
-
data=downloaded_audio, mime_type=media_type
|
|
163
|
-
)
|
|
164
|
-
converted_content.append(PartDict(inline_data=blob_dict))
|
|
165
|
-
audio_size = len(downloaded_audio)
|
|
166
|
-
total_payload_size += audio_size
|
|
167
|
-
if (
|
|
168
|
-
_over_file_size_limit(total_payload_size)
|
|
169
|
-
and not client.vertexai
|
|
170
|
-
):
|
|
171
|
-
must_upload[index] = blob_dict
|
|
172
|
-
total_payload_size -= audio_size
|
|
173
|
-
elif part.type == "document":
|
|
174
|
-
_check_document_media_type(part.media_type)
|
|
175
|
-
blob_dict = BlobDict(data=part.document, mime_type=part.media_type)
|
|
176
|
-
converted_content.append(PartDict(inline_data=blob_dict))
|
|
177
|
-
document_size = len(part.document)
|
|
178
|
-
total_payload_size += document_size
|
|
179
|
-
if (
|
|
180
|
-
_over_file_size_limit(total_payload_size)
|
|
181
|
-
and not client.vertexai
|
|
182
|
-
):
|
|
183
|
-
must_upload[index] = blob_dict
|
|
184
|
-
total_payload_size -= document_size
|
|
185
|
-
elif part.type == "document_url":
|
|
186
|
-
if (
|
|
187
|
-
client.vertexai
|
|
188
|
-
or not part.url.startswith(("https://", "http://"))
|
|
189
|
-
or "generativelanguage.googleapis.com" in part.url
|
|
190
|
-
):
|
|
191
|
-
converted_content.append(
|
|
192
|
-
PartDict(
|
|
193
|
-
file_data=FileDataDict(
|
|
194
|
-
file_uri=part.url, mime_type=None
|
|
195
|
-
)
|
|
196
|
-
)
|
|
197
|
-
)
|
|
198
|
-
else:
|
|
199
|
-
media_type = None
|
|
200
|
-
try:
|
|
201
|
-
downloaded_document = _load_media(part.url)
|
|
202
|
-
document_types = {
|
|
203
|
-
"pdf": "application/pdf",
|
|
204
|
-
"html": "text/html",
|
|
205
|
-
"xml": "text/xml",
|
|
206
|
-
"rtf": "text/rtf",
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
try:
|
|
210
|
-
document_type_ext = get_document_type(
|
|
211
|
-
downloaded_document
|
|
212
|
-
)
|
|
213
|
-
media_type = document_types.get(document_type_ext)
|
|
214
|
-
except ValueError:
|
|
215
|
-
try:
|
|
216
|
-
downloaded_document.decode("utf-8")
|
|
217
|
-
media_type = "text/plain"
|
|
218
|
-
except UnicodeDecodeError:
|
|
219
|
-
pass
|
|
220
|
-
|
|
221
|
-
if media_type is None:
|
|
222
|
-
raise ValueError(
|
|
223
|
-
f"Unsupported document format detected for URL: {part.url}. "
|
|
224
|
-
"Google API only supports the following document formats: "
|
|
225
|
-
"PDF, JavaScript, Python, TXT, HTML, CSS, Markdown, CSV, XML and RTF. "
|
|
226
|
-
"Please provide a document in one of these supported formats."
|
|
227
|
-
)
|
|
228
|
-
|
|
229
|
-
_check_document_media_type(media_type)
|
|
230
|
-
blob_dict = BlobDict(
|
|
231
|
-
data=downloaded_document, mime_type=media_type
|
|
232
|
-
)
|
|
233
|
-
converted_content.append(PartDict(inline_data=blob_dict))
|
|
234
|
-
document_size = len(downloaded_document)
|
|
235
|
-
total_payload_size += document_size
|
|
236
|
-
if (
|
|
237
|
-
_over_file_size_limit(total_payload_size)
|
|
238
|
-
and not client.vertexai
|
|
239
|
-
):
|
|
240
|
-
must_upload[index] = blob_dict
|
|
241
|
-
total_payload_size -= document_size
|
|
242
|
-
except ValueError as e:
|
|
243
|
-
raise ValueError(
|
|
244
|
-
f"Failed to process document from URL: {part.url}. "
|
|
245
|
-
f"Error details: {str(e)}. "
|
|
246
|
-
"Please ensure the URL is accessible and points to a supported document format."
|
|
247
|
-
)
|
|
248
|
-
else:
|
|
249
|
-
raise ValueError(
|
|
250
|
-
"Google currently only supports text, tool_call, tool_result, image, audio, and document parts. "
|
|
251
|
-
f"Part provided: {part.type}"
|
|
252
|
-
)
|
|
253
|
-
|
|
254
|
-
if must_upload and not client.vertexai:
|
|
255
|
-
indices, blob_dicts = zip(*must_upload.items(), strict=True)
|
|
256
|
-
upload_tasks = [
|
|
257
|
-
client.aio.files.upload(
|
|
258
|
-
file=io.BytesIO(blob_dict["data"]),
|
|
259
|
-
config={"mime_type": blob_dict.get("mime_type", None)},
|
|
260
|
-
)
|
|
261
|
-
for blob_dict in blob_dicts
|
|
262
|
-
]
|
|
263
|
-
file_refs = await asyncio.gather(*upload_tasks)
|
|
264
|
-
for index, file_ref in zip(indices, file_refs, strict=True):
|
|
265
|
-
converted_content[index] = PartDict(
|
|
266
|
-
file_data=FileDataDict(
|
|
267
|
-
file_uri=file_ref.uri, mime_type=file_ref.mime_type
|
|
268
|
-
)
|
|
269
|
-
)
|
|
270
|
-
|
|
271
|
-
converted_message_params.append(
|
|
272
|
-
{
|
|
273
|
-
"role": role if role == "user" else "model",
|
|
274
|
-
"parts": converted_content,
|
|
275
|
-
}
|
|
276
|
-
)
|
|
277
|
-
return converted_message_params
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
def convert_message_params(
|
|
281
|
-
message_params: list[BaseMessageParam | ContentDict], client: Client
|
|
282
|
-
) -> list[ContentDict]:
|
|
283
|
-
"""Convert message params to Google's ContentDict format.
|
|
284
|
-
|
|
285
|
-
If called from sync context, uses asyncio.run().
|
|
286
|
-
If called from async context, uses the current event loop.
|
|
287
|
-
"""
|
|
288
|
-
try:
|
|
289
|
-
asyncio.get_running_loop()
|
|
290
|
-
with ThreadPoolExecutor(max_workers=1) as executor:
|
|
291
|
-
future = executor.submit(
|
|
292
|
-
asyncio.run, _convert_message_params_async(message_params, client)
|
|
293
|
-
)
|
|
294
|
-
return future.result()
|
|
295
|
-
except RuntimeError:
|
|
296
|
-
...
|
|
297
|
-
return asyncio.run(_convert_message_params_async(message_params, client))
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
"""Get JSON output from a Google response."""
|
|
2
|
-
|
|
3
|
-
import json
|
|
4
|
-
|
|
5
|
-
from proto.marshal.collections import RepeatedComposite
|
|
6
|
-
|
|
7
|
-
from ..call_response import GoogleCallResponse
|
|
8
|
-
from ..call_response_chunk import GoogleCallResponseChunk
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
def get_json_output(
|
|
12
|
-
response: GoogleCallResponse | GoogleCallResponseChunk, json_mode: bool
|
|
13
|
-
) -> str:
|
|
14
|
-
"""Extracts the JSON output from a Google response."""
|
|
15
|
-
if isinstance(response, GoogleCallResponse):
|
|
16
|
-
if json_mode and (content := response.content):
|
|
17
|
-
json_start = content.index("{")
|
|
18
|
-
json_end = content.rfind("}")
|
|
19
|
-
return content[json_start : json_end + 1]
|
|
20
|
-
elif tool_calls := [
|
|
21
|
-
function_call
|
|
22
|
-
for function_call in (response.response.function_calls or []) # pyright: ignore [reportOptionalSubscript, reportOptionalIterable, reportOptionalMemberAccess]
|
|
23
|
-
if function_call.args # pyright: ignore [reportOptionalSubscript, reportOptionalIterable, reportOptionalMemberAccess]
|
|
24
|
-
]:
|
|
25
|
-
return json.dumps(
|
|
26
|
-
{
|
|
27
|
-
k: v if not isinstance(v, RepeatedComposite) else list(v)
|
|
28
|
-
for k, v in (tool_calls[0].args or {}).items() # pyright: ignore [reportOptionalMemberAccess]
|
|
29
|
-
}
|
|
30
|
-
if isinstance(tool_calls, list) and tool_calls[0]
|
|
31
|
-
else {}
|
|
32
|
-
)
|
|
33
|
-
else:
|
|
34
|
-
raise ValueError("No tool call or JSON object found in response.")
|
|
35
|
-
elif not json_mode:
|
|
36
|
-
raise ValueError("Google only supports structured streaming in json mode.")
|
|
37
|
-
return response.content
|