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
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
"""Call response chunk module."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
from typing import Any
|
|
6
|
-
|
|
7
|
-
from ..core.base.call_response_chunk import BaseCallResponseChunk
|
|
8
|
-
from ..core.base.types import CostMetadata, FinishReason, Usage
|
|
9
|
-
from ._response_metaclass import _ResponseMetaclass
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class CallResponseChunk(
|
|
13
|
-
BaseCallResponseChunk[Any, FinishReason],
|
|
14
|
-
metaclass=_ResponseMetaclass,
|
|
15
|
-
):
|
|
16
|
-
_response: BaseCallResponseChunk[Any, Any]
|
|
17
|
-
|
|
18
|
-
def __init__(
|
|
19
|
-
self,
|
|
20
|
-
response: BaseCallResponseChunk[Any, Any],
|
|
21
|
-
) -> None:
|
|
22
|
-
super().__init__(
|
|
23
|
-
**{field: getattr(response, field) for field in response.model_fields}
|
|
24
|
-
)
|
|
25
|
-
object.__setattr__(self, "_response", response)
|
|
26
|
-
|
|
27
|
-
def __getattribute__(self, name: str) -> Any: # noqa: ANN401
|
|
28
|
-
special_names = {
|
|
29
|
-
"_response",
|
|
30
|
-
"__dict__",
|
|
31
|
-
"__class__",
|
|
32
|
-
"model_fields",
|
|
33
|
-
"__annotations__",
|
|
34
|
-
"__pydantic_validator__",
|
|
35
|
-
"__pydantic_fields_set__",
|
|
36
|
-
"__pydantic_extra__",
|
|
37
|
-
"__pydantic_private__",
|
|
38
|
-
"__class_getitem__",
|
|
39
|
-
"_properties",
|
|
40
|
-
"cost_metadata",
|
|
41
|
-
"finish_reasons",
|
|
42
|
-
"usage",
|
|
43
|
-
} | set(object.__getattribute__(self, "_properties"))
|
|
44
|
-
|
|
45
|
-
if name in special_names:
|
|
46
|
-
return object.__getattribute__(self, name)
|
|
47
|
-
|
|
48
|
-
try:
|
|
49
|
-
response = object.__getattribute__(self, "_response")
|
|
50
|
-
return getattr(response, name)
|
|
51
|
-
except AttributeError:
|
|
52
|
-
return object.__getattribute__(self, name)
|
|
53
|
-
|
|
54
|
-
@property
|
|
55
|
-
def finish_reasons(self) -> list[FinishReason] | None:
|
|
56
|
-
return self._response.common_finish_reasons
|
|
57
|
-
|
|
58
|
-
@property
|
|
59
|
-
def usage(self) -> Usage | None:
|
|
60
|
-
return self._response.common_usage
|
|
61
|
-
|
|
62
|
-
@property
|
|
63
|
-
def cost_metadata(self) -> CostMetadata:
|
|
64
|
-
"""Get metadata required for cost calculation."""
|
|
65
|
-
|
|
66
|
-
return self._response.cost_metadata
|
mirascope/llm/stream.py
DELETED
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
"""This module contains the Stream class that inherits from BaseStream."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
from collections.abc import AsyncGenerator, Generator
|
|
6
|
-
from typing import Any, TypeVar
|
|
7
|
-
|
|
8
|
-
from ..core.base import (
|
|
9
|
-
BaseCallParams,
|
|
10
|
-
BaseCallResponse,
|
|
11
|
-
BaseCallResponseChunk,
|
|
12
|
-
BaseDynamicConfig,
|
|
13
|
-
BaseMessageParam,
|
|
14
|
-
BaseTool,
|
|
15
|
-
)
|
|
16
|
-
from ..core.base.call_response import JsonableType
|
|
17
|
-
from ..core.base.stream import BaseStream
|
|
18
|
-
from ..core.base.types import FinishReason
|
|
19
|
-
from ..llm.call_response import CallResponse
|
|
20
|
-
from ..llm.call_response_chunk import CallResponseChunk
|
|
21
|
-
from .tool import Tool
|
|
22
|
-
|
|
23
|
-
_BaseCallResponseT = TypeVar("_BaseCallResponseT", bound=BaseCallResponse)
|
|
24
|
-
_BaseCallResponseChunkT = TypeVar(
|
|
25
|
-
"_BaseCallResponseChunkT", bound=BaseCallResponseChunk
|
|
26
|
-
)
|
|
27
|
-
_UserMessageParamT = TypeVar("_UserMessageParamT", bound=BaseMessageParam)
|
|
28
|
-
_AssistantMessageParamT = TypeVar("_AssistantMessageParamT", bound=BaseMessageParam)
|
|
29
|
-
_ToolMessageParamT = TypeVar("_ToolMessageParamT", bound=BaseMessageParam)
|
|
30
|
-
_MessageParamT = TypeVar("_MessageParamT", bound=BaseMessageParam)
|
|
31
|
-
_BaseToolT = TypeVar("_BaseToolT", bound=BaseTool)
|
|
32
|
-
_ToolSchemaT = TypeVar("_ToolSchemaT")
|
|
33
|
-
_BaseDynamicConfigT = TypeVar("_BaseDynamicConfigT", bound=BaseDynamicConfig)
|
|
34
|
-
_BaseCallParamsT = TypeVar("_BaseCallParamsT", bound=BaseCallParams)
|
|
35
|
-
_FinishReasonT = TypeVar("_FinishReasonT")
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
class Stream(
|
|
39
|
-
BaseStream[
|
|
40
|
-
BaseCallResponse,
|
|
41
|
-
BaseCallResponseChunk,
|
|
42
|
-
BaseMessageParam,
|
|
43
|
-
BaseMessageParam,
|
|
44
|
-
BaseMessageParam,
|
|
45
|
-
BaseMessageParam,
|
|
46
|
-
BaseTool,
|
|
47
|
-
Any,
|
|
48
|
-
BaseDynamicConfig,
|
|
49
|
-
BaseCallParams,
|
|
50
|
-
FinishReason,
|
|
51
|
-
],
|
|
52
|
-
):
|
|
53
|
-
"""A non-pydantic class that inherits from BaseStream."""
|
|
54
|
-
|
|
55
|
-
_stream: BaseStream[
|
|
56
|
-
BaseCallResponse,
|
|
57
|
-
BaseCallResponseChunk,
|
|
58
|
-
BaseMessageParam,
|
|
59
|
-
BaseMessageParam,
|
|
60
|
-
BaseMessageParam,
|
|
61
|
-
BaseMessageParam,
|
|
62
|
-
BaseTool,
|
|
63
|
-
Any,
|
|
64
|
-
BaseDynamicConfig,
|
|
65
|
-
BaseCallParams,
|
|
66
|
-
FinishReason,
|
|
67
|
-
]
|
|
68
|
-
|
|
69
|
-
def __init__(
|
|
70
|
-
self,
|
|
71
|
-
*,
|
|
72
|
-
stream: BaseStream[
|
|
73
|
-
BaseCallResponse,
|
|
74
|
-
BaseCallResponseChunk,
|
|
75
|
-
BaseMessageParam,
|
|
76
|
-
BaseMessageParam,
|
|
77
|
-
BaseMessageParam,
|
|
78
|
-
BaseMessageParam,
|
|
79
|
-
BaseTool,
|
|
80
|
-
Any,
|
|
81
|
-
BaseDynamicConfig,
|
|
82
|
-
BaseCallParams,
|
|
83
|
-
FinishReason,
|
|
84
|
-
],
|
|
85
|
-
) -> None:
|
|
86
|
-
"""Initialize the Stream class."""
|
|
87
|
-
object.__setattr__(self, "_stream", stream)
|
|
88
|
-
|
|
89
|
-
def __getattribute__(self, name: str) -> Any: # noqa: ANN401
|
|
90
|
-
special_names = {
|
|
91
|
-
"_stream",
|
|
92
|
-
"cost",
|
|
93
|
-
"_construct_message_param",
|
|
94
|
-
"construct_call_response",
|
|
95
|
-
"tool_message_params",
|
|
96
|
-
"__dict__",
|
|
97
|
-
"__class__",
|
|
98
|
-
"__repr__",
|
|
99
|
-
"__str__",
|
|
100
|
-
"__iter__",
|
|
101
|
-
"__aiter__",
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
if name in special_names:
|
|
105
|
-
return object.__getattribute__(self, name)
|
|
106
|
-
response = object.__getattribute__(self, "_stream")
|
|
107
|
-
return getattr(response, name)
|
|
108
|
-
|
|
109
|
-
def __iter__( # pyright: ignore [reportIncompatibleMethodOverride]
|
|
110
|
-
self,
|
|
111
|
-
) -> Generator[
|
|
112
|
-
tuple[CallResponseChunk, Tool[_ToolMessageParamT] | None],
|
|
113
|
-
None,
|
|
114
|
-
None,
|
|
115
|
-
]:
|
|
116
|
-
"""Iterate over the stream."""
|
|
117
|
-
for chunk, tool in self._stream:
|
|
118
|
-
yield (
|
|
119
|
-
CallResponseChunk(response=chunk), # pyright: ignore [reportAbstractUsage]
|
|
120
|
-
Tool(tool=tool) if tool is not None else None, # pyright: ignore [reportAbstractUsage]
|
|
121
|
-
)
|
|
122
|
-
|
|
123
|
-
async def __aiter__( # pyright: ignore [reportIncompatibleMethodOverride]
|
|
124
|
-
self,
|
|
125
|
-
) -> AsyncGenerator[
|
|
126
|
-
tuple[CallResponseChunk, Tool[_ToolMessageParamT] | None],
|
|
127
|
-
None,
|
|
128
|
-
]:
|
|
129
|
-
"""Iterates over the stream and stores useful information."""
|
|
130
|
-
async for chunk, tool in self._stream:
|
|
131
|
-
yield (
|
|
132
|
-
CallResponseChunk(response=chunk), # pyright: ignore [reportAbstractUsage]
|
|
133
|
-
Tool(tool=tool) if tool is not None else None, # pyright: ignore [reportAbstractUsage]
|
|
134
|
-
)
|
|
135
|
-
|
|
136
|
-
@property
|
|
137
|
-
def cost(self) -> float | None:
|
|
138
|
-
return self._stream.cost
|
|
139
|
-
|
|
140
|
-
def _construct_message_param(
|
|
141
|
-
self, tool_calls: list[Any] | None = None, content: str | None = None
|
|
142
|
-
) -> BaseMessageParam:
|
|
143
|
-
return self._stream._construct_message_param(
|
|
144
|
-
tool_calls=tool_calls, content=content
|
|
145
|
-
)
|
|
146
|
-
|
|
147
|
-
def construct_call_response( # pyright: ignore [reportIncompatibleMethodOverride]
|
|
148
|
-
self,
|
|
149
|
-
) -> CallResponse:
|
|
150
|
-
return CallResponse(response=self._stream.construct_call_response()) # pyright: ignore [reportAbstractUsage]
|
|
151
|
-
|
|
152
|
-
@classmethod
|
|
153
|
-
def tool_message_params( # pyright: ignore [reportIncompatibleMethodOverride]
|
|
154
|
-
cls, tools_and_outputs: list[tuple[Tool, JsonableType]]
|
|
155
|
-
) -> list[BaseMessageParam]:
|
|
156
|
-
"""Returns the tool message parameters for tool call results.
|
|
157
|
-
|
|
158
|
-
Args:
|
|
159
|
-
tools_and_outputs: The list of tools and their outputs from which the tool
|
|
160
|
-
message parameters should be constructed.
|
|
161
|
-
"""
|
|
162
|
-
return CallResponse.tool_message_params(tools_and_outputs)
|
mirascope/llm/tool.py
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
"""Tool class for the provider-agnostic tool."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
from typing import Any, TypeVar
|
|
6
|
-
|
|
7
|
-
from pydantic._internal._model_construction import ModelMetaclass
|
|
8
|
-
|
|
9
|
-
from ..core.base.tool import BaseTool
|
|
10
|
-
|
|
11
|
-
_ToolResponseT = TypeVar("_ToolResponseT", bound=BaseTool)
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class _DelegateAbstractMethodsForTool(ModelMetaclass):
|
|
15
|
-
def __new__(
|
|
16
|
-
mcls,
|
|
17
|
-
name: str,
|
|
18
|
-
bases: tuple[type, ...],
|
|
19
|
-
namespace: dict[str, Any],
|
|
20
|
-
**kwargs: Any, # noqa: ANN401
|
|
21
|
-
) -> type:
|
|
22
|
-
cls = super().__new__(mcls, name, bases, namespace)
|
|
23
|
-
cls.__abstractmethods__ = frozenset()
|
|
24
|
-
return cls
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
_ToolMessageParamT = TypeVar("_ToolMessageParamT")
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
class Tool(BaseTool, metaclass=_DelegateAbstractMethodsForTool):
|
|
31
|
-
"""
|
|
32
|
-
A provider-agnostic Tool class.
|
|
33
|
-
- No BaseProviderConverter
|
|
34
|
-
- Relies on _response having `common_` methods/properties if needed.
|
|
35
|
-
"""
|
|
36
|
-
|
|
37
|
-
_tool: BaseTool
|
|
38
|
-
|
|
39
|
-
def __init__(self, tool: BaseTool) -> None:
|
|
40
|
-
super().__init__(**{field: getattr(tool, field) for field in tool.model_fields})
|
|
41
|
-
object.__setattr__(self, "_tool", tool)
|
|
42
|
-
|
|
43
|
-
def __getattribute__(self, name: str) -> Any: # noqa: ANN401
|
|
44
|
-
special_names = {
|
|
45
|
-
"_response",
|
|
46
|
-
"__dict__",
|
|
47
|
-
"__class__",
|
|
48
|
-
"model_fields",
|
|
49
|
-
"__annotations__",
|
|
50
|
-
"__pydantic_validator__",
|
|
51
|
-
"__pydantic_fields_set__",
|
|
52
|
-
"__pydantic_extra__",
|
|
53
|
-
"__pydantic_private__",
|
|
54
|
-
"__class_getitem__",
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
if name in special_names:
|
|
58
|
-
return object.__getattribute__(self, name)
|
|
59
|
-
|
|
60
|
-
try:
|
|
61
|
-
tool = object.__getattribute__(self, "_tool")
|
|
62
|
-
return getattr(tool, name)
|
|
63
|
-
except AttributeError:
|
|
64
|
-
return object.__getattribute__(self, name)
|
mirascope/mcp/__init__.py
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
"""Mirascope Model Context Protocol (MCP) implementation."""
|
|
2
|
-
|
|
3
|
-
from .client import MCPClient, sse_client, stdio_client
|
|
4
|
-
from .server import MCPServer # DEPRECATED
|
|
5
|
-
from .tools import MCPTool # DEPRECATED
|
|
6
|
-
|
|
7
|
-
__all__ = ["MCPClient", "MCPServer", "MCPTool", "sse_client", "stdio_client"]
|
mirascope/mcp/_utils.py
DELETED
|
@@ -1,288 +0,0 @@
|
|
|
1
|
-
"""MCP client utility functions."""
|
|
2
|
-
|
|
3
|
-
import base64
|
|
4
|
-
import string
|
|
5
|
-
from collections.abc import AsyncGenerator, Awaitable, Callable
|
|
6
|
-
from contextlib import asynccontextmanager
|
|
7
|
-
from typing import Any
|
|
8
|
-
|
|
9
|
-
from anyio import create_memory_object_stream, create_task_group
|
|
10
|
-
from anyio.streams.memory import MemoryObjectReceiveStream
|
|
11
|
-
from mcp.types import (
|
|
12
|
-
EmbeddedResource,
|
|
13
|
-
ImageContent,
|
|
14
|
-
JSONRPCMessage,
|
|
15
|
-
PromptMessage,
|
|
16
|
-
TextContent,
|
|
17
|
-
TextResourceContents,
|
|
18
|
-
)
|
|
19
|
-
from mcp.types import Tool as MCPTool
|
|
20
|
-
from pydantic import BaseModel, ConfigDict, Field, create_model
|
|
21
|
-
|
|
22
|
-
from ..core import BaseMessageParam, BaseTool
|
|
23
|
-
from ..core.base import AudioPart, DocumentPart, ImagePart
|
|
24
|
-
|
|
25
|
-
_UNSET = object()
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
def create_tool_call(
|
|
29
|
-
name: str,
|
|
30
|
-
call_tool: Callable[[str, dict | None], Awaitable[Any]],
|
|
31
|
-
) -> Callable[..., Awaitable[list[str | ImageContent | EmbeddedResource]]]:
|
|
32
|
-
"""Create a tool call function for a Mirascope Tool.
|
|
33
|
-
|
|
34
|
-
Args:
|
|
35
|
-
name: The name of the tool
|
|
36
|
-
call_tool: The function to call the tool
|
|
37
|
-
|
|
38
|
-
Returns:
|
|
39
|
-
A function that can be used as the call method for a Tool
|
|
40
|
-
"""
|
|
41
|
-
|
|
42
|
-
async def call(self: BaseTool) -> list[str | ImageContent | EmbeddedResource]:
|
|
43
|
-
args = {key: value for key, value in self.args.items() if value is not _UNSET}
|
|
44
|
-
result = await call_tool(name, args if args else None)
|
|
45
|
-
if result.isError:
|
|
46
|
-
raise RuntimeError(f"MCP Server returned error: {self._name()}")
|
|
47
|
-
return [
|
|
48
|
-
content.text if isinstance(content, TextContent) else content
|
|
49
|
-
for content in result.content
|
|
50
|
-
]
|
|
51
|
-
|
|
52
|
-
return call
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
def convert_prompt_message_to_base_message_params(
|
|
56
|
-
prompt_message: PromptMessage,
|
|
57
|
-
) -> BaseMessageParam:
|
|
58
|
-
"""
|
|
59
|
-
Convert a single PromptMessage back into a BaseMessageParam.
|
|
60
|
-
|
|
61
|
-
Args:
|
|
62
|
-
prompt_message: A PromptMessage instance.
|
|
63
|
-
|
|
64
|
-
Returns:
|
|
65
|
-
A BaseMessageParam instance representing the given prompt_message.
|
|
66
|
-
|
|
67
|
-
Raises:
|
|
68
|
-
ValueError: If the role is invalid or if the content type is unsupported.
|
|
69
|
-
"""
|
|
70
|
-
|
|
71
|
-
# Validate role
|
|
72
|
-
if prompt_message.role not in ["user", "assistant"]:
|
|
73
|
-
raise ValueError(f"invalid role: {prompt_message.role}")
|
|
74
|
-
|
|
75
|
-
content = prompt_message.content
|
|
76
|
-
|
|
77
|
-
# Handle TextContent
|
|
78
|
-
if isinstance(content, TextContent):
|
|
79
|
-
# If it's text, we can just return a single string
|
|
80
|
-
return BaseMessageParam(role=prompt_message.role, content=content.text)
|
|
81
|
-
|
|
82
|
-
# Handle ImageContent
|
|
83
|
-
elif isinstance(content, ImageContent):
|
|
84
|
-
decoded_image = base64.b64decode(content.data)
|
|
85
|
-
|
|
86
|
-
image_part = ImagePart(
|
|
87
|
-
type="image",
|
|
88
|
-
image=decoded_image,
|
|
89
|
-
media_type=content.mimeType,
|
|
90
|
-
detail=None, # detail not provided by PromptMessage
|
|
91
|
-
)
|
|
92
|
-
return BaseMessageParam(role=prompt_message.role, content=[image_part])
|
|
93
|
-
|
|
94
|
-
elif isinstance(content, EmbeddedResource):
|
|
95
|
-
resource = content.resource
|
|
96
|
-
if isinstance(resource, TextResourceContents):
|
|
97
|
-
# For text content embedded resources, just return the text
|
|
98
|
-
return BaseMessageParam(role=prompt_message.role, content=resource.text)
|
|
99
|
-
else:
|
|
100
|
-
mime_type = resource.mimeType
|
|
101
|
-
if not mime_type:
|
|
102
|
-
raise ValueError(
|
|
103
|
-
"BlobResourceContents has no mimeType, cannot determine content type."
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
decoded_data = base64.b64decode(resource.blob)
|
|
107
|
-
|
|
108
|
-
if mime_type.startswith("image/"):
|
|
109
|
-
# Treat as ImagePart
|
|
110
|
-
image_part = ImagePart(
|
|
111
|
-
type="image",
|
|
112
|
-
image=decoded_data,
|
|
113
|
-
media_type=mime_type,
|
|
114
|
-
detail=None,
|
|
115
|
-
)
|
|
116
|
-
return BaseMessageParam(role=prompt_message.role, content=[image_part])
|
|
117
|
-
elif mime_type == "application/pdf":
|
|
118
|
-
doc_part = DocumentPart(
|
|
119
|
-
type="document", media_type=mime_type, document=decoded_data
|
|
120
|
-
)
|
|
121
|
-
return BaseMessageParam(role=prompt_message.role, content=[doc_part])
|
|
122
|
-
elif mime_type.startswith("audio/"):
|
|
123
|
-
# Treat as AudioPart
|
|
124
|
-
audio_part = AudioPart(
|
|
125
|
-
type="audio", media_type=mime_type, audio=decoded_data
|
|
126
|
-
)
|
|
127
|
-
return BaseMessageParam(role=prompt_message.role, content=[audio_part])
|
|
128
|
-
else:
|
|
129
|
-
raise ValueError(f"Unsupported mime type: {mime_type}")
|
|
130
|
-
|
|
131
|
-
else:
|
|
132
|
-
raise ValueError(f"Unsupported content type: {type(content)}")
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
def snake_to_pascal(snake: str) -> str:
|
|
136
|
-
"""Convert a snake_case string to PascalCase.
|
|
137
|
-
|
|
138
|
-
Args:
|
|
139
|
-
snake: A snake_case string
|
|
140
|
-
|
|
141
|
-
Returns:
|
|
142
|
-
The string converted to PascalCase
|
|
143
|
-
"""
|
|
144
|
-
return string.capwords(snake.replace("_", " ")).replace(" ", "")
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
def build_object_type(
|
|
148
|
-
properties: dict[str, Any], required: list[str], name: str
|
|
149
|
-
) -> type[BaseModel]:
|
|
150
|
-
"""Build a Pydantic model from JSON Schema properties.
|
|
151
|
-
|
|
152
|
-
Args:
|
|
153
|
-
properties: JSON Schema properties dictionary
|
|
154
|
-
required: List of required property names
|
|
155
|
-
name: Name for the generated model
|
|
156
|
-
|
|
157
|
-
Returns:
|
|
158
|
-
A dynamically created Pydantic model class
|
|
159
|
-
"""
|
|
160
|
-
fields = {}
|
|
161
|
-
for prop_name, prop_schema in properties.items():
|
|
162
|
-
class_name = snake_to_pascal(prop_name)
|
|
163
|
-
type_ = json_schema_to_python_type(prop_schema, class_name)
|
|
164
|
-
if prop_name in required:
|
|
165
|
-
fields[prop_name] = (
|
|
166
|
-
type_,
|
|
167
|
-
Field(..., description=prop_schema.get("description")),
|
|
168
|
-
)
|
|
169
|
-
else:
|
|
170
|
-
fields[prop_name] = (
|
|
171
|
-
type_ | None,
|
|
172
|
-
Field(None, description=prop_schema.get("description")),
|
|
173
|
-
)
|
|
174
|
-
|
|
175
|
-
return create_model(name, __config__=ConfigDict(extra="allow"), **fields)
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
def json_schema_to_python_type(schema: dict[str, Any], name: str = "Model") -> Any: # noqa: ANN401
|
|
179
|
-
"""
|
|
180
|
-
Recursively convert a JSON Schema snippet into a Python type annotation or a dynamically generated pydantic model.
|
|
181
|
-
|
|
182
|
-
Args:
|
|
183
|
-
schema: JSON Schema to convert
|
|
184
|
-
name: Name for any generated models
|
|
185
|
-
|
|
186
|
-
Returns:
|
|
187
|
-
Corresponding Python type or Pydantic model
|
|
188
|
-
"""
|
|
189
|
-
json_type = schema.get("type", "any")
|
|
190
|
-
|
|
191
|
-
if json_type == "string":
|
|
192
|
-
return str
|
|
193
|
-
elif json_type == "number":
|
|
194
|
-
return float
|
|
195
|
-
elif json_type == "integer":
|
|
196
|
-
return int
|
|
197
|
-
elif json_type == "boolean":
|
|
198
|
-
return bool
|
|
199
|
-
elif json_type == "array":
|
|
200
|
-
# Recursively determine the items type for arrays
|
|
201
|
-
items_schema = schema.get("items", {})
|
|
202
|
-
items_type = json_schema_to_python_type(items_schema)
|
|
203
|
-
return list[items_type]
|
|
204
|
-
elif json_type == "object":
|
|
205
|
-
# Recursively build a dynamic model for objects
|
|
206
|
-
properties = schema.get("properties", {})
|
|
207
|
-
required = schema.get("required", [])
|
|
208
|
-
return build_object_type(properties, required, name)
|
|
209
|
-
else:
|
|
210
|
-
# Default fallback
|
|
211
|
-
return Any
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
def create_tool_from_mcp_tool(tool: MCPTool) -> type[BaseTool]:
|
|
215
|
-
"""
|
|
216
|
-
Create a `BaseTool` type definition from the given MCP Tool instance.
|
|
217
|
-
|
|
218
|
-
Args:
|
|
219
|
-
tool: MCP tool instance.
|
|
220
|
-
|
|
221
|
-
Returns:
|
|
222
|
-
A dynamically created `Tool` schema.
|
|
223
|
-
"""
|
|
224
|
-
schema = tool.inputSchema
|
|
225
|
-
properties = schema.get("properties", {})
|
|
226
|
-
required_fields = schema.get("required", [])
|
|
227
|
-
|
|
228
|
-
fields = {}
|
|
229
|
-
for field_name, field_schema in properties.items():
|
|
230
|
-
field_type = json_schema_to_python_type(field_schema)
|
|
231
|
-
if field_schema.get("nullable", False):
|
|
232
|
-
field_type = field_type | None
|
|
233
|
-
|
|
234
|
-
field_info = {
|
|
235
|
-
"default": field_schema.get(
|
|
236
|
-
"default", ... if field_name in required_fields else _UNSET
|
|
237
|
-
)
|
|
238
|
-
}
|
|
239
|
-
if description := field_schema.get("description", ""):
|
|
240
|
-
field_info["description"] = description
|
|
241
|
-
|
|
242
|
-
fields[field_name] = (field_type, Field(**field_info))
|
|
243
|
-
|
|
244
|
-
return create_model(
|
|
245
|
-
snake_to_pascal(tool.name),
|
|
246
|
-
__base__=BaseTool,
|
|
247
|
-
__doc__=tool.description,
|
|
248
|
-
**fields,
|
|
249
|
-
)
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
@asynccontextmanager
|
|
253
|
-
async def read_stream_exception_filer(
|
|
254
|
-
original_read: MemoryObjectReceiveStream[JSONRPCMessage | Exception],
|
|
255
|
-
exception_handler: Callable[[Exception], None] | None = None,
|
|
256
|
-
) -> AsyncGenerator[MemoryObjectReceiveStream[JSONRPCMessage], None]:
|
|
257
|
-
"""
|
|
258
|
-
Handle exceptions in the original stream.
|
|
259
|
-
Default handler is to ignore read stream exception for invalid JSON lines and log them.
|
|
260
|
-
|
|
261
|
-
Args:
|
|
262
|
-
original_read: The original stream to read from.
|
|
263
|
-
exception_handler: An optional handler for exception.
|
|
264
|
-
|
|
265
|
-
Yields:
|
|
266
|
-
A filtered stream with exceptions removed
|
|
267
|
-
"""
|
|
268
|
-
read_stream_writer, filtered_read = create_memory_object_stream(0)
|
|
269
|
-
|
|
270
|
-
async def task() -> None:
|
|
271
|
-
try:
|
|
272
|
-
async with original_read:
|
|
273
|
-
async for msg in original_read:
|
|
274
|
-
if isinstance(msg, Exception):
|
|
275
|
-
if exception_handler:
|
|
276
|
-
exception_handler(msg)
|
|
277
|
-
continue
|
|
278
|
-
await read_stream_writer.send(msg)
|
|
279
|
-
finally:
|
|
280
|
-
await read_stream_writer.aclose()
|
|
281
|
-
|
|
282
|
-
async with create_task_group() as tg:
|
|
283
|
-
tg.start_soon(task)
|
|
284
|
-
try:
|
|
285
|
-
yield filtered_read
|
|
286
|
-
finally:
|
|
287
|
-
await filtered_read.aclose()
|
|
288
|
-
tg.cancel_scope.cancel()
|