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
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
"""Stream classes for streaming assistant content parts."""
|
|
2
|
+
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
from collections.abc import AsyncIterator, Iterator
|
|
5
|
+
from typing import Generic, Literal, TypeAlias, TypeVar
|
|
6
|
+
|
|
7
|
+
from ..content import (
|
|
8
|
+
AssistantContentPart,
|
|
9
|
+
Text,
|
|
10
|
+
TextChunk,
|
|
11
|
+
Thought,
|
|
12
|
+
ThoughtChunk,
|
|
13
|
+
ToolCall,
|
|
14
|
+
ToolCallChunk,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
ContentT = TypeVar("ContentT", bound=AssistantContentPart)
|
|
18
|
+
"""Type variable for content types (Text, Thought, ToolCall)."""
|
|
19
|
+
|
|
20
|
+
DeltaT = TypeVar("DeltaT")
|
|
21
|
+
"""Type variable for the deltas that the stream provides on iteration."""
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class BaseStream(ABC, Generic[ContentT, DeltaT]):
|
|
25
|
+
"""Base class for synchronous streaming content."""
|
|
26
|
+
|
|
27
|
+
@abstractmethod
|
|
28
|
+
def __iter__(self) -> Iterator[DeltaT]:
|
|
29
|
+
"""Iterate over content deltas as they arrive."""
|
|
30
|
+
...
|
|
31
|
+
|
|
32
|
+
@abstractmethod
|
|
33
|
+
def collect(self) -> ContentT:
|
|
34
|
+
"""Collect all chunks and return the final content."""
|
|
35
|
+
...
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class BaseAsyncStream(ABC, Generic[ContentT, DeltaT]):
|
|
39
|
+
"""Base class for asynchronous streaming content."""
|
|
40
|
+
|
|
41
|
+
@abstractmethod
|
|
42
|
+
def __aiter__(self) -> AsyncIterator[DeltaT]:
|
|
43
|
+
"""Asynchronously iterate over content deltas as they arrive."""
|
|
44
|
+
...
|
|
45
|
+
|
|
46
|
+
@abstractmethod
|
|
47
|
+
async def collect(self) -> ContentT:
|
|
48
|
+
"""Asynchronously collect all chunks and return the final content."""
|
|
49
|
+
...
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class TextStream(BaseStream[Text, str]):
|
|
53
|
+
"""Synchronous text stream implementation."""
|
|
54
|
+
|
|
55
|
+
type: Literal["text_stream"] = "text_stream"
|
|
56
|
+
|
|
57
|
+
content_type: Literal["text"] = "text"
|
|
58
|
+
"""The type of content stored in this stream."""
|
|
59
|
+
|
|
60
|
+
partial_text: str
|
|
61
|
+
"""The accumulated text content as chunks are received."""
|
|
62
|
+
|
|
63
|
+
def __init__(
|
|
64
|
+
self,
|
|
65
|
+
chunk_iterator: Iterator[TextChunk],
|
|
66
|
+
) -> None:
|
|
67
|
+
"""Initialize TextStream with a start chunk and chunk iterator.
|
|
68
|
+
|
|
69
|
+
Args:
|
|
70
|
+
chunk_iterator: Iterator providing subsequent chunks.
|
|
71
|
+
"""
|
|
72
|
+
self.partial_text = ""
|
|
73
|
+
self._chunk_iterator = chunk_iterator
|
|
74
|
+
|
|
75
|
+
def __iter__(self) -> Iterator[str]:
|
|
76
|
+
"""Iterate over text deltas as they are received.
|
|
77
|
+
|
|
78
|
+
Yields:
|
|
79
|
+
str: Each delta string containing text.
|
|
80
|
+
"""
|
|
81
|
+
for chunk in self._chunk_iterator:
|
|
82
|
+
delta = chunk.delta
|
|
83
|
+
self.partial_text += delta
|
|
84
|
+
yield delta
|
|
85
|
+
|
|
86
|
+
def collect(self) -> Text:
|
|
87
|
+
"""Collect all chunks and return the final Text content.
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
Text: The complete text content after consuming all chunks.
|
|
91
|
+
"""
|
|
92
|
+
for _ in self:
|
|
93
|
+
pass
|
|
94
|
+
return Text(text=self.partial_text)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class AsyncTextStream(BaseAsyncStream[Text, str]):
|
|
98
|
+
"""Asynchronous text stream implementation."""
|
|
99
|
+
|
|
100
|
+
type: Literal["async_text_stream"] = "async_text_stream"
|
|
101
|
+
|
|
102
|
+
content_type: Literal["text"] = "text"
|
|
103
|
+
"""The type of content stored in this stream."""
|
|
104
|
+
|
|
105
|
+
partial_text: str
|
|
106
|
+
"""The accumulated text content as chunks are received."""
|
|
107
|
+
|
|
108
|
+
def __init__(
|
|
109
|
+
self,
|
|
110
|
+
chunk_iterator: AsyncIterator[TextChunk],
|
|
111
|
+
) -> None:
|
|
112
|
+
"""Initialize AsyncTextStream with a chunk iterator.
|
|
113
|
+
|
|
114
|
+
Args:
|
|
115
|
+
chunk_iterator: AsyncIterator providing subsequent chunks.
|
|
116
|
+
"""
|
|
117
|
+
self.partial_text = ""
|
|
118
|
+
self._chunk_iterator = chunk_iterator
|
|
119
|
+
|
|
120
|
+
async def __aiter__(self) -> AsyncIterator[str]:
|
|
121
|
+
"""Asynchronously iterate over text deltas as they are received.
|
|
122
|
+
|
|
123
|
+
Yields:
|
|
124
|
+
str: Each delta string containing text.
|
|
125
|
+
"""
|
|
126
|
+
async for chunk in self._chunk_iterator:
|
|
127
|
+
delta = chunk.delta
|
|
128
|
+
self.partial_text += delta
|
|
129
|
+
yield delta
|
|
130
|
+
|
|
131
|
+
async def collect(self) -> Text:
|
|
132
|
+
"""Asynchronously collect all chunks and return the final Text content.
|
|
133
|
+
|
|
134
|
+
Returns:
|
|
135
|
+
Text: The complete text content after consuming all chunks.
|
|
136
|
+
"""
|
|
137
|
+
async for _ in self:
|
|
138
|
+
pass
|
|
139
|
+
return Text(text=self.partial_text)
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
class ThoughtStream(BaseStream[Thought, str]):
|
|
143
|
+
"""Synchronous thought stream implementation."""
|
|
144
|
+
|
|
145
|
+
type: Literal["thought_stream"] = "thought_stream"
|
|
146
|
+
|
|
147
|
+
content_type: Literal["thought"] = "thought"
|
|
148
|
+
"""The type of content stored in this stream."""
|
|
149
|
+
|
|
150
|
+
partial_thought: str
|
|
151
|
+
"""The accumulated thought content as chunks are received."""
|
|
152
|
+
|
|
153
|
+
def __init__(
|
|
154
|
+
self,
|
|
155
|
+
chunk_iterator: Iterator[ThoughtChunk],
|
|
156
|
+
) -> None:
|
|
157
|
+
"""Initialize ThoughtStream with a chunk iterator.
|
|
158
|
+
|
|
159
|
+
Args:
|
|
160
|
+
chunk_iterator: Iterator providing subsequent chunks.
|
|
161
|
+
"""
|
|
162
|
+
self.partial_thought = ""
|
|
163
|
+
self._chunk_iterator = chunk_iterator
|
|
164
|
+
|
|
165
|
+
def __iter__(self) -> Iterator[str]:
|
|
166
|
+
"""Iterate over thought deltas as they are received.
|
|
167
|
+
|
|
168
|
+
Yields:
|
|
169
|
+
str: Each delta string containing thought text.
|
|
170
|
+
"""
|
|
171
|
+
for chunk in self._chunk_iterator:
|
|
172
|
+
delta = chunk.delta
|
|
173
|
+
self.partial_thought += delta
|
|
174
|
+
yield delta
|
|
175
|
+
|
|
176
|
+
def collect(self) -> Thought:
|
|
177
|
+
"""Collect all chunks and return the final Thought content.
|
|
178
|
+
|
|
179
|
+
Returns:
|
|
180
|
+
Thought: The complete thought content after consuming all chunks.
|
|
181
|
+
"""
|
|
182
|
+
for _ in self:
|
|
183
|
+
pass
|
|
184
|
+
return Thought(thought=self.partial_thought)
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
class AsyncThoughtStream(BaseAsyncStream[Thought, str]):
|
|
188
|
+
"""Asynchronous thought stream implementation."""
|
|
189
|
+
|
|
190
|
+
type: Literal["async_thought_stream"] = "async_thought_stream"
|
|
191
|
+
|
|
192
|
+
content_type: Literal["thought"] = "thought"
|
|
193
|
+
"""The type of content stored in this stream."""
|
|
194
|
+
|
|
195
|
+
partial_thought: str
|
|
196
|
+
"""The accumulated thought content as chunks are received."""
|
|
197
|
+
|
|
198
|
+
def __init__(
|
|
199
|
+
self,
|
|
200
|
+
chunk_iterator: AsyncIterator[ThoughtChunk],
|
|
201
|
+
) -> None:
|
|
202
|
+
"""Initialize AsyncThoughtStream with a chunk iterator.
|
|
203
|
+
|
|
204
|
+
Args:
|
|
205
|
+
chunk_iterator: AsyncIterator providing subsequent chunks.
|
|
206
|
+
"""
|
|
207
|
+
self.partial_thought = ""
|
|
208
|
+
self._chunk_iterator = chunk_iterator
|
|
209
|
+
|
|
210
|
+
async def __aiter__(self) -> AsyncIterator[str]:
|
|
211
|
+
"""Asynchronously iterate over thought deltas as they are received.
|
|
212
|
+
|
|
213
|
+
Yields:
|
|
214
|
+
str: Each delta string containing thought text.
|
|
215
|
+
"""
|
|
216
|
+
async for chunk in self._chunk_iterator:
|
|
217
|
+
delta = chunk.delta
|
|
218
|
+
self.partial_thought += delta
|
|
219
|
+
yield delta
|
|
220
|
+
|
|
221
|
+
async def collect(self) -> Thought:
|
|
222
|
+
"""Asynchronously collect all chunks and return the final Thought content.
|
|
223
|
+
|
|
224
|
+
Returns:
|
|
225
|
+
Thought: The complete thought content after consuming all chunks.
|
|
226
|
+
"""
|
|
227
|
+
async for _ in self:
|
|
228
|
+
pass
|
|
229
|
+
return Thought(thought=self.partial_thought)
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
class ToolCallStream(BaseStream[ToolCall, str]):
|
|
233
|
+
"""Synchronous tool call stream implementation."""
|
|
234
|
+
|
|
235
|
+
type: Literal["tool_call_stream"] = "tool_call_stream"
|
|
236
|
+
|
|
237
|
+
content_type: Literal["tool_call"] = "tool_call"
|
|
238
|
+
"""The type of content stored in this stream."""
|
|
239
|
+
|
|
240
|
+
tool_id: str
|
|
241
|
+
"""A unique identifier for this tool call."""
|
|
242
|
+
|
|
243
|
+
tool_name: str
|
|
244
|
+
"""The name of the tool being called."""
|
|
245
|
+
|
|
246
|
+
partial_args: str
|
|
247
|
+
"""The accumulated tool arguments as chunks are received."""
|
|
248
|
+
|
|
249
|
+
def __init__(
|
|
250
|
+
self,
|
|
251
|
+
tool_id: str,
|
|
252
|
+
tool_name: str,
|
|
253
|
+
chunk_iterator: Iterator[ToolCallChunk],
|
|
254
|
+
) -> None:
|
|
255
|
+
"""Initialize ToolCallStream with tool metadata and chunk iterator.
|
|
256
|
+
|
|
257
|
+
Args:
|
|
258
|
+
tool_id: A unique identifier for this tool call.
|
|
259
|
+
tool_name: The name of the tool being called.
|
|
260
|
+
chunk_iterator: Iterator providing subsequent chunks.
|
|
261
|
+
"""
|
|
262
|
+
self.tool_id = tool_id
|
|
263
|
+
self.tool_name = tool_name
|
|
264
|
+
self.partial_args = ""
|
|
265
|
+
self._chunk_iterator = chunk_iterator
|
|
266
|
+
|
|
267
|
+
def __iter__(self) -> Iterator[str]:
|
|
268
|
+
"""Iterate over tool call argument deltas as they are received.
|
|
269
|
+
|
|
270
|
+
Yields:
|
|
271
|
+
str: Each delta string containing JSON argument fragments.
|
|
272
|
+
"""
|
|
273
|
+
for chunk in self._chunk_iterator:
|
|
274
|
+
delta = chunk.delta
|
|
275
|
+
self.partial_args += delta
|
|
276
|
+
yield delta
|
|
277
|
+
|
|
278
|
+
def collect(self) -> ToolCall:
|
|
279
|
+
"""Collect all chunks and return the final ToolCall content.
|
|
280
|
+
|
|
281
|
+
Returns:
|
|
282
|
+
ToolCall: The complete tool call after consuming all chunks.
|
|
283
|
+
"""
|
|
284
|
+
for _ in self:
|
|
285
|
+
pass
|
|
286
|
+
return ToolCall(id=self.tool_id, name=self.tool_name, args=self.partial_args)
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
class AsyncToolCallStream(BaseAsyncStream[ToolCall, str]):
|
|
290
|
+
"""Asynchronous tool call stream implementation."""
|
|
291
|
+
|
|
292
|
+
type: Literal["async_tool_call_stream"] = "async_tool_call_stream"
|
|
293
|
+
|
|
294
|
+
content_type: Literal["tool_call"] = "tool_call"
|
|
295
|
+
"""The type of content stored in this stream."""
|
|
296
|
+
|
|
297
|
+
tool_id: str
|
|
298
|
+
"""A unique identifier for this tool call."""
|
|
299
|
+
|
|
300
|
+
tool_name: str
|
|
301
|
+
"""The name of the tool being called."""
|
|
302
|
+
|
|
303
|
+
partial_args: str
|
|
304
|
+
"""The accumulated tool arguments as chunks are received."""
|
|
305
|
+
|
|
306
|
+
def __init__(
|
|
307
|
+
self,
|
|
308
|
+
tool_id: str,
|
|
309
|
+
tool_name: str,
|
|
310
|
+
chunk_iterator: AsyncIterator[ToolCallChunk],
|
|
311
|
+
) -> None:
|
|
312
|
+
"""Initialize AsyncToolCallStream with tool metadata and chunk iterator.
|
|
313
|
+
|
|
314
|
+
Args:
|
|
315
|
+
tool_id: A unique identifier for this tool call.
|
|
316
|
+
tool_name: The name of the tool being called.
|
|
317
|
+
chunk_iterator: AsyncIterator providing subsequent chunks.
|
|
318
|
+
"""
|
|
319
|
+
self.tool_id = tool_id
|
|
320
|
+
self.tool_name = tool_name
|
|
321
|
+
self.partial_args = ""
|
|
322
|
+
self._chunk_iterator = chunk_iterator
|
|
323
|
+
|
|
324
|
+
async def __aiter__(self) -> AsyncIterator[str]:
|
|
325
|
+
"""Asynchronously iterate over tool call argument deltas as they are received.
|
|
326
|
+
|
|
327
|
+
Yields:
|
|
328
|
+
str: Each delta string containing JSON argument fragments.
|
|
329
|
+
"""
|
|
330
|
+
async for chunk in self._chunk_iterator:
|
|
331
|
+
delta = chunk.delta
|
|
332
|
+
self.partial_args += delta
|
|
333
|
+
yield delta
|
|
334
|
+
|
|
335
|
+
async def collect(self) -> ToolCall:
|
|
336
|
+
"""Asynchronously collect all chunks and return the final ToolCall content.
|
|
337
|
+
|
|
338
|
+
Returns:
|
|
339
|
+
ToolCall: The complete tool call after consuming all chunks.
|
|
340
|
+
"""
|
|
341
|
+
async for _ in self:
|
|
342
|
+
pass
|
|
343
|
+
return ToolCall(id=self.tool_id, name=self.tool_name, args=self.partial_args)
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
Stream: TypeAlias = TextStream | ToolCallStream | ThoughtStream
|
|
347
|
+
"""A synchronous assistant content stream."""
|
|
348
|
+
|
|
349
|
+
AsyncStream: TypeAlias = AsyncTextStream | AsyncToolCallStream | AsyncThoughtStream
|
|
350
|
+
"""An asynchronous assistant content stream."""
|
|
351
|
+
|
|
352
|
+
__all__ = [
|
|
353
|
+
"AsyncStream",
|
|
354
|
+
"AsyncTextStream",
|
|
355
|
+
"AsyncThoughtStream",
|
|
356
|
+
"AsyncToolCallStream",
|
|
357
|
+
"BaseAsyncStream",
|
|
358
|
+
"BaseStream",
|
|
359
|
+
"Stream",
|
|
360
|
+
"TextStream",
|
|
361
|
+
"ThoughtStream",
|
|
362
|
+
"ToolCallStream",
|
|
363
|
+
]
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"""The Tools module for LLMs."""
|
|
2
|
+
|
|
3
|
+
from . import protocols
|
|
4
|
+
from .decorator import ToolDecorator, tool
|
|
5
|
+
from .tool_schema import (
|
|
6
|
+
FORMAT_TOOL_NAME,
|
|
7
|
+
ToolParameterSchema,
|
|
8
|
+
ToolSchema,
|
|
9
|
+
ToolSchemaT,
|
|
10
|
+
)
|
|
11
|
+
from .toolkit import (
|
|
12
|
+
AsyncContextToolkit,
|
|
13
|
+
AsyncToolkit,
|
|
14
|
+
BaseToolkit,
|
|
15
|
+
ContextToolkit,
|
|
16
|
+
Toolkit,
|
|
17
|
+
ToolkitT,
|
|
18
|
+
)
|
|
19
|
+
from .tools import AsyncContextTool, AsyncTool, ContextTool, Tool, ToolT
|
|
20
|
+
|
|
21
|
+
__all__ = [
|
|
22
|
+
"FORMAT_TOOL_NAME",
|
|
23
|
+
"AsyncContextTool",
|
|
24
|
+
"AsyncContextToolkit",
|
|
25
|
+
"AsyncTool",
|
|
26
|
+
"AsyncToolkit",
|
|
27
|
+
"BaseToolkit",
|
|
28
|
+
"ContextTool",
|
|
29
|
+
"ContextToolkit",
|
|
30
|
+
"Tool",
|
|
31
|
+
"ToolDecorator",
|
|
32
|
+
"ToolParameterSchema",
|
|
33
|
+
"ToolSchema",
|
|
34
|
+
"ToolSchemaT",
|
|
35
|
+
"ToolT",
|
|
36
|
+
"Toolkit",
|
|
37
|
+
"ToolkitT",
|
|
38
|
+
"protocols",
|
|
39
|
+
"tool",
|
|
40
|
+
]
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""Utilities for tool type checking and validation."""
|
|
2
|
+
|
|
3
|
+
import inspect
|
|
4
|
+
from typing_extensions import TypeIs
|
|
5
|
+
|
|
6
|
+
from ..context import DepsT, _utils as _context_utils
|
|
7
|
+
from ..types import JsonableCovariantT, P
|
|
8
|
+
from .protocols import AsyncContextToolFn, AsyncToolFn, ContextToolFn, ToolFn
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def is_context_tool_fn(
|
|
12
|
+
fn: ToolFn | AsyncToolFn | ContextToolFn | AsyncContextToolFn,
|
|
13
|
+
) -> TypeIs[
|
|
14
|
+
ContextToolFn[DepsT, P, JsonableCovariantT]
|
|
15
|
+
| AsyncContextToolFn[DepsT, P, JsonableCovariantT]
|
|
16
|
+
]:
|
|
17
|
+
"""Type guard to check if a function is a context tool function."""
|
|
18
|
+
return _context_utils.first_param_is_context(fn)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def is_async_tool_fn(
|
|
22
|
+
fn: ToolFn | AsyncToolFn | ContextToolFn | AsyncContextToolFn,
|
|
23
|
+
) -> TypeIs[AsyncToolFn | AsyncContextToolFn]:
|
|
24
|
+
"""Type guard to check if a function is an async tool function."""
|
|
25
|
+
return inspect.iscoroutinefunction(fn)
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"""The `llm.tool` decorator for turning functions into tools."""
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import overload
|
|
5
|
+
|
|
6
|
+
from ..context import DepsT
|
|
7
|
+
from ..types import JsonableCovariantT, P
|
|
8
|
+
from . import _utils as _tool_utils
|
|
9
|
+
from .protocols import AsyncContextToolFn, AsyncToolFn, ContextToolFn, ToolFn
|
|
10
|
+
from .tools import AsyncContextTool, AsyncTool, ContextTool, Tool
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass(kw_only=True)
|
|
14
|
+
class ToolDecorator:
|
|
15
|
+
"""Protocol for the tool decorator."""
|
|
16
|
+
|
|
17
|
+
strict: bool
|
|
18
|
+
"""Whether to use strict tool calling, if supported by the provider."""
|
|
19
|
+
|
|
20
|
+
@overload
|
|
21
|
+
def __call__( # pyright:ignore[reportOverlappingOverload]
|
|
22
|
+
self, fn: ContextToolFn[DepsT, P, JsonableCovariantT]
|
|
23
|
+
) -> ContextTool[DepsT, P, JsonableCovariantT]:
|
|
24
|
+
"""Call the decorator with a context function."""
|
|
25
|
+
...
|
|
26
|
+
|
|
27
|
+
@overload
|
|
28
|
+
def __call__( # pyright:ignore[reportOverlappingOverload]
|
|
29
|
+
self, fn: AsyncContextToolFn[DepsT, P, JsonableCovariantT]
|
|
30
|
+
) -> AsyncContextTool[DepsT, P, JsonableCovariantT]:
|
|
31
|
+
"""Call the decorator with an async context function."""
|
|
32
|
+
...
|
|
33
|
+
|
|
34
|
+
@overload
|
|
35
|
+
def __call__(
|
|
36
|
+
self, fn: ToolFn[P, JsonableCovariantT]
|
|
37
|
+
) -> Tool[P, JsonableCovariantT]:
|
|
38
|
+
"""Call the decorator with a sync function."""
|
|
39
|
+
...
|
|
40
|
+
|
|
41
|
+
@overload
|
|
42
|
+
def __call__(
|
|
43
|
+
self, fn: AsyncToolFn[P, JsonableCovariantT]
|
|
44
|
+
) -> AsyncTool[P, JsonableCovariantT]:
|
|
45
|
+
"""Call the decorator with an async function."""
|
|
46
|
+
...
|
|
47
|
+
|
|
48
|
+
def __call__(
|
|
49
|
+
self,
|
|
50
|
+
fn: ContextToolFn[DepsT, P, JsonableCovariantT]
|
|
51
|
+
| AsyncContextToolFn[DepsT, P, JsonableCovariantT]
|
|
52
|
+
| ToolFn[P, JsonableCovariantT]
|
|
53
|
+
| AsyncToolFn[P, JsonableCovariantT],
|
|
54
|
+
) -> (
|
|
55
|
+
ContextTool[DepsT, P, JsonableCovariantT]
|
|
56
|
+
| AsyncContextTool[DepsT, P, JsonableCovariantT]
|
|
57
|
+
| Tool[P, JsonableCovariantT]
|
|
58
|
+
| AsyncTool[P, JsonableCovariantT]
|
|
59
|
+
):
|
|
60
|
+
"""Call the decorator with a function."""
|
|
61
|
+
is_context = _tool_utils.is_context_tool_fn(fn)
|
|
62
|
+
is_async = _tool_utils.is_async_tool_fn(fn)
|
|
63
|
+
|
|
64
|
+
if is_context and is_async:
|
|
65
|
+
return AsyncContextTool[DepsT, P, JsonableCovariantT](
|
|
66
|
+
fn, strict=self.strict
|
|
67
|
+
)
|
|
68
|
+
elif is_context:
|
|
69
|
+
return ContextTool[DepsT, P, JsonableCovariantT](fn, strict=self.strict)
|
|
70
|
+
elif is_async:
|
|
71
|
+
return AsyncTool[P, JsonableCovariantT](fn, strict=self.strict)
|
|
72
|
+
else:
|
|
73
|
+
return Tool[P, JsonableCovariantT](fn, strict=self.strict)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
@overload
|
|
77
|
+
def tool( # pyright:ignore[reportOverlappingOverload]
|
|
78
|
+
__fn: AsyncContextToolFn[DepsT, P, JsonableCovariantT],
|
|
79
|
+
) -> AsyncContextTool[DepsT, P, JsonableCovariantT]:
|
|
80
|
+
"""Overload for async context tool functions."""
|
|
81
|
+
...
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
@overload
|
|
85
|
+
def tool( # pyright:ignore[reportOverlappingOverload]
|
|
86
|
+
__fn: ContextToolFn[DepsT, P, JsonableCovariantT],
|
|
87
|
+
) -> ContextTool[DepsT, P, JsonableCovariantT]:
|
|
88
|
+
"""Overload for context tool functions."""
|
|
89
|
+
...
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
@overload
|
|
93
|
+
def tool(__fn: AsyncToolFn[P, JsonableCovariantT]) -> AsyncTool[P, JsonableCovariantT]:
|
|
94
|
+
"""Overload for regular async tool functions."""
|
|
95
|
+
...
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
@overload
|
|
99
|
+
def tool(__fn: ToolFn[P, JsonableCovariantT]) -> Tool[P, JsonableCovariantT]:
|
|
100
|
+
"""Overload for regular sync tool functions."""
|
|
101
|
+
...
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
@overload
|
|
105
|
+
def tool(*, strict: bool = False) -> ToolDecorator:
|
|
106
|
+
"""Overload for setting non-default arguments."""
|
|
107
|
+
...
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def tool(
|
|
111
|
+
__fn: ContextToolFn[DepsT, P, JsonableCovariantT]
|
|
112
|
+
| AsyncContextToolFn[DepsT, P, JsonableCovariantT]
|
|
113
|
+
| ToolFn[P, JsonableCovariantT]
|
|
114
|
+
| AsyncToolFn[P, JsonableCovariantT]
|
|
115
|
+
| None = None,
|
|
116
|
+
*,
|
|
117
|
+
strict: bool = False,
|
|
118
|
+
) -> (
|
|
119
|
+
ContextTool[DepsT, P, JsonableCovariantT]
|
|
120
|
+
| AsyncContextTool[DepsT, P, JsonableCovariantT]
|
|
121
|
+
| Tool[P, JsonableCovariantT]
|
|
122
|
+
| AsyncTool[P, JsonableCovariantT]
|
|
123
|
+
| ToolDecorator
|
|
124
|
+
):
|
|
125
|
+
'''Decorator that turns a function into a tool definition.
|
|
126
|
+
|
|
127
|
+
This decorator creates a `Tool` or `ContextTool` that can be used with `llm.call`.
|
|
128
|
+
The function's name, docstring, and type hints are used to generate the
|
|
129
|
+
tool's metadata.
|
|
130
|
+
|
|
131
|
+
If the first parameter is named 'ctx' or typed as `llm.Context[T]`, it creates
|
|
132
|
+
a ContextTool. Otherwise, it creates a regular Tool.
|
|
133
|
+
|
|
134
|
+
Args:
|
|
135
|
+
strict: Whether the tool should use strict mode when supported by the model.
|
|
136
|
+
|
|
137
|
+
Returns:
|
|
138
|
+
A decorator function that converts the function into a Tool or ContextTool.
|
|
139
|
+
|
|
140
|
+
Examples:
|
|
141
|
+
|
|
142
|
+
Regular tool:
|
|
143
|
+
```python
|
|
144
|
+
from mirascope import llm
|
|
145
|
+
|
|
146
|
+
@llm.tool
|
|
147
|
+
def available_books() -> list[str]:
|
|
148
|
+
"""Returns the list of available books."""
|
|
149
|
+
return ["The Name of the Wind"]
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Context tool:
|
|
153
|
+
```python
|
|
154
|
+
from dataclasses import dataclass
|
|
155
|
+
|
|
156
|
+
from mirascope import llm
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
@dataclass
|
|
160
|
+
class Library:
|
|
161
|
+
books: list[str]
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
library = Library(books=["Mistborn", "Gödel, Escher, Bach", "Dune"])
|
|
165
|
+
|
|
166
|
+
@llm.tool
|
|
167
|
+
def available_books(ctx: llm.Context[Library]) -> list[str]:
|
|
168
|
+
"""Returns the list of available books."""
|
|
169
|
+
return ctx.deps.books
|
|
170
|
+
```
|
|
171
|
+
'''
|
|
172
|
+
decorator = ToolDecorator(strict=strict)
|
|
173
|
+
if __fn is None:
|
|
174
|
+
return decorator
|
|
175
|
+
return decorator(__fn)
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
from typing import Any, Protocol
|
|
2
|
+
|
|
3
|
+
from ..context import Context, DepsT
|
|
4
|
+
from ..types import JsonableCovariantT, P
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ToolFn(Protocol[P, JsonableCovariantT]):
|
|
8
|
+
"""Protocol for the tool function."""
|
|
9
|
+
|
|
10
|
+
__name__: str
|
|
11
|
+
"""The name of the tool."""
|
|
12
|
+
|
|
13
|
+
def __call__(self, *args: P.args, **kwargs: P.kwargs) -> JsonableCovariantT:
|
|
14
|
+
"""Call the function with the given arguments."""
|
|
15
|
+
raise NotImplementedError()
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class AsyncToolFn(Protocol[P, JsonableCovariantT]):
|
|
19
|
+
"""Protocol for the async tool function."""
|
|
20
|
+
|
|
21
|
+
__name__: str
|
|
22
|
+
"""The name of the tool."""
|
|
23
|
+
|
|
24
|
+
async def __call__(self, *args: P.args, **kwargs: P.kwargs) -> JsonableCovariantT:
|
|
25
|
+
"""Call the function with the given arguments."""
|
|
26
|
+
raise NotImplementedError()
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class ContextToolFn(Protocol[DepsT, P, JsonableCovariantT]):
|
|
30
|
+
"""Protocol for the context tool function."""
|
|
31
|
+
|
|
32
|
+
__name__: str
|
|
33
|
+
"""The name of the tool."""
|
|
34
|
+
|
|
35
|
+
def __call__(
|
|
36
|
+
self, ctx: Context[DepsT], *args: P.args, **kwargs: P.kwargs
|
|
37
|
+
) -> JsonableCovariantT:
|
|
38
|
+
"""Call the function with the given arguments."""
|
|
39
|
+
raise NotImplementedError()
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class AsyncContextToolFn(Protocol[DepsT, P, JsonableCovariantT]):
|
|
43
|
+
"""Protocol for the async context tool function."""
|
|
44
|
+
|
|
45
|
+
__name__: str
|
|
46
|
+
"""The name of the tool."""
|
|
47
|
+
|
|
48
|
+
async def __call__(
|
|
49
|
+
self, ctx: Context[DepsT], *args: P.args, **kwargs: P.kwargs
|
|
50
|
+
) -> JsonableCovariantT:
|
|
51
|
+
"""Call the function with the given arguments."""
|
|
52
|
+
raise NotImplementedError()
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class _KwargsCallable(Protocol[JsonableCovariantT]):
|
|
56
|
+
"""Protocol for functions that can be called with `Any`-typed kwargs.
|
|
57
|
+
|
|
58
|
+
Used internally to type-cast tool functions for compatibility with
|
|
59
|
+
json.loads() output when executing tool calls.
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
def __call__(self, **kwargs: dict[str, Any]) -> JsonableCovariantT: ...
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class _AsyncKwargsCallable(Protocol[JsonableCovariantT]):
|
|
66
|
+
"""Protocol for async functions that can be called with `Any`-typed kwargs.
|
|
67
|
+
|
|
68
|
+
Used internally to type-cast async tool functions for compatibility with
|
|
69
|
+
json.loads() output when executing tool calls.
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
async def __call__(self, **kwargs: dict[str, Any]) -> JsonableCovariantT: ...
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class _ContextKwargsCallable(Protocol[DepsT, JsonableCovariantT]):
|
|
76
|
+
"""Protocol for context functions that can be called with `Any`-typed kwargs.
|
|
77
|
+
|
|
78
|
+
Used internally to type-cast context tool functions for compatibility with
|
|
79
|
+
json.loads() output when executing tool calls.
|
|
80
|
+
"""
|
|
81
|
+
|
|
82
|
+
def __call__(
|
|
83
|
+
self, ctx: Context[DepsT], **kwargs: dict[str, Any]
|
|
84
|
+
) -> JsonableCovariantT: ...
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
class _AsyncJsonKwargsCallable(Protocol[DepsT, JsonableCovariantT]):
|
|
88
|
+
"""Protocol for async context functions that can be called with `Any`-typed kwargs.
|
|
89
|
+
|
|
90
|
+
Used internally to type-cast async context tool functions for compatibility with
|
|
91
|
+
json.loads() output when executing tool calls.
|
|
92
|
+
"""
|
|
93
|
+
|
|
94
|
+
async def __call__(
|
|
95
|
+
self, ctx: Context[DepsT], **kwargs: dict[str, Any]
|
|
96
|
+
) -> JsonableCovariantT: ...
|