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,113 +0,0 @@
|
|
|
1
|
-
"""Utilities for handling a stream of messages."""
|
|
2
|
-
|
|
3
|
-
from collections.abc import AsyncGenerator, Generator
|
|
4
|
-
|
|
5
|
-
import jiter
|
|
6
|
-
from anthropic.types import MessageStreamEvent, ToolUseBlock
|
|
7
|
-
|
|
8
|
-
from ..call_response_chunk import AnthropicCallResponseChunk
|
|
9
|
-
from ..tool import AnthropicTool
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
def _handle_chunk(
|
|
13
|
-
buffer: str,
|
|
14
|
-
chunk: MessageStreamEvent,
|
|
15
|
-
current_tool_call: ToolUseBlock,
|
|
16
|
-
current_tool_type: type[AnthropicTool] | None,
|
|
17
|
-
tool_types: list[type[AnthropicTool]] | None,
|
|
18
|
-
partial_tools: bool = False,
|
|
19
|
-
) -> tuple[
|
|
20
|
-
str,
|
|
21
|
-
AnthropicTool | None,
|
|
22
|
-
ToolUseBlock,
|
|
23
|
-
type[AnthropicTool] | None,
|
|
24
|
-
]:
|
|
25
|
-
"""Handles a chunk of the stream."""
|
|
26
|
-
if not tool_types:
|
|
27
|
-
return buffer, None, current_tool_call, current_tool_type
|
|
28
|
-
|
|
29
|
-
if chunk.type == "content_block_stop" and current_tool_type and buffer:
|
|
30
|
-
current_tool_call.input = jiter.from_json(buffer.encode())
|
|
31
|
-
return (
|
|
32
|
-
"",
|
|
33
|
-
current_tool_type.from_tool_call(current_tool_call),
|
|
34
|
-
ToolUseBlock(id="", input={}, name="", type="tool_use"),
|
|
35
|
-
None,
|
|
36
|
-
)
|
|
37
|
-
|
|
38
|
-
if chunk.type == "content_block_start" and isinstance(
|
|
39
|
-
chunk.content_block, ToolUseBlock
|
|
40
|
-
):
|
|
41
|
-
content_block = chunk.content_block
|
|
42
|
-
current_tool_type = None
|
|
43
|
-
for tool_type in tool_types:
|
|
44
|
-
if tool_type._name() == content_block.name:
|
|
45
|
-
current_tool_type = tool_type
|
|
46
|
-
break
|
|
47
|
-
if current_tool_type is None:
|
|
48
|
-
raise RuntimeError(
|
|
49
|
-
f"Unknown tool type in stream: {content_block.name}."
|
|
50
|
-
) # pragma: no cover
|
|
51
|
-
return (
|
|
52
|
-
"",
|
|
53
|
-
None,
|
|
54
|
-
ToolUseBlock(
|
|
55
|
-
id=content_block.id, input={}, name=content_block.name, type="tool_use"
|
|
56
|
-
),
|
|
57
|
-
current_tool_type,
|
|
58
|
-
)
|
|
59
|
-
|
|
60
|
-
if chunk.type == "content_block_delta" and chunk.delta.type == "input_json_delta":
|
|
61
|
-
buffer += chunk.delta.partial_json
|
|
62
|
-
|
|
63
|
-
# Return partial tool if enabled
|
|
64
|
-
if partial_tools and current_tool_type:
|
|
65
|
-
partial_tool_call = ToolUseBlock(
|
|
66
|
-
id=current_tool_call.id,
|
|
67
|
-
input=buffer,
|
|
68
|
-
name=current_tool_call.name,
|
|
69
|
-
type="tool_use",
|
|
70
|
-
)
|
|
71
|
-
partial_tool = current_tool_type.from_tool_call(partial_tool_call, True)
|
|
72
|
-
partial_tool.delta = chunk.delta.partial_json
|
|
73
|
-
return buffer, partial_tool, current_tool_call, current_tool_type
|
|
74
|
-
return buffer, None, current_tool_call, current_tool_type
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
def handle_stream(
|
|
78
|
-
stream: Generator[MessageStreamEvent, None, None],
|
|
79
|
-
tool_types: list[type[AnthropicTool]] | None,
|
|
80
|
-
partial_tools: bool = False,
|
|
81
|
-
) -> Generator[tuple[AnthropicCallResponseChunk, AnthropicTool | None], None, None]:
|
|
82
|
-
"""Iterator over the stream and constructs tools as they are streamed."""
|
|
83
|
-
current_tool_call = ToolUseBlock(id="", input={}, name="", type="tool_use")
|
|
84
|
-
current_tool_type, buffer = None, ""
|
|
85
|
-
for chunk in stream:
|
|
86
|
-
buffer, tool, current_tool_call, current_tool_type = _handle_chunk(
|
|
87
|
-
buffer,
|
|
88
|
-
chunk,
|
|
89
|
-
current_tool_call,
|
|
90
|
-
current_tool_type,
|
|
91
|
-
tool_types,
|
|
92
|
-
partial_tools,
|
|
93
|
-
)
|
|
94
|
-
yield AnthropicCallResponseChunk(chunk=chunk), tool
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
async def handle_stream_async(
|
|
98
|
-
stream: AsyncGenerator[MessageStreamEvent, None],
|
|
99
|
-
tool_types: list[type[AnthropicTool]] | None,
|
|
100
|
-
partial_tools: bool = False,
|
|
101
|
-
) -> AsyncGenerator[tuple[AnthropicCallResponseChunk, AnthropicTool | None], None]:
|
|
102
|
-
current_tool_call = ToolUseBlock(id="", input={}, name="", type="tool_use")
|
|
103
|
-
current_tool_type, buffer = None, ""
|
|
104
|
-
async for chunk in stream:
|
|
105
|
-
buffer, tool, current_tool_call, current_tool_type = _handle_chunk(
|
|
106
|
-
buffer,
|
|
107
|
-
chunk,
|
|
108
|
-
current_tool_call,
|
|
109
|
-
current_tool_type,
|
|
110
|
-
tool_types,
|
|
111
|
-
partial_tools,
|
|
112
|
-
)
|
|
113
|
-
yield AnthropicCallResponseChunk(chunk=chunk), tool
|
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
import base64
|
|
2
|
-
import logging
|
|
3
|
-
from os import PathLike
|
|
4
|
-
from typing import cast
|
|
5
|
-
|
|
6
|
-
from anthropic.types import MessageParam
|
|
7
|
-
|
|
8
|
-
from mirascope.core import BaseMessageParam
|
|
9
|
-
from mirascope.core.anthropic._utils import convert_message_params
|
|
10
|
-
from mirascope.core.base import (
|
|
11
|
-
ImagePart,
|
|
12
|
-
ImageURLPart,
|
|
13
|
-
TextPart,
|
|
14
|
-
ToolCallPart,
|
|
15
|
-
ToolResultPart,
|
|
16
|
-
)
|
|
17
|
-
from mirascope.core.base._utils._base_message_param_converter import (
|
|
18
|
-
BaseMessageParamConverter,
|
|
19
|
-
)
|
|
20
|
-
|
|
21
|
-
logger = logging.getLogger(__name__)
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
class AnthropicMessageParamConverter(BaseMessageParamConverter):
|
|
25
|
-
"""Converts between Anthropic `MessageParam` objects and Mirascope `BaseMessageParam`."""
|
|
26
|
-
|
|
27
|
-
@staticmethod
|
|
28
|
-
def to_provider(message_params: list[BaseMessageParam]) -> list[MessageParam]:
|
|
29
|
-
"""
|
|
30
|
-
Convert from Mirascope `BaseMessageParam` to Anthropic's `MessageParam`.
|
|
31
|
-
"""
|
|
32
|
-
return convert_message_params(
|
|
33
|
-
cast(list[BaseMessageParam | MessageParam], message_params)
|
|
34
|
-
)
|
|
35
|
-
|
|
36
|
-
@staticmethod
|
|
37
|
-
def from_provider(message_params: list[MessageParam]) -> list[BaseMessageParam]:
|
|
38
|
-
"""
|
|
39
|
-
Convert from Anthropic's `MessageParam` back to Mirascope `BaseMessageParam`.
|
|
40
|
-
"""
|
|
41
|
-
converted: list[BaseMessageParam] = []
|
|
42
|
-
for message_param in message_params:
|
|
43
|
-
content = message_param["content"]
|
|
44
|
-
if isinstance(content, str):
|
|
45
|
-
converted.append(
|
|
46
|
-
BaseMessageParam(role=message_param["role"], content=content)
|
|
47
|
-
)
|
|
48
|
-
continue
|
|
49
|
-
converted_content = []
|
|
50
|
-
|
|
51
|
-
for block in content:
|
|
52
|
-
if not isinstance(block, dict):
|
|
53
|
-
continue
|
|
54
|
-
|
|
55
|
-
if block["type"] == "text":
|
|
56
|
-
text = block.get("text")
|
|
57
|
-
if not isinstance(text, str):
|
|
58
|
-
raise ValueError(
|
|
59
|
-
"TextBlockParam must have a string 'text' field."
|
|
60
|
-
)
|
|
61
|
-
converted_content.append(TextPart(type="text", text=text))
|
|
62
|
-
|
|
63
|
-
elif block["type"] == "image":
|
|
64
|
-
source = block.get("source")
|
|
65
|
-
source_type = source.get("type") if source else None
|
|
66
|
-
if not source or source_type not in ["base64", "url"]:
|
|
67
|
-
raise ValueError(
|
|
68
|
-
"ImageBlockParam must have a 'source' with type='base64' or type='url'."
|
|
69
|
-
)
|
|
70
|
-
if source_type == "url":
|
|
71
|
-
url = source.get("url")
|
|
72
|
-
if not url:
|
|
73
|
-
raise ValueError(
|
|
74
|
-
"ImageBlockParam source with type='url' must have a 'url'."
|
|
75
|
-
)
|
|
76
|
-
converted_content.append(
|
|
77
|
-
ImageURLPart(type="image_url", url=url, detail=None)
|
|
78
|
-
)
|
|
79
|
-
else:
|
|
80
|
-
image_data = source.get("data")
|
|
81
|
-
media_type = source.get("media_type")
|
|
82
|
-
if not image_data or not media_type:
|
|
83
|
-
raise ValueError(
|
|
84
|
-
"ImageBlockParam source with type='base64' must have 'data' and 'media_type'."
|
|
85
|
-
)
|
|
86
|
-
if media_type not in [
|
|
87
|
-
"image/jpeg",
|
|
88
|
-
"image/png",
|
|
89
|
-
"image/gif",
|
|
90
|
-
"image/webp",
|
|
91
|
-
]:
|
|
92
|
-
raise ValueError(
|
|
93
|
-
f"Unsupported image media type: {media_type}. "
|
|
94
|
-
"BaseMessageParam currently only supports JPEG, PNG, GIF, and WebP images."
|
|
95
|
-
)
|
|
96
|
-
if isinstance(image_data, str):
|
|
97
|
-
decoded_image_data = base64.b64decode(image_data)
|
|
98
|
-
elif isinstance(image_data, PathLike):
|
|
99
|
-
with open(image_data, "rb") as image_data:
|
|
100
|
-
decoded_image_data = image_data.read()
|
|
101
|
-
else:
|
|
102
|
-
decoded_image_data = image_data.read()
|
|
103
|
-
converted_content.append(
|
|
104
|
-
ImagePart(
|
|
105
|
-
type="image",
|
|
106
|
-
media_type=media_type,
|
|
107
|
-
image=decoded_image_data,
|
|
108
|
-
detail=None,
|
|
109
|
-
)
|
|
110
|
-
)
|
|
111
|
-
|
|
112
|
-
elif block["type"] == "tool_use":
|
|
113
|
-
converted_content.append(
|
|
114
|
-
ToolCallPart(
|
|
115
|
-
type="tool_call",
|
|
116
|
-
args=cast(dict, block["input"]),
|
|
117
|
-
id=block["id"],
|
|
118
|
-
name=block["name"],
|
|
119
|
-
)
|
|
120
|
-
)
|
|
121
|
-
elif block["type"] == "tool_result":
|
|
122
|
-
converted_content.append(
|
|
123
|
-
ToolResultPart(
|
|
124
|
-
type="tool_result",
|
|
125
|
-
content=block["content"] # pyright: ignore [reportTypedDictNotRequiredAccess]
|
|
126
|
-
if isinstance(block["content"], str) # pyright: ignore [reportTypedDictNotRequiredAccess]
|
|
127
|
-
else list(block["content"])[0]["text"], # pyright: ignore [reportTypedDictNotRequiredAccess, reportGeneralTypeIssues]
|
|
128
|
-
id=block["tool_use_id"],
|
|
129
|
-
is_error=block.get("is_error", False),
|
|
130
|
-
)
|
|
131
|
-
)
|
|
132
|
-
elif block["type"] in [
|
|
133
|
-
"thinking",
|
|
134
|
-
"redacted_thinking",
|
|
135
|
-
]: # pragma: no cover
|
|
136
|
-
logger.warning(
|
|
137
|
-
"Dropping thinking content blocks as they are not supported at "
|
|
138
|
-
"the provider agnostic level in v1. For native thinking support "
|
|
139
|
-
"check out [v2](https://mirascope.com/docs/mirascope/v2)"
|
|
140
|
-
)
|
|
141
|
-
else:
|
|
142
|
-
# Any other block type is not supported
|
|
143
|
-
raise ValueError(
|
|
144
|
-
f"Unsupported block type '{block['type']}'. "
|
|
145
|
-
"BaseMessageParam currently only supports text and image parts."
|
|
146
|
-
)
|
|
147
|
-
if converted_content:
|
|
148
|
-
converted.append(
|
|
149
|
-
BaseMessageParam(
|
|
150
|
-
role=message_param["role"], content=converted_content
|
|
151
|
-
)
|
|
152
|
-
)
|
|
153
|
-
|
|
154
|
-
return converted
|
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
"""This module contains the setup_call function for the Anthropic API."""
|
|
2
|
-
|
|
3
|
-
import inspect
|
|
4
|
-
from collections.abc import Awaitable, Callable
|
|
5
|
-
from typing import Any, cast, overload
|
|
6
|
-
|
|
7
|
-
from anthropic import (
|
|
8
|
-
Anthropic,
|
|
9
|
-
AnthropicBedrock,
|
|
10
|
-
AnthropicVertex,
|
|
11
|
-
AsyncAnthropic,
|
|
12
|
-
AsyncAnthropicBedrock,
|
|
13
|
-
AsyncAnthropicVertex,
|
|
14
|
-
)
|
|
15
|
-
from anthropic.types import Message, MessageParam, MessageStreamEvent
|
|
16
|
-
from pydantic import BaseModel
|
|
17
|
-
|
|
18
|
-
from ...base import BaseMessageParam, BaseTool, _utils
|
|
19
|
-
from ...base._utils import AsyncCreateFn, CreateFn
|
|
20
|
-
from ...base.stream_config import StreamConfig
|
|
21
|
-
from .._call_kwargs import AnthropicCallKwargs
|
|
22
|
-
from .._thinking import HAS_THINKING_SUPPORT
|
|
23
|
-
from ..call_params import AnthropicCallParams
|
|
24
|
-
from ..dynamic_config import AnthropicDynamicConfig, AsyncAnthropicDynamicConfig
|
|
25
|
-
from ..tool import AnthropicTool
|
|
26
|
-
from ._convert_common_call_params import convert_common_call_params
|
|
27
|
-
from ._convert_message_params import convert_message_params
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
@overload
|
|
31
|
-
def setup_call(
|
|
32
|
-
*,
|
|
33
|
-
model: str,
|
|
34
|
-
client: AsyncAnthropic | AsyncAnthropicBedrock | AsyncAnthropicVertex | None,
|
|
35
|
-
fn: Callable[..., Awaitable[AsyncAnthropicDynamicConfig]],
|
|
36
|
-
fn_args: dict[str, Any],
|
|
37
|
-
dynamic_config: AsyncAnthropicDynamicConfig,
|
|
38
|
-
tools: list[type[BaseTool] | Callable] | None,
|
|
39
|
-
json_mode: bool,
|
|
40
|
-
call_params: AnthropicCallParams,
|
|
41
|
-
response_model: type[BaseModel] | None,
|
|
42
|
-
stream: bool | StreamConfig,
|
|
43
|
-
) -> tuple[
|
|
44
|
-
AsyncCreateFn[Message, MessageStreamEvent],
|
|
45
|
-
str | None,
|
|
46
|
-
list[MessageParam],
|
|
47
|
-
list[type[AnthropicTool]] | None,
|
|
48
|
-
AnthropicCallKwargs,
|
|
49
|
-
]: ...
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
@overload
|
|
53
|
-
def setup_call(
|
|
54
|
-
*,
|
|
55
|
-
model: str,
|
|
56
|
-
client: Anthropic | AnthropicBedrock | AnthropicVertex | None,
|
|
57
|
-
fn: Callable[..., AnthropicDynamicConfig],
|
|
58
|
-
fn_args: dict[str, Any],
|
|
59
|
-
dynamic_config: AnthropicDynamicConfig,
|
|
60
|
-
tools: list[type[BaseTool] | Callable] | None,
|
|
61
|
-
json_mode: bool,
|
|
62
|
-
call_params: AnthropicCallParams,
|
|
63
|
-
response_model: type[BaseModel] | None,
|
|
64
|
-
stream: bool | StreamConfig,
|
|
65
|
-
) -> tuple[
|
|
66
|
-
CreateFn[Message, MessageStreamEvent],
|
|
67
|
-
str | None,
|
|
68
|
-
list[MessageParam],
|
|
69
|
-
list[type[AnthropicTool]] | None,
|
|
70
|
-
AnthropicCallKwargs,
|
|
71
|
-
]: ...
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
def setup_call(
|
|
75
|
-
*,
|
|
76
|
-
model: str,
|
|
77
|
-
client: Anthropic
|
|
78
|
-
| AsyncAnthropic
|
|
79
|
-
| AnthropicBedrock
|
|
80
|
-
| AsyncAnthropicBedrock
|
|
81
|
-
| AnthropicVertex
|
|
82
|
-
| AsyncAnthropicVertex
|
|
83
|
-
| None,
|
|
84
|
-
fn: Callable[..., AnthropicDynamicConfig | Awaitable[AsyncAnthropicDynamicConfig]],
|
|
85
|
-
fn_args: dict[str, Any],
|
|
86
|
-
dynamic_config: AsyncAnthropicDynamicConfig | AnthropicDynamicConfig,
|
|
87
|
-
tools: list[type[BaseTool] | Callable] | None,
|
|
88
|
-
json_mode: bool,
|
|
89
|
-
call_params: AnthropicCallParams,
|
|
90
|
-
response_model: type[BaseModel] | None,
|
|
91
|
-
stream: bool | StreamConfig,
|
|
92
|
-
) -> tuple[
|
|
93
|
-
Callable[..., Message | Awaitable[Message]],
|
|
94
|
-
str | None,
|
|
95
|
-
list[MessageParam],
|
|
96
|
-
list[type[AnthropicTool]] | None,
|
|
97
|
-
AnthropicCallKwargs,
|
|
98
|
-
]:
|
|
99
|
-
thinking_enabled = call_params.get("thinking") is not None
|
|
100
|
-
|
|
101
|
-
# Validate thinking parameter before processing
|
|
102
|
-
if thinking_enabled and not HAS_THINKING_SUPPORT:
|
|
103
|
-
raise ValueError( # pragma: no cover
|
|
104
|
-
"Thinking parameter requires anthropic>=0.47.0. "
|
|
105
|
-
"Please upgrade: pip install 'anthropic>=0.47.0'"
|
|
106
|
-
)
|
|
107
|
-
|
|
108
|
-
prompt_template, messages, tool_types, base_call_kwargs = _utils.setup_call(
|
|
109
|
-
fn,
|
|
110
|
-
fn_args,
|
|
111
|
-
dynamic_config,
|
|
112
|
-
tools,
|
|
113
|
-
AnthropicTool,
|
|
114
|
-
call_params,
|
|
115
|
-
convert_common_call_params,
|
|
116
|
-
)
|
|
117
|
-
call_kwargs = cast(AnthropicCallKwargs, base_call_kwargs)
|
|
118
|
-
messages = cast(list[BaseMessageParam | MessageParam], messages)
|
|
119
|
-
messages = convert_message_params(messages)
|
|
120
|
-
|
|
121
|
-
if messages[0]["role"] == "system":
|
|
122
|
-
call_kwargs["system"] = messages.pop(0)["content"] # pyright: ignore [reportGeneralTypeIssues]
|
|
123
|
-
|
|
124
|
-
use_json_mode = json_mode or (response_model and thinking_enabled)
|
|
125
|
-
|
|
126
|
-
if use_json_mode:
|
|
127
|
-
json_mode_content = _utils.json_mode_content(response_model)
|
|
128
|
-
if isinstance(messages[-1]["content"], str):
|
|
129
|
-
messages[-1]["content"] += json_mode_content
|
|
130
|
-
else:
|
|
131
|
-
messages[-1]["content"] = list(messages[-1]["content"]) + [
|
|
132
|
-
{"type": "text", "text": json_mode_content}
|
|
133
|
-
]
|
|
134
|
-
elif response_model:
|
|
135
|
-
assert tool_types, "At least one tool must be provided for extraction."
|
|
136
|
-
call_kwargs["tool_choice"] = {"type": "tool", "name": tool_types[0]._name()}
|
|
137
|
-
call_kwargs |= {
|
|
138
|
-
"model": model,
|
|
139
|
-
"messages": messages,
|
|
140
|
-
"max_tokens": call_kwargs["max_tokens"],
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
if client is None:
|
|
144
|
-
client = AsyncAnthropic() if inspect.iscoroutinefunction(fn) else Anthropic()
|
|
145
|
-
create = client.messages.create
|
|
146
|
-
return create, prompt_template, messages, tool_types, call_kwargs
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
"""usage docs: learn/calls.md#provider-specific-parameters"""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
from collections.abc import Iterable
|
|
6
|
-
|
|
7
|
-
from anthropic.types import TextBlockParam
|
|
8
|
-
from anthropic.types.completion_create_params import Metadata
|
|
9
|
-
from anthropic.types.message_create_params import ToolChoice
|
|
10
|
-
from httpx import Timeout
|
|
11
|
-
from typing_extensions import NotRequired
|
|
12
|
-
|
|
13
|
-
from ..base import BaseCallParams
|
|
14
|
-
from ._thinking import ThinkingConfigParam
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class AnthropicCallParams(BaseCallParams):
|
|
18
|
-
"""The parameters to use when calling the Anthropic API.
|
|
19
|
-
|
|
20
|
-
[Anthropic API Reference](https://docs.anthropic.com/en/api/messages)
|
|
21
|
-
|
|
22
|
-
Attributes:
|
|
23
|
-
max_tokens: ...
|
|
24
|
-
tool_choice: ...
|
|
25
|
-
thinking: ...
|
|
26
|
-
metadata: ...
|
|
27
|
-
stop_sequences: ...
|
|
28
|
-
temperature: ...
|
|
29
|
-
top_k: ...
|
|
30
|
-
top_p: ...
|
|
31
|
-
timeout: ...
|
|
32
|
-
"""
|
|
33
|
-
|
|
34
|
-
extra_headers: NotRequired[dict[str, str] | None]
|
|
35
|
-
max_tokens: int
|
|
36
|
-
tool_choice: NotRequired[ToolChoice | None]
|
|
37
|
-
thinking: NotRequired[ThinkingConfigParam | None]
|
|
38
|
-
metadata: NotRequired[Metadata | None]
|
|
39
|
-
stop_sequences: NotRequired[list[str] | None]
|
|
40
|
-
system: NotRequired[str | Iterable[TextBlockParam] | None]
|
|
41
|
-
temperature: NotRequired[float | None]
|
|
42
|
-
top_k: NotRequired[int | None]
|
|
43
|
-
top_p: NotRequired[float | None]
|
|
44
|
-
timeout: NotRequired[float | Timeout | None]
|
|
@@ -1,226 +0,0 @@
|
|
|
1
|
-
"""This module contains the `AnthropicCallResponse` class.
|
|
2
|
-
|
|
3
|
-
usage docs: learn/calls.md#handling-responses
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
from collections.abc import Sequence
|
|
7
|
-
from functools import cached_property
|
|
8
|
-
|
|
9
|
-
from anthropic.types import (
|
|
10
|
-
Message,
|
|
11
|
-
MessageParam,
|
|
12
|
-
ToolParam,
|
|
13
|
-
ToolResultBlockParam,
|
|
14
|
-
Usage,
|
|
15
|
-
)
|
|
16
|
-
from pydantic import SerializeAsAny, computed_field
|
|
17
|
-
|
|
18
|
-
from .. import BaseMessageParam
|
|
19
|
-
from ..base import BaseCallResponse, transform_tool_outputs, types
|
|
20
|
-
from ..base.types import CostMetadata
|
|
21
|
-
from ._utils._convert_finish_reason_to_common_finish_reasons import (
|
|
22
|
-
_convert_finish_reasons_to_common_finish_reasons,
|
|
23
|
-
)
|
|
24
|
-
from ._utils._message_param_converter import AnthropicMessageParamConverter
|
|
25
|
-
from .call_params import AnthropicCallParams
|
|
26
|
-
from .dynamic_config import AnthropicDynamicConfig, AsyncAnthropicDynamicConfig
|
|
27
|
-
from .tool import AnthropicTool
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
class AnthropicCallResponse(
|
|
31
|
-
BaseCallResponse[
|
|
32
|
-
Message,
|
|
33
|
-
AnthropicTool,
|
|
34
|
-
ToolParam,
|
|
35
|
-
AsyncAnthropicDynamicConfig | AnthropicDynamicConfig,
|
|
36
|
-
MessageParam,
|
|
37
|
-
AnthropicCallParams,
|
|
38
|
-
MessageParam,
|
|
39
|
-
AnthropicMessageParamConverter,
|
|
40
|
-
]
|
|
41
|
-
):
|
|
42
|
-
"""A convenience wrapper around the Anthropic `Message` response.
|
|
43
|
-
|
|
44
|
-
When calling the Anthropic API using a function decorated with `anthropic_call`, the
|
|
45
|
-
response will be an `AnthropicCallResponse` instance with properties that allow for
|
|
46
|
-
more convenience access to commonly used attributes.
|
|
47
|
-
|
|
48
|
-
Example:
|
|
49
|
-
|
|
50
|
-
```python
|
|
51
|
-
from mirascope.core import prompt_template
|
|
52
|
-
from mirascope.core.anthropic import anthropic_call
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
@anthropic_call("claude-3-5-sonnet-20240620")
|
|
56
|
-
def recommend_book(genre: str) -> str:
|
|
57
|
-
return f"Recommend a {genre} book"
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
response = recommend_book("fantasy") # response is an `AnthropicCallResponse` instance
|
|
61
|
-
print(response.content)
|
|
62
|
-
```
|
|
63
|
-
"""
|
|
64
|
-
|
|
65
|
-
_message_converter: type[AnthropicMessageParamConverter] = (
|
|
66
|
-
AnthropicMessageParamConverter
|
|
67
|
-
)
|
|
68
|
-
|
|
69
|
-
_provider = "anthropic"
|
|
70
|
-
|
|
71
|
-
@computed_field
|
|
72
|
-
@property
|
|
73
|
-
def content(self) -> str:
|
|
74
|
-
"""Returns the text content from the first text block."""
|
|
75
|
-
for block in self.response.content:
|
|
76
|
-
if block.type == "text":
|
|
77
|
-
return block.text
|
|
78
|
-
return ""
|
|
79
|
-
|
|
80
|
-
@computed_field
|
|
81
|
-
@property
|
|
82
|
-
def thinking(self) -> str | None:
|
|
83
|
-
"""Returns the thinking content from the first thinking block."""
|
|
84
|
-
for block in self.response.content:
|
|
85
|
-
if block.type == "thinking":
|
|
86
|
-
return block.thinking
|
|
87
|
-
return None
|
|
88
|
-
|
|
89
|
-
@computed_field
|
|
90
|
-
@property
|
|
91
|
-
def signature(self) -> str | None:
|
|
92
|
-
"""Returns the signature from the first thinking block."""
|
|
93
|
-
for block in self.response.content:
|
|
94
|
-
if block.type == "thinking":
|
|
95
|
-
return block.signature
|
|
96
|
-
return None
|
|
97
|
-
|
|
98
|
-
@computed_field
|
|
99
|
-
@property
|
|
100
|
-
def finish_reasons(self) -> list[str]:
|
|
101
|
-
"""Returns the finish reasons of the response."""
|
|
102
|
-
return [str(self.response.stop_reason)]
|
|
103
|
-
|
|
104
|
-
@computed_field
|
|
105
|
-
@property
|
|
106
|
-
def model(self) -> str:
|
|
107
|
-
"""Returns the name of the response model."""
|
|
108
|
-
return self.response.model
|
|
109
|
-
|
|
110
|
-
@computed_field
|
|
111
|
-
@property
|
|
112
|
-
def id(self) -> str:
|
|
113
|
-
"""Returns the id of the response."""
|
|
114
|
-
return self.response.id
|
|
115
|
-
|
|
116
|
-
@property
|
|
117
|
-
def usage(self) -> Usage:
|
|
118
|
-
"""Returns the usage of the message."""
|
|
119
|
-
return self.response.usage
|
|
120
|
-
|
|
121
|
-
@computed_field
|
|
122
|
-
@property
|
|
123
|
-
def input_tokens(self) -> int:
|
|
124
|
-
"""Returns the number of input tokens."""
|
|
125
|
-
return self.usage.input_tokens
|
|
126
|
-
|
|
127
|
-
@computed_field
|
|
128
|
-
@property
|
|
129
|
-
def cached_tokens(self) -> int:
|
|
130
|
-
"""Returns the number of cached tokens."""
|
|
131
|
-
return getattr(self.usage, "cache_read_input_tokens", 0)
|
|
132
|
-
|
|
133
|
-
@computed_field
|
|
134
|
-
@property
|
|
135
|
-
def output_tokens(self) -> int:
|
|
136
|
-
"""Returns the number of output tokens."""
|
|
137
|
-
return self.usage.output_tokens
|
|
138
|
-
|
|
139
|
-
@computed_field
|
|
140
|
-
@cached_property
|
|
141
|
-
def message_param(self) -> SerializeAsAny[MessageParam]:
|
|
142
|
-
"""Returns the assistants's response as a message parameter."""
|
|
143
|
-
return MessageParam(**self.response.model_dump(include={"content", "role"}))
|
|
144
|
-
|
|
145
|
-
@cached_property
|
|
146
|
-
def tools(self) -> list[AnthropicTool] | None:
|
|
147
|
-
"""Returns any available tool calls as their `AnthropicTool` definition.
|
|
148
|
-
|
|
149
|
-
Raises:
|
|
150
|
-
ValidationError: if a tool call doesn't match the tool's schema.
|
|
151
|
-
"""
|
|
152
|
-
if not self.tool_types:
|
|
153
|
-
return None
|
|
154
|
-
|
|
155
|
-
extracted_tools = []
|
|
156
|
-
for content in self.response.content:
|
|
157
|
-
if content.type != "tool_use":
|
|
158
|
-
continue
|
|
159
|
-
for tool_type in self.tool_types:
|
|
160
|
-
if content.name == tool_type._name():
|
|
161
|
-
extracted_tools.append(tool_type.from_tool_call(content))
|
|
162
|
-
break
|
|
163
|
-
|
|
164
|
-
return extracted_tools
|
|
165
|
-
|
|
166
|
-
@cached_property
|
|
167
|
-
def tool(self) -> AnthropicTool | None:
|
|
168
|
-
"""Returns the 0th tool for the 0th choice message.
|
|
169
|
-
|
|
170
|
-
Raises:
|
|
171
|
-
ValidationError: if the tool call doesn't match the tool's schema.
|
|
172
|
-
"""
|
|
173
|
-
if tools := self.tools:
|
|
174
|
-
return tools[0]
|
|
175
|
-
return None
|
|
176
|
-
|
|
177
|
-
@classmethod
|
|
178
|
-
@transform_tool_outputs
|
|
179
|
-
def tool_message_params(
|
|
180
|
-
cls, tools_and_outputs: Sequence[tuple[AnthropicTool, str]]
|
|
181
|
-
) -> list[MessageParam]:
|
|
182
|
-
"""Returns the tool message parameters for tool call results.
|
|
183
|
-
|
|
184
|
-
Args:
|
|
185
|
-
tools_and_outputs: The sequence of tools and their outputs from which the tool
|
|
186
|
-
message parameters should be constructed.
|
|
187
|
-
|
|
188
|
-
Returns:
|
|
189
|
-
The list of constructed `MessageParam` parameters.
|
|
190
|
-
"""
|
|
191
|
-
return [
|
|
192
|
-
{
|
|
193
|
-
"role": "user",
|
|
194
|
-
"content": [
|
|
195
|
-
ToolResultBlockParam(
|
|
196
|
-
tool_use_id=tool.tool_call.id, # pyright: ignore [reportOptionalMemberAccess]
|
|
197
|
-
type="tool_result",
|
|
198
|
-
content=[{"text": output, "type": "text"}],
|
|
199
|
-
)
|
|
200
|
-
for tool, output in tools_and_outputs
|
|
201
|
-
],
|
|
202
|
-
}
|
|
203
|
-
]
|
|
204
|
-
|
|
205
|
-
@property
|
|
206
|
-
def common_finish_reasons(self) -> list[types.FinishReason] | None:
|
|
207
|
-
"""Provider-agnostic finish reasons."""
|
|
208
|
-
return _convert_finish_reasons_to_common_finish_reasons(self.finish_reasons)
|
|
209
|
-
|
|
210
|
-
@property
|
|
211
|
-
def common_message_param(self) -> BaseMessageParam:
|
|
212
|
-
return AnthropicMessageParamConverter.from_provider([(self.message_param)])[0]
|
|
213
|
-
|
|
214
|
-
@property
|
|
215
|
-
def common_user_message_param(self) -> BaseMessageParam | None:
|
|
216
|
-
if not self.user_message_param:
|
|
217
|
-
return None
|
|
218
|
-
return AnthropicMessageParamConverter.from_provider(
|
|
219
|
-
[(self.user_message_param)]
|
|
220
|
-
)[0]
|
|
221
|
-
|
|
222
|
-
@computed_field
|
|
223
|
-
@property
|
|
224
|
-
def cost_metadata(self) -> CostMetadata:
|
|
225
|
-
"""Get metadata required for cost calculation."""
|
|
226
|
-
return super().cost_metadata
|