mirascope 1.25.7__py3-none-any.whl → 2.0.0a0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mirascope/__init__.py +3 -59
- mirascope/graphs/__init__.py +22 -0
- mirascope/{experimental/graphs → graphs}/finite_state_machine.py +70 -159
- mirascope/llm/__init__.py +206 -16
- mirascope/llm/agents/__init__.py +15 -0
- mirascope/llm/agents/agent.py +97 -0
- mirascope/llm/agents/agent_template.py +45 -0
- mirascope/llm/agents/decorator.py +176 -0
- mirascope/llm/calls/__init__.py +16 -0
- mirascope/llm/calls/base_call.py +33 -0
- mirascope/llm/calls/calls.py +315 -0
- mirascope/llm/calls/decorator.py +255 -0
- mirascope/llm/clients/__init__.py +34 -0
- mirascope/llm/clients/anthropic/__init__.py +11 -0
- mirascope/llm/clients/anthropic/_utils/__init__.py +13 -0
- mirascope/llm/clients/anthropic/_utils/decode.py +244 -0
- mirascope/llm/clients/anthropic/_utils/encode.py +243 -0
- mirascope/llm/clients/anthropic/clients.py +819 -0
- mirascope/llm/clients/anthropic/model_ids.py +8 -0
- mirascope/llm/clients/base/__init__.py +15 -0
- mirascope/llm/clients/base/_utils.py +192 -0
- mirascope/llm/clients/base/client.py +1256 -0
- mirascope/llm/clients/base/kwargs.py +12 -0
- mirascope/llm/clients/base/params.py +93 -0
- mirascope/llm/clients/google/__init__.py +6 -0
- mirascope/llm/clients/google/_utils/__init__.py +13 -0
- mirascope/llm/clients/google/_utils/decode.py +231 -0
- mirascope/llm/clients/google/_utils/encode.py +279 -0
- mirascope/llm/clients/google/clients.py +853 -0
- mirascope/llm/clients/google/message.py +7 -0
- mirascope/llm/clients/google/model_ids.py +15 -0
- mirascope/llm/clients/openai/__init__.py +25 -0
- mirascope/llm/clients/openai/completions/__init__.py +9 -0
- mirascope/llm/clients/openai/completions/_utils/__init__.py +13 -0
- mirascope/llm/clients/openai/completions/_utils/decode.py +187 -0
- mirascope/llm/clients/openai/completions/_utils/encode.py +358 -0
- mirascope/llm/clients/openai/completions/_utils/model_features.py +81 -0
- mirascope/llm/clients/openai/completions/clients.py +833 -0
- mirascope/llm/clients/openai/completions/model_ids.py +8 -0
- mirascope/llm/clients/openai/responses/__init__.py +9 -0
- mirascope/llm/clients/openai/responses/_utils/__init__.py +13 -0
- mirascope/llm/clients/openai/responses/_utils/decode.py +194 -0
- mirascope/llm/clients/openai/responses/_utils/encode.py +333 -0
- mirascope/llm/clients/openai/responses/_utils/model_features.py +87 -0
- mirascope/llm/clients/openai/responses/clients.py +832 -0
- mirascope/llm/clients/openai/responses/model_ids.py +8 -0
- mirascope/llm/clients/openai/shared/__init__.py +7 -0
- mirascope/llm/clients/openai/shared/_utils.py +55 -0
- mirascope/llm/clients/providers.py +175 -0
- mirascope/llm/content/__init__.py +70 -0
- mirascope/llm/content/audio.py +173 -0
- mirascope/llm/content/document.py +94 -0
- mirascope/llm/content/image.py +206 -0
- mirascope/llm/content/text.py +47 -0
- mirascope/llm/content/thought.py +58 -0
- mirascope/llm/content/tool_call.py +63 -0
- mirascope/llm/content/tool_output.py +26 -0
- mirascope/llm/context/__init__.py +6 -0
- mirascope/llm/context/_utils.py +28 -0
- mirascope/llm/context/context.py +24 -0
- mirascope/llm/exceptions.py +105 -0
- mirascope/llm/formatting/__init__.py +22 -0
- mirascope/llm/formatting/_utils.py +74 -0
- mirascope/llm/formatting/format.py +104 -0
- mirascope/llm/formatting/from_call_args.py +30 -0
- mirascope/llm/formatting/partial.py +58 -0
- mirascope/llm/formatting/types.py +109 -0
- mirascope/llm/mcp/__init__.py +5 -0
- mirascope/llm/mcp/client.py +118 -0
- mirascope/llm/messages/__init__.py +32 -0
- mirascope/llm/messages/message.py +182 -0
- mirascope/llm/models/__init__.py +16 -0
- mirascope/llm/models/models.py +1243 -0
- mirascope/llm/prompts/__init__.py +33 -0
- mirascope/llm/prompts/_utils.py +60 -0
- mirascope/llm/prompts/decorator.py +286 -0
- mirascope/llm/prompts/protocols.py +99 -0
- mirascope/llm/responses/__init__.py +57 -0
- mirascope/llm/responses/_utils.py +56 -0
- mirascope/llm/responses/base_response.py +91 -0
- mirascope/llm/responses/base_stream_response.py +697 -0
- mirascope/llm/responses/finish_reason.py +27 -0
- mirascope/llm/responses/response.py +345 -0
- mirascope/llm/responses/root_response.py +177 -0
- mirascope/llm/responses/stream_response.py +572 -0
- mirascope/llm/responses/streams.py +363 -0
- mirascope/llm/tools/__init__.py +40 -0
- mirascope/llm/tools/_utils.py +25 -0
- mirascope/llm/tools/decorator.py +175 -0
- mirascope/llm/tools/protocols.py +96 -0
- mirascope/llm/tools/tool_schema.py +246 -0
- mirascope/llm/tools/toolkit.py +152 -0
- mirascope/llm/tools/tools.py +169 -0
- mirascope/llm/types/__init__.py +22 -0
- mirascope/llm/types/dataclass.py +9 -0
- mirascope/llm/types/jsonable.py +44 -0
- mirascope/llm/types/type_vars.py +19 -0
- mirascope-2.0.0a0.dist-info/METADATA +117 -0
- mirascope-2.0.0a0.dist-info/RECORD +101 -0
- mirascope/beta/__init__.py +0 -3
- mirascope/beta/openai/__init__.py +0 -17
- mirascope/beta/openai/realtime/__init__.py +0 -13
- mirascope/beta/openai/realtime/_utils/__init__.py +0 -3
- mirascope/beta/openai/realtime/_utils/_audio.py +0 -74
- mirascope/beta/openai/realtime/_utils/_protocols.py +0 -50
- mirascope/beta/openai/realtime/realtime.py +0 -500
- mirascope/beta/openai/realtime/recording.py +0 -98
- mirascope/beta/openai/realtime/tool.py +0 -113
- mirascope/beta/rag/__init__.py +0 -24
- mirascope/beta/rag/base/__init__.py +0 -22
- mirascope/beta/rag/base/chunkers/__init__.py +0 -2
- mirascope/beta/rag/base/chunkers/base_chunker.py +0 -37
- mirascope/beta/rag/base/chunkers/text_chunker.py +0 -33
- mirascope/beta/rag/base/config.py +0 -8
- mirascope/beta/rag/base/document.py +0 -11
- mirascope/beta/rag/base/embedders.py +0 -35
- mirascope/beta/rag/base/embedding_params.py +0 -18
- mirascope/beta/rag/base/embedding_response.py +0 -30
- mirascope/beta/rag/base/query_results.py +0 -7
- mirascope/beta/rag/base/vectorstore_params.py +0 -18
- mirascope/beta/rag/base/vectorstores.py +0 -37
- mirascope/beta/rag/chroma/__init__.py +0 -11
- mirascope/beta/rag/chroma/types.py +0 -62
- mirascope/beta/rag/chroma/vectorstores.py +0 -121
- mirascope/beta/rag/cohere/__init__.py +0 -11
- mirascope/beta/rag/cohere/embedders.py +0 -87
- mirascope/beta/rag/cohere/embedding_params.py +0 -29
- mirascope/beta/rag/cohere/embedding_response.py +0 -29
- mirascope/beta/rag/cohere/py.typed +0 -0
- mirascope/beta/rag/openai/__init__.py +0 -11
- mirascope/beta/rag/openai/embedders.py +0 -144
- mirascope/beta/rag/openai/embedding_params.py +0 -18
- mirascope/beta/rag/openai/embedding_response.py +0 -14
- mirascope/beta/rag/openai/py.typed +0 -0
- mirascope/beta/rag/pinecone/__init__.py +0 -19
- mirascope/beta/rag/pinecone/types.py +0 -143
- mirascope/beta/rag/pinecone/vectorstores.py +0 -148
- mirascope/beta/rag/weaviate/__init__.py +0 -6
- mirascope/beta/rag/weaviate/types.py +0 -92
- mirascope/beta/rag/weaviate/vectorstores.py +0 -103
- mirascope/core/__init__.py +0 -109
- mirascope/core/anthropic/__init__.py +0 -31
- mirascope/core/anthropic/_call.py +0 -67
- mirascope/core/anthropic/_call_kwargs.py +0 -13
- mirascope/core/anthropic/_thinking.py +0 -70
- mirascope/core/anthropic/_utils/__init__.py +0 -16
- mirascope/core/anthropic/_utils/_convert_common_call_params.py +0 -25
- mirascope/core/anthropic/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -21
- mirascope/core/anthropic/_utils/_convert_message_params.py +0 -102
- mirascope/core/anthropic/_utils/_get_json_output.py +0 -31
- mirascope/core/anthropic/_utils/_handle_stream.py +0 -113
- mirascope/core/anthropic/_utils/_message_param_converter.py +0 -154
- mirascope/core/anthropic/_utils/_setup_call.py +0 -146
- mirascope/core/anthropic/call_params.py +0 -44
- mirascope/core/anthropic/call_response.py +0 -226
- mirascope/core/anthropic/call_response_chunk.py +0 -152
- mirascope/core/anthropic/dynamic_config.py +0 -40
- mirascope/core/anthropic/py.typed +0 -0
- mirascope/core/anthropic/stream.py +0 -204
- mirascope/core/anthropic/tool.py +0 -101
- mirascope/core/azure/__init__.py +0 -31
- mirascope/core/azure/_call.py +0 -67
- mirascope/core/azure/_call_kwargs.py +0 -13
- mirascope/core/azure/_utils/__init__.py +0 -14
- mirascope/core/azure/_utils/_convert_common_call_params.py +0 -26
- mirascope/core/azure/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -21
- mirascope/core/azure/_utils/_convert_message_params.py +0 -121
- mirascope/core/azure/_utils/_get_credential.py +0 -33
- mirascope/core/azure/_utils/_get_json_output.py +0 -27
- mirascope/core/azure/_utils/_handle_stream.py +0 -130
- mirascope/core/azure/_utils/_message_param_converter.py +0 -117
- mirascope/core/azure/_utils/_setup_call.py +0 -183
- mirascope/core/azure/call_params.py +0 -59
- mirascope/core/azure/call_response.py +0 -215
- mirascope/core/azure/call_response_chunk.py +0 -105
- mirascope/core/azure/dynamic_config.py +0 -30
- mirascope/core/azure/py.typed +0 -0
- mirascope/core/azure/stream.py +0 -147
- mirascope/core/azure/tool.py +0 -93
- mirascope/core/base/__init__.py +0 -86
- mirascope/core/base/_call_factory.py +0 -256
- mirascope/core/base/_create.py +0 -253
- mirascope/core/base/_extract.py +0 -175
- mirascope/core/base/_extract_with_tools.py +0 -189
- mirascope/core/base/_partial.py +0 -95
- mirascope/core/base/_utils/__init__.py +0 -92
- mirascope/core/base/_utils/_base_message_param_converter.py +0 -22
- mirascope/core/base/_utils/_base_type.py +0 -26
- mirascope/core/base/_utils/_convert_base_model_to_base_tool.py +0 -48
- mirascope/core/base/_utils/_convert_base_type_to_base_tool.py +0 -24
- mirascope/core/base/_utils/_convert_function_to_base_tool.py +0 -139
- mirascope/core/base/_utils/_convert_messages_to_message_params.py +0 -178
- mirascope/core/base/_utils/_convert_provider_finish_reason_to_finish_reason.py +0 -20
- mirascope/core/base/_utils/_default_tool_docstring.py +0 -6
- mirascope/core/base/_utils/_extract_tool_return.py +0 -42
- mirascope/core/base/_utils/_fn_is_async.py +0 -24
- mirascope/core/base/_utils/_format_template.py +0 -32
- mirascope/core/base/_utils/_get_audio_type.py +0 -18
- mirascope/core/base/_utils/_get_common_usage.py +0 -20
- mirascope/core/base/_utils/_get_create_fn_or_async_create_fn.py +0 -137
- mirascope/core/base/_utils/_get_document_type.py +0 -7
- mirascope/core/base/_utils/_get_dynamic_configuration.py +0 -69
- mirascope/core/base/_utils/_get_fields_from_call_args.py +0 -34
- mirascope/core/base/_utils/_get_fn_args.py +0 -23
- mirascope/core/base/_utils/_get_image_dimensions.py +0 -39
- mirascope/core/base/_utils/_get_image_type.py +0 -26
- mirascope/core/base/_utils/_get_metadata.py +0 -17
- mirascope/core/base/_utils/_get_possible_user_message_param.py +0 -21
- mirascope/core/base/_utils/_get_prompt_template.py +0 -28
- mirascope/core/base/_utils/_get_template_values.py +0 -51
- mirascope/core/base/_utils/_get_template_variables.py +0 -38
- mirascope/core/base/_utils/_get_unsupported_tool_config_keys.py +0 -10
- mirascope/core/base/_utils/_is_prompt_template.py +0 -24
- mirascope/core/base/_utils/_json_mode_content.py +0 -17
- mirascope/core/base/_utils/_messages_decorator.py +0 -121
- mirascope/core/base/_utils/_parse_content_template.py +0 -323
- mirascope/core/base/_utils/_parse_prompt_messages.py +0 -63
- mirascope/core/base/_utils/_pil_image_to_bytes.py +0 -13
- mirascope/core/base/_utils/_protocols.py +0 -901
- mirascope/core/base/_utils/_setup_call.py +0 -79
- mirascope/core/base/_utils/_setup_extract_tool.py +0 -30
- mirascope/core/base/call_kwargs.py +0 -13
- mirascope/core/base/call_params.py +0 -36
- mirascope/core/base/call_response.py +0 -338
- mirascope/core/base/call_response_chunk.py +0 -130
- mirascope/core/base/dynamic_config.py +0 -82
- mirascope/core/base/from_call_args.py +0 -30
- mirascope/core/base/merge_decorators.py +0 -59
- mirascope/core/base/message_param.py +0 -175
- mirascope/core/base/messages.py +0 -116
- mirascope/core/base/metadata.py +0 -13
- mirascope/core/base/prompt.py +0 -497
- mirascope/core/base/response_model_config_dict.py +0 -9
- mirascope/core/base/stream.py +0 -479
- mirascope/core/base/stream_config.py +0 -11
- mirascope/core/base/structured_stream.py +0 -296
- mirascope/core/base/tool.py +0 -214
- mirascope/core/base/toolkit.py +0 -176
- mirascope/core/base/types.py +0 -344
- mirascope/core/bedrock/__init__.py +0 -34
- mirascope/core/bedrock/_call.py +0 -68
- mirascope/core/bedrock/_call_kwargs.py +0 -12
- mirascope/core/bedrock/_types.py +0 -104
- mirascope/core/bedrock/_utils/__init__.py +0 -14
- mirascope/core/bedrock/_utils/_convert_common_call_params.py +0 -39
- mirascope/core/bedrock/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -23
- mirascope/core/bedrock/_utils/_convert_message_params.py +0 -111
- mirascope/core/bedrock/_utils/_get_json_output.py +0 -30
- mirascope/core/bedrock/_utils/_handle_stream.py +0 -104
- mirascope/core/bedrock/_utils/_message_param_converter.py +0 -172
- mirascope/core/bedrock/_utils/_setup_call.py +0 -258
- mirascope/core/bedrock/call_params.py +0 -38
- mirascope/core/bedrock/call_response.py +0 -248
- mirascope/core/bedrock/call_response_chunk.py +0 -111
- mirascope/core/bedrock/dynamic_config.py +0 -37
- mirascope/core/bedrock/py.typed +0 -0
- mirascope/core/bedrock/stream.py +0 -154
- mirascope/core/bedrock/tool.py +0 -100
- mirascope/core/cohere/__init__.py +0 -30
- mirascope/core/cohere/_call.py +0 -67
- mirascope/core/cohere/_call_kwargs.py +0 -11
- mirascope/core/cohere/_types.py +0 -20
- mirascope/core/cohere/_utils/__init__.py +0 -14
- mirascope/core/cohere/_utils/_convert_common_call_params.py +0 -26
- mirascope/core/cohere/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -24
- mirascope/core/cohere/_utils/_convert_message_params.py +0 -32
- mirascope/core/cohere/_utils/_get_json_output.py +0 -30
- mirascope/core/cohere/_utils/_handle_stream.py +0 -35
- mirascope/core/cohere/_utils/_message_param_converter.py +0 -54
- mirascope/core/cohere/_utils/_setup_call.py +0 -150
- mirascope/core/cohere/call_params.py +0 -62
- mirascope/core/cohere/call_response.py +0 -205
- mirascope/core/cohere/call_response_chunk.py +0 -125
- mirascope/core/cohere/dynamic_config.py +0 -32
- mirascope/core/cohere/py.typed +0 -0
- mirascope/core/cohere/stream.py +0 -113
- mirascope/core/cohere/tool.py +0 -93
- mirascope/core/costs/__init__.py +0 -5
- mirascope/core/costs/_anthropic_calculate_cost.py +0 -219
- mirascope/core/costs/_azure_calculate_cost.py +0 -11
- mirascope/core/costs/_bedrock_calculate_cost.py +0 -15
- mirascope/core/costs/_cohere_calculate_cost.py +0 -44
- mirascope/core/costs/_gemini_calculate_cost.py +0 -67
- mirascope/core/costs/_google_calculate_cost.py +0 -427
- mirascope/core/costs/_groq_calculate_cost.py +0 -156
- mirascope/core/costs/_litellm_calculate_cost.py +0 -11
- mirascope/core/costs/_mistral_calculate_cost.py +0 -64
- mirascope/core/costs/_openai_calculate_cost.py +0 -416
- mirascope/core/costs/_vertex_calculate_cost.py +0 -67
- mirascope/core/costs/_xai_calculate_cost.py +0 -104
- mirascope/core/costs/calculate_cost.py +0 -86
- mirascope/core/gemini/__init__.py +0 -40
- mirascope/core/gemini/_call.py +0 -67
- mirascope/core/gemini/_call_kwargs.py +0 -12
- mirascope/core/gemini/_utils/__init__.py +0 -14
- mirascope/core/gemini/_utils/_convert_common_call_params.py +0 -39
- mirascope/core/gemini/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -23
- mirascope/core/gemini/_utils/_convert_message_params.py +0 -156
- mirascope/core/gemini/_utils/_get_json_output.py +0 -35
- mirascope/core/gemini/_utils/_handle_stream.py +0 -33
- mirascope/core/gemini/_utils/_message_param_converter.py +0 -209
- mirascope/core/gemini/_utils/_setup_call.py +0 -149
- mirascope/core/gemini/call_params.py +0 -52
- mirascope/core/gemini/call_response.py +0 -216
- mirascope/core/gemini/call_response_chunk.py +0 -100
- mirascope/core/gemini/dynamic_config.py +0 -26
- mirascope/core/gemini/stream.py +0 -120
- mirascope/core/gemini/tool.py +0 -104
- mirascope/core/google/__init__.py +0 -29
- mirascope/core/google/_call.py +0 -67
- mirascope/core/google/_call_kwargs.py +0 -13
- mirascope/core/google/_utils/__init__.py +0 -14
- mirascope/core/google/_utils/_convert_common_call_params.py +0 -38
- mirascope/core/google/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -27
- mirascope/core/google/_utils/_convert_message_params.py +0 -297
- mirascope/core/google/_utils/_get_json_output.py +0 -37
- mirascope/core/google/_utils/_handle_stream.py +0 -58
- mirascope/core/google/_utils/_message_param_converter.py +0 -200
- mirascope/core/google/_utils/_setup_call.py +0 -201
- mirascope/core/google/_utils/_validate_media_type.py +0 -58
- mirascope/core/google/call_params.py +0 -22
- mirascope/core/google/call_response.py +0 -255
- mirascope/core/google/call_response_chunk.py +0 -135
- mirascope/core/google/dynamic_config.py +0 -26
- mirascope/core/google/stream.py +0 -199
- mirascope/core/google/tool.py +0 -146
- mirascope/core/groq/__init__.py +0 -30
- mirascope/core/groq/_call.py +0 -67
- mirascope/core/groq/_call_kwargs.py +0 -13
- mirascope/core/groq/_utils/__init__.py +0 -14
- mirascope/core/groq/_utils/_convert_common_call_params.py +0 -26
- mirascope/core/groq/_utils/_convert_message_params.py +0 -112
- mirascope/core/groq/_utils/_get_json_output.py +0 -27
- mirascope/core/groq/_utils/_handle_stream.py +0 -123
- mirascope/core/groq/_utils/_message_param_converter.py +0 -89
- mirascope/core/groq/_utils/_setup_call.py +0 -132
- mirascope/core/groq/call_params.py +0 -52
- mirascope/core/groq/call_response.py +0 -213
- mirascope/core/groq/call_response_chunk.py +0 -104
- mirascope/core/groq/dynamic_config.py +0 -29
- mirascope/core/groq/py.typed +0 -0
- mirascope/core/groq/stream.py +0 -135
- mirascope/core/groq/tool.py +0 -80
- mirascope/core/litellm/__init__.py +0 -28
- mirascope/core/litellm/_call.py +0 -67
- mirascope/core/litellm/_utils/__init__.py +0 -5
- mirascope/core/litellm/_utils/_setup_call.py +0 -109
- mirascope/core/litellm/call_params.py +0 -10
- mirascope/core/litellm/call_response.py +0 -24
- mirascope/core/litellm/call_response_chunk.py +0 -14
- mirascope/core/litellm/dynamic_config.py +0 -8
- mirascope/core/litellm/py.typed +0 -0
- mirascope/core/litellm/stream.py +0 -86
- mirascope/core/litellm/tool.py +0 -13
- mirascope/core/mistral/__init__.py +0 -36
- mirascope/core/mistral/_call.py +0 -65
- mirascope/core/mistral/_call_kwargs.py +0 -19
- mirascope/core/mistral/_utils/__init__.py +0 -14
- mirascope/core/mistral/_utils/_convert_common_call_params.py +0 -24
- mirascope/core/mistral/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -22
- mirascope/core/mistral/_utils/_convert_message_params.py +0 -122
- mirascope/core/mistral/_utils/_get_json_output.py +0 -34
- mirascope/core/mistral/_utils/_handle_stream.py +0 -139
- mirascope/core/mistral/_utils/_message_param_converter.py +0 -176
- mirascope/core/mistral/_utils/_setup_call.py +0 -164
- mirascope/core/mistral/call_params.py +0 -36
- mirascope/core/mistral/call_response.py +0 -205
- mirascope/core/mistral/call_response_chunk.py +0 -105
- mirascope/core/mistral/dynamic_config.py +0 -33
- mirascope/core/mistral/py.typed +0 -0
- mirascope/core/mistral/stream.py +0 -120
- mirascope/core/mistral/tool.py +0 -81
- mirascope/core/openai/__init__.py +0 -31
- mirascope/core/openai/_call.py +0 -67
- mirascope/core/openai/_call_kwargs.py +0 -13
- mirascope/core/openai/_utils/__init__.py +0 -14
- mirascope/core/openai/_utils/_convert_common_call_params.py +0 -26
- mirascope/core/openai/_utils/_convert_message_params.py +0 -148
- mirascope/core/openai/_utils/_get_json_output.py +0 -31
- mirascope/core/openai/_utils/_handle_stream.py +0 -138
- mirascope/core/openai/_utils/_message_param_converter.py +0 -105
- mirascope/core/openai/_utils/_setup_call.py +0 -155
- mirascope/core/openai/call_params.py +0 -92
- mirascope/core/openai/call_response.py +0 -273
- mirascope/core/openai/call_response_chunk.py +0 -139
- mirascope/core/openai/dynamic_config.py +0 -34
- mirascope/core/openai/py.typed +0 -0
- mirascope/core/openai/stream.py +0 -185
- mirascope/core/openai/tool.py +0 -101
- mirascope/core/py.typed +0 -0
- mirascope/core/vertex/__init__.py +0 -45
- mirascope/core/vertex/_call.py +0 -62
- mirascope/core/vertex/_call_kwargs.py +0 -12
- mirascope/core/vertex/_utils/__init__.py +0 -14
- mirascope/core/vertex/_utils/_convert_common_call_params.py +0 -37
- mirascope/core/vertex/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -23
- mirascope/core/vertex/_utils/_convert_message_params.py +0 -171
- mirascope/core/vertex/_utils/_get_json_output.py +0 -36
- mirascope/core/vertex/_utils/_handle_stream.py +0 -33
- mirascope/core/vertex/_utils/_message_param_converter.py +0 -133
- mirascope/core/vertex/_utils/_setup_call.py +0 -160
- mirascope/core/vertex/call_params.py +0 -24
- mirascope/core/vertex/call_response.py +0 -206
- mirascope/core/vertex/call_response_chunk.py +0 -99
- mirascope/core/vertex/dynamic_config.py +0 -28
- mirascope/core/vertex/stream.py +0 -119
- mirascope/core/vertex/tool.py +0 -101
- mirascope/core/xai/__init__.py +0 -28
- mirascope/core/xai/_call.py +0 -67
- mirascope/core/xai/_utils/__init__.py +0 -5
- mirascope/core/xai/_utils/_setup_call.py +0 -113
- mirascope/core/xai/call_params.py +0 -10
- mirascope/core/xai/call_response.py +0 -16
- mirascope/core/xai/call_response_chunk.py +0 -14
- mirascope/core/xai/dynamic_config.py +0 -8
- mirascope/core/xai/py.typed +0 -0
- mirascope/core/xai/stream.py +0 -57
- mirascope/core/xai/tool.py +0 -13
- mirascope/experimental/graphs/__init__.py +0 -5
- mirascope/integrations/__init__.py +0 -16
- mirascope/integrations/_middleware_factory.py +0 -403
- mirascope/integrations/langfuse/__init__.py +0 -3
- mirascope/integrations/langfuse/_utils.py +0 -114
- mirascope/integrations/langfuse/_with_langfuse.py +0 -70
- mirascope/integrations/logfire/__init__.py +0 -3
- mirascope/integrations/logfire/_utils.py +0 -225
- mirascope/integrations/logfire/_with_logfire.py +0 -63
- mirascope/integrations/otel/__init__.py +0 -10
- mirascope/integrations/otel/_utils.py +0 -270
- mirascope/integrations/otel/_with_hyperdx.py +0 -60
- mirascope/integrations/otel/_with_otel.py +0 -59
- mirascope/integrations/tenacity.py +0 -14
- mirascope/llm/_call.py +0 -401
- mirascope/llm/_context.py +0 -384
- mirascope/llm/_override.py +0 -3639
- mirascope/llm/_protocols.py +0 -500
- mirascope/llm/_response_metaclass.py +0 -31
- mirascope/llm/call_response.py +0 -158
- mirascope/llm/call_response_chunk.py +0 -66
- mirascope/llm/stream.py +0 -162
- mirascope/llm/tool.py +0 -64
- mirascope/mcp/__init__.py +0 -7
- mirascope/mcp/_utils.py +0 -288
- mirascope/mcp/client.py +0 -167
- mirascope/mcp/server.py +0 -356
- mirascope/mcp/tools.py +0 -110
- mirascope/py.typed +0 -0
- mirascope/retries/__init__.py +0 -11
- mirascope/retries/fallback.py +0 -131
- mirascope/retries/tenacity.py +0 -50
- mirascope/tools/__init__.py +0 -37
- mirascope/tools/base.py +0 -98
- mirascope/tools/system/__init__.py +0 -0
- mirascope/tools/system/_docker_operation.py +0 -166
- mirascope/tools/system/_file_system.py +0 -267
- mirascope/tools/web/__init__.py +0 -0
- mirascope/tools/web/_duckduckgo.py +0 -111
- mirascope/tools/web/_httpx.py +0 -125
- mirascope/tools/web/_parse_url_content.py +0 -94
- mirascope/tools/web/_requests.py +0 -54
- mirascope/v0/__init__.py +0 -43
- mirascope/v0/anthropic.py +0 -54
- mirascope/v0/base/__init__.py +0 -12
- mirascope/v0/base/calls.py +0 -118
- mirascope/v0/base/extractors.py +0 -122
- mirascope/v0/base/ops_utils.py +0 -207
- mirascope/v0/base/prompts.py +0 -48
- mirascope/v0/base/types.py +0 -14
- mirascope/v0/base/utils.py +0 -21
- mirascope/v0/openai.py +0 -54
- mirascope-1.25.7.dist-info/METADATA +0 -169
- mirascope-1.25.7.dist-info/RECORD +0 -378
- {mirascope-1.25.7.dist-info → mirascope-2.0.0a0.dist-info}/WHEEL +0 -0
- {mirascope-1.25.7.dist-info → mirascope-2.0.0a0.dist-info}/licenses/LICENSE +0 -0
mirascope/__init__.py
CHANGED
|
@@ -1,61 +1,5 @@
|
|
|
1
|
-
"""Mirascope
|
|
1
|
+
"""Mirascope v2 Beta."""
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
from contextlib import suppress
|
|
3
|
+
from . import graphs as graphs, llm as llm
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
from . import core as core
|
|
8
|
-
|
|
9
|
-
from .core import (
|
|
10
|
-
AudioPart,
|
|
11
|
-
AudioURLPart,
|
|
12
|
-
BaseDynamicConfig,
|
|
13
|
-
BaseMessageParam,
|
|
14
|
-
BaseTool,
|
|
15
|
-
BaseToolKit,
|
|
16
|
-
CacheControlPart,
|
|
17
|
-
DocumentPart,
|
|
18
|
-
DocumentURLPart,
|
|
19
|
-
ImagePart,
|
|
20
|
-
ImageURLPart,
|
|
21
|
-
LocalProvider,
|
|
22
|
-
Messages,
|
|
23
|
-
Provider,
|
|
24
|
-
TextPart,
|
|
25
|
-
ToolCallPart,
|
|
26
|
-
ToolResultPart,
|
|
27
|
-
prompt_template,
|
|
28
|
-
)
|
|
29
|
-
|
|
30
|
-
with suppress(ImportError):
|
|
31
|
-
from . import integrations as integrations
|
|
32
|
-
|
|
33
|
-
with suppress(ImportError):
|
|
34
|
-
from . import retries as retries
|
|
35
|
-
|
|
36
|
-
__version__ = importlib.metadata.version("mirascope")
|
|
37
|
-
|
|
38
|
-
__all__ = [
|
|
39
|
-
"AudioPart",
|
|
40
|
-
"AudioURLPart",
|
|
41
|
-
"BaseDynamicConfig",
|
|
42
|
-
"BaseMessageParam",
|
|
43
|
-
"BaseTool",
|
|
44
|
-
"BaseToolKit",
|
|
45
|
-
"CacheControlPart",
|
|
46
|
-
"DocumentPart",
|
|
47
|
-
"DocumentURLPart",
|
|
48
|
-
"ImagePart",
|
|
49
|
-
"ImageURLPart",
|
|
50
|
-
"LocalProvider",
|
|
51
|
-
"Messages",
|
|
52
|
-
"Provider",
|
|
53
|
-
"TextPart",
|
|
54
|
-
"ToolCallPart",
|
|
55
|
-
"ToolResultPart",
|
|
56
|
-
"__version__",
|
|
57
|
-
"core",
|
|
58
|
-
"integrations",
|
|
59
|
-
"prompt_template",
|
|
60
|
-
"retries",
|
|
61
|
-
]
|
|
5
|
+
__all__ = ["graphs", "llm"]
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""The `graphs` module for writing graphs in a declarative style.
|
|
2
|
+
|
|
3
|
+
This module provides graph interfacing for writing graphs as a collection of functions
|
|
4
|
+
that are marked as nodes. Simply calling the function for one node inside of another
|
|
5
|
+
node function indicates an edge.
|
|
6
|
+
|
|
7
|
+
The graph can run uncompiled, in which case it's simply a context management interface
|
|
8
|
+
that makes it easy to access / update a shared context across multiple functions.
|
|
9
|
+
|
|
10
|
+
Compiling the graph will construct the underlying graph represented by the implicit
|
|
11
|
+
edges defined in the code. The way a node function is executed inside of another node
|
|
12
|
+
function will determine the final node and edge structure of the graph.
|
|
13
|
+
|
|
14
|
+
For example, a node that calls another node and returns nothing will operate as it's own
|
|
15
|
+
node with an edge to the node it called. A node that calls another node and stores its
|
|
16
|
+
return value will split into two nodes, one for everything before the call, and one for
|
|
17
|
+
everything after.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
from .finite_state_machine import FiniteStateMachine, RunContext
|
|
21
|
+
|
|
22
|
+
__all__ = ["FiniteStateMachine", "RunContext"]
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
"""The `FiniteStateMachine` Class Implementation."""
|
|
2
2
|
|
|
3
|
-
import contextvars
|
|
4
3
|
import inspect
|
|
5
|
-
from collections.abc import Callable, Coroutine
|
|
4
|
+
from collections.abc import Callable, Coroutine, Iterator
|
|
5
|
+
from contextlib import contextmanager
|
|
6
|
+
from contextvars import ContextVar
|
|
7
|
+
from dataclasses import dataclass
|
|
6
8
|
from functools import wraps
|
|
7
|
-
from types import TracebackType
|
|
8
9
|
from typing import Any, Generic, ParamSpec, Protocol, overload
|
|
9
|
-
|
|
10
10
|
from typing_extensions import TypeVar
|
|
11
11
|
|
|
12
12
|
NoneType = type(None)
|
|
13
|
-
|
|
13
|
+
DepsT = TypeVar("DepsT", default=None)
|
|
14
14
|
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
@dataclass
|
|
17
|
+
class RunContext(Generic[DepsT]):
|
|
17
18
|
"""The runtime context for the Finite State Machine (FSM).
|
|
18
19
|
|
|
19
20
|
This class is used to store the state of the FSM and the data that is passed between
|
|
@@ -43,129 +44,27 @@ class RunContext(Generic[_DepsT]):
|
|
|
43
44
|
error_states (...): Error states and fallback handling.
|
|
44
45
|
"""
|
|
45
46
|
|
|
46
|
-
deps:
|
|
47
|
-
|
|
48
|
-
def __init__(self, deps: _DepsT, **data: dict[str, Any]) -> None:
|
|
49
|
-
self.deps = deps
|
|
50
|
-
for key, value in data.items():
|
|
51
|
-
setattr(self, key, value)
|
|
47
|
+
deps: DepsT
|
|
48
|
+
"""The dependencies for the FSM."""
|
|
52
49
|
|
|
53
50
|
|
|
54
|
-
|
|
55
|
-
# This automatically propagates across async boundaries
|
|
56
|
-
_CONTEXT_VAR: contextvars.ContextVar[RunContext[Any] | None] = contextvars.ContextVar(
|
|
51
|
+
FSM_CONTEXT: ContextVar[RunContext[Any] | None] = ContextVar(
|
|
57
52
|
"fsm_context", default=None
|
|
58
53
|
)
|
|
59
54
|
|
|
60
55
|
|
|
61
|
-
class FSMContextManager(Generic[_DepsT]):
|
|
62
|
-
"""Context manager for FSM contexts that supports both sync and async patterns.
|
|
63
|
-
|
|
64
|
-
This class implements both the synchronous context manager protocol
|
|
65
|
-
(__enter__/__exit__) and the asynchronous context manager protocol
|
|
66
|
-
(__aenter__/__aexit__), allowing it to be used with both `with` and
|
|
67
|
-
`async with` statements.
|
|
68
|
-
|
|
69
|
-
The context manager handles setting and resetting the context variable
|
|
70
|
-
that stores the RunContext, ensuring proper propagation through async code.
|
|
71
|
-
|
|
72
|
-
NOTE: This simplified implementation has some limitations with complex nested
|
|
73
|
-
async calls across context boundaries. For nested nodes calling other nodes
|
|
74
|
-
asynchronously after a context exit, the context may not be properly preserved.
|
|
75
|
-
In these cases, using a compiled machine is recommended.
|
|
76
|
-
|
|
77
|
-
NOTE: We implement stubs using the sync case because the async case is currently
|
|
78
|
-
the same and does not require separate implementations. In the future we may update
|
|
79
|
-
this to handle more complex async cases where the context e.g. pulls from an
|
|
80
|
-
external source or something.
|
|
81
|
-
|
|
82
|
-
Attributes:
|
|
83
|
-
ctx: The RunContext that will be set as active during the context.
|
|
84
|
-
token: The token returned by _CONTEXT_VAR.set() that is used to restore
|
|
85
|
-
the previous context when exiting.
|
|
86
|
-
"""
|
|
87
|
-
|
|
88
|
-
ctx: RunContext[_DepsT]
|
|
89
|
-
token: contextvars.Token | None = None
|
|
90
|
-
|
|
91
|
-
def __init__(self, ctx: RunContext[_DepsT]) -> None:
|
|
92
|
-
"""Initialize a new FSMContextManager.
|
|
93
|
-
|
|
94
|
-
Args:
|
|
95
|
-
ctx: The RunContext to use during this context.
|
|
96
|
-
"""
|
|
97
|
-
self.ctx = ctx
|
|
98
|
-
|
|
99
|
-
def __enter__(self) -> RunContext[_DepsT]:
|
|
100
|
-
"""Enter the context manager (synchronous).
|
|
101
|
-
|
|
102
|
-
Sets the RunContext as the current context and returns it.
|
|
103
|
-
|
|
104
|
-
Returns:
|
|
105
|
-
The RunContext for use within the `with` block.
|
|
106
|
-
"""
|
|
107
|
-
self.token = _CONTEXT_VAR.set(self.ctx)
|
|
108
|
-
return self.ctx
|
|
109
|
-
|
|
110
|
-
def __exit__(
|
|
111
|
-
self,
|
|
112
|
-
exc_type: type[BaseException],
|
|
113
|
-
exc_val: BaseException | None,
|
|
114
|
-
exc_tb: TracebackType | None,
|
|
115
|
-
) -> None:
|
|
116
|
-
"""Exit the context manager (synchronous).
|
|
117
|
-
|
|
118
|
-
Restores the previous context that was active before entering.
|
|
119
|
-
|
|
120
|
-
Args:
|
|
121
|
-
exc_type: The exception type if an exception was raised in the with block.
|
|
122
|
-
exc_val: The exception value if an exception was raised in the with block.
|
|
123
|
-
exc_tb: The traceback if an exception was raised in the with block.
|
|
124
|
-
"""
|
|
125
|
-
if self.token is not None:
|
|
126
|
-
_CONTEXT_VAR.reset(self.token)
|
|
127
|
-
self.token = None
|
|
128
|
-
|
|
129
|
-
async def __aenter__(self) -> RunContext[_DepsT]:
|
|
130
|
-
"""Enter the context manager (asynchronous).
|
|
131
|
-
|
|
132
|
-
Same as __enter__ but for use with `async with`.
|
|
133
|
-
|
|
134
|
-
Returns:
|
|
135
|
-
The RunContext for use within the `async with` block.
|
|
136
|
-
"""
|
|
137
|
-
return self.__enter__()
|
|
138
|
-
|
|
139
|
-
async def __aexit__(
|
|
140
|
-
self,
|
|
141
|
-
exc_type: type[BaseException],
|
|
142
|
-
exc_val: BaseException | None,
|
|
143
|
-
exc_tb: TracebackType | None,
|
|
144
|
-
) -> None:
|
|
145
|
-
"""Exit the context manager (asynchronous).
|
|
146
|
-
|
|
147
|
-
Same as __exit__ but for use with `async with`.
|
|
148
|
-
|
|
149
|
-
Args:
|
|
150
|
-
exc_type: The exception type if an exception was raised in the with block.
|
|
151
|
-
exc_val: The exception value if an exception was raised in the with block.
|
|
152
|
-
exc_tb: The traceback if an exception was raised in the with block.
|
|
153
|
-
"""
|
|
154
|
-
self.__exit__(exc_type, exc_val, exc_tb)
|
|
155
|
-
|
|
156
|
-
|
|
157
56
|
class FSMContextError(Exception):
|
|
158
57
|
"""Raised when a node is executed outside of a context manager."""
|
|
159
58
|
|
|
160
59
|
pass
|
|
161
60
|
|
|
162
61
|
|
|
163
|
-
|
|
164
|
-
|
|
62
|
+
NodeDecoratedFunctionP = ParamSpec("NodeDecoratedFunctionP")
|
|
63
|
+
NodeDecoratedFunctionR = TypeVar("NodeDecoratedFunctionR", covariant=True)
|
|
165
64
|
|
|
166
65
|
|
|
167
66
|
class NodeDecoratedFunction(
|
|
168
|
-
Protocol[
|
|
67
|
+
Protocol[NodeDecoratedFunctionP, NodeDecoratedFunctionR, DepsT]
|
|
169
68
|
):
|
|
170
69
|
"""The protocol for functions decorated with the `node` decorator.
|
|
171
70
|
|
|
@@ -178,17 +77,17 @@ class NodeDecoratedFunction(
|
|
|
178
77
|
|
|
179
78
|
def __call__(
|
|
180
79
|
self,
|
|
181
|
-
ctx: RunContext[
|
|
182
|
-
*args:
|
|
183
|
-
**kwargs:
|
|
184
|
-
) ->
|
|
80
|
+
ctx: RunContext[DepsT],
|
|
81
|
+
*args: NodeDecoratedFunctionP.args,
|
|
82
|
+
**kwargs: NodeDecoratedFunctionP.kwargs,
|
|
83
|
+
) -> NodeDecoratedFunctionR: ...
|
|
185
84
|
|
|
186
85
|
|
|
187
|
-
|
|
188
|
-
|
|
86
|
+
NodeDecoratorP = ParamSpec("NodeDecoratorP")
|
|
87
|
+
NodeDecoratorR = TypeVar("NodeDecoratorR")
|
|
189
88
|
|
|
190
89
|
|
|
191
|
-
class NodeDecorator(Protocol[
|
|
90
|
+
class NodeDecorator(Protocol[DepsT]):
|
|
192
91
|
"""The `node` decorator protocol.
|
|
193
92
|
|
|
194
93
|
This protocol enables overloading the `node` function such that it can detect and
|
|
@@ -201,24 +100,24 @@ class NodeDecorator(Protocol[_DepsT]):
|
|
|
201
100
|
def __call__(
|
|
202
101
|
self,
|
|
203
102
|
fn: NodeDecoratedFunction[
|
|
204
|
-
|
|
103
|
+
NodeDecoratorP, Coroutine[Any, Any, NodeDecoratorR], DepsT
|
|
205
104
|
],
|
|
206
|
-
) -> Callable[
|
|
105
|
+
) -> Callable[NodeDecoratorP, Coroutine[Any, Any, NodeDecoratorR]]: ...
|
|
207
106
|
|
|
208
107
|
@overload
|
|
209
108
|
def __call__(
|
|
210
|
-
self, fn: NodeDecoratedFunction[
|
|
211
|
-
) -> Callable[
|
|
109
|
+
self, fn: NodeDecoratedFunction[NodeDecoratorP, NodeDecoratorR, DepsT]
|
|
110
|
+
) -> Callable[NodeDecoratorP, NodeDecoratorR]: ...
|
|
212
111
|
|
|
213
112
|
def __call__(
|
|
214
113
|
self,
|
|
215
114
|
fn: NodeDecoratedFunction[
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
115
|
+
NodeDecoratorP,
|
|
116
|
+
NodeDecoratorR | Coroutine[Any, Any, NodeDecoratorR],
|
|
117
|
+
DepsT,
|
|
219
118
|
],
|
|
220
119
|
) -> Callable[
|
|
221
|
-
|
|
120
|
+
NodeDecoratorP, NodeDecoratorR | Coroutine[Any, Any, NodeDecoratorR]
|
|
222
121
|
]: ...
|
|
223
122
|
|
|
224
123
|
|
|
@@ -226,7 +125,8 @@ _P = ParamSpec("_P")
|
|
|
226
125
|
_R = TypeVar("_R")
|
|
227
126
|
|
|
228
127
|
|
|
229
|
-
|
|
128
|
+
@dataclass(kw_only=True)
|
|
129
|
+
class FiniteStateMachine(Generic[DepsT]):
|
|
230
130
|
'''Automatical Finite State Machine (FSM) compiled from the code execution graph.
|
|
231
131
|
|
|
232
132
|
This class provides a global `RunContext` and a `node` decorator that gives function
|
|
@@ -324,21 +224,21 @@ class FiniteStateMachine(Generic[_DepsT]):
|
|
|
324
224
|
|
|
325
225
|
|
|
326
226
|
@machine.node()
|
|
327
|
-
@llm.tool
|
|
227
|
+
@llm.tool
|
|
328
228
|
def all_books(ctx: g.RunContext[Library]) -> list[Book]:
|
|
329
229
|
"""Returns the titles of all books the library owns."""
|
|
330
230
|
return ctx.deps.all_books
|
|
331
231
|
|
|
332
232
|
|
|
333
233
|
@machine.node()
|
|
334
|
-
@llm.tool
|
|
234
|
+
@llm.tool
|
|
335
235
|
def book_is_available(ctx: g.RunContext[Library], title: str) -> str:
|
|
336
236
|
"""Returns the author of the book with the given title."""
|
|
337
237
|
return ctx.deps.available_books[title]
|
|
338
238
|
|
|
339
239
|
|
|
340
240
|
@machine.node()
|
|
341
|
-
@llm.call("openai", "gpt-4o-mini", tools=[all_books, book_is_available])
|
|
241
|
+
@llm.call(provider="openai:completions", model_id="gpt-4o-mini", tools=[all_books, book_is_available])
|
|
342
242
|
async def answer_question(ctx: g.RunContext[Library]) -> str:
|
|
343
243
|
return f"You are a librarian named {ctx.deps.librarian}"
|
|
344
244
|
|
|
@@ -410,13 +310,11 @@ class FiniteStateMachine(Generic[_DepsT]):
|
|
|
410
310
|
We get to code. The FSM then builds itself.
|
|
411
311
|
'''
|
|
412
312
|
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
def __init__(self, *, deps_type: type[_DepsT] = NoneType) -> None:
|
|
416
|
-
"""Initializes an instance of `FiniteStateMachine`."""
|
|
417
|
-
self._deps_type = deps_type
|
|
313
|
+
deps_type: type[DepsT]
|
|
314
|
+
"""The type of the dependencies for the FSM."""
|
|
418
315
|
|
|
419
|
-
|
|
316
|
+
@contextmanager
|
|
317
|
+
def context(self, *, deps: DepsT) -> Iterator[RunContext[DepsT]]:
|
|
420
318
|
"""Creates a context manager for the FSM that handles both sync and async.
|
|
421
319
|
|
|
422
320
|
This method returns an instance of FSMContextManager which can be used with both
|
|
@@ -426,6 +324,16 @@ class FiniteStateMachine(Generic[_DepsT]):
|
|
|
426
324
|
async code, allowing context to be maintained across await points and between
|
|
427
325
|
nodes so long as each node is called within the context.
|
|
428
326
|
|
|
327
|
+
NOTE: This simplified implementation has some limitations with complex nested
|
|
328
|
+
async calls across context boundaries. For nested nodes calling other nodes
|
|
329
|
+
asynchronously after a context exit, the context may not be properly preserved.
|
|
330
|
+
In these cases, using a compiled machine is recommended.
|
|
331
|
+
|
|
332
|
+
NOTE: We implement stubs using the sync case because the async case is currently
|
|
333
|
+
the same and does not require separate implementations. In the future we may update
|
|
334
|
+
this to handle more complex async cases where the context e.g. pulls from an
|
|
335
|
+
external source or something.
|
|
336
|
+
|
|
429
337
|
Example:
|
|
430
338
|
|
|
431
339
|
Synchronous usage:
|
|
@@ -448,10 +356,14 @@ class FiniteStateMachine(Generic[_DepsT]):
|
|
|
448
356
|
Returns:
|
|
449
357
|
An FSMContextManager instance that supports both `with` and `async with`.
|
|
450
358
|
"""
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
359
|
+
context = RunContext(deps=deps)
|
|
360
|
+
token = FSM_CONTEXT.set(context)
|
|
361
|
+
try:
|
|
362
|
+
yield context
|
|
363
|
+
finally:
|
|
364
|
+
FSM_CONTEXT.reset(token)
|
|
365
|
+
|
|
366
|
+
def node(self) -> NodeDecorator[DepsT]:
|
|
455
367
|
"""Registers the given function as a node in the FSM.
|
|
456
368
|
|
|
457
369
|
This decorator transforms a function that requires a RunContext as its first
|
|
@@ -473,22 +385,22 @@ class FiniteStateMachine(Generic[_DepsT]):
|
|
|
473
385
|
|
|
474
386
|
@overload
|
|
475
387
|
def decorator(
|
|
476
|
-
fn: NodeDecoratedFunction[_P, Coroutine[Any, Any, _R],
|
|
388
|
+
fn: NodeDecoratedFunction[_P, Coroutine[Any, Any, _R], DepsT],
|
|
477
389
|
) -> Callable[_P, Coroutine[Any, Any, _R]]: ...
|
|
478
390
|
|
|
479
391
|
@overload
|
|
480
392
|
def decorator(
|
|
481
|
-
fn: NodeDecoratedFunction[_P, _R,
|
|
393
|
+
fn: NodeDecoratedFunction[_P, _R, DepsT],
|
|
482
394
|
) -> Callable[_P, _R]: ...
|
|
483
395
|
|
|
484
396
|
def decorator(
|
|
485
|
-
fn: NodeDecoratedFunction[_P, _R | Coroutine[Any, Any, _R],
|
|
397
|
+
fn: NodeDecoratedFunction[_P, _R | Coroutine[Any, Any, _R], DepsT],
|
|
486
398
|
) -> Callable[_P, _R | Coroutine[Any, Any, _R]]:
|
|
487
399
|
@wraps(fn)
|
|
488
400
|
def context_wrapper(
|
|
489
401
|
*args: _P.args, **kwargs: _P.kwargs
|
|
490
402
|
) -> _R | Coroutine[Any, Any, _R]:
|
|
491
|
-
context =
|
|
403
|
+
context = FSM_CONTEXT.get()
|
|
492
404
|
if context is None:
|
|
493
405
|
raise FSMContextError(
|
|
494
406
|
f"Node `{fn.__name__}` called outside of a context manager. "
|
|
@@ -500,8 +412,7 @@ class FiniteStateMachine(Generic[_DepsT]):
|
|
|
500
412
|
# context management inside so we handle contextvars correctly
|
|
501
413
|
@wraps(fn)
|
|
502
414
|
async def inner_async() -> _R:
|
|
503
|
-
|
|
504
|
-
return await fn(context, *args, **kwargs) # pyright: ignore [reportGeneralTypeIssues]
|
|
415
|
+
return await fn(context, *args, **kwargs) # pyright: ignore [reportGeneralTypeIssues]
|
|
505
416
|
|
|
506
417
|
return inner_async()
|
|
507
418
|
|
|
@@ -515,8 +426,8 @@ class FiniteStateMachine(Generic[_DepsT]):
|
|
|
515
426
|
self,
|
|
516
427
|
start: Callable[_P, _R],
|
|
517
428
|
*,
|
|
518
|
-
deps:
|
|
519
|
-
) -> "CompiledMachine[_P, _R,
|
|
429
|
+
deps: DepsT = None,
|
|
430
|
+
) -> "CompiledMachine[_P, _R, DepsT]":
|
|
520
431
|
"""Returns the compiled FSM.
|
|
521
432
|
|
|
522
433
|
Compiles the FSM and returns a CompiledMachine that can be used to run the FSM.
|
|
@@ -533,7 +444,7 @@ class FiniteStateMachine(Generic[_DepsT]):
|
|
|
533
444
|
return CompiledMachine(fsm=self, start=start, deps=deps)
|
|
534
445
|
|
|
535
446
|
|
|
536
|
-
class CompiledMachine(Generic[_P, _R,
|
|
447
|
+
class CompiledMachine(Generic[_P, _R, DepsT]):
|
|
537
448
|
"""The compiled Finite State Machine (FSM).
|
|
538
449
|
|
|
539
450
|
This class represents a compiled FSM that can be run with a specific start function.
|
|
@@ -546,16 +457,16 @@ class CompiledMachine(Generic[_P, _R, _DepsT]):
|
|
|
546
457
|
deps: The dependencies for the FSM.
|
|
547
458
|
"""
|
|
548
459
|
|
|
549
|
-
fsm: FiniteStateMachine[
|
|
460
|
+
fsm: FiniteStateMachine[DepsT]
|
|
550
461
|
start: Callable[_P, _R]
|
|
551
|
-
deps:
|
|
462
|
+
deps: DepsT
|
|
552
463
|
|
|
553
464
|
def __init__(
|
|
554
465
|
self,
|
|
555
466
|
*,
|
|
556
|
-
fsm: FiniteStateMachine[
|
|
467
|
+
fsm: FiniteStateMachine[DepsT],
|
|
557
468
|
start: Callable[_P, _R],
|
|
558
|
-
deps:
|
|
469
|
+
deps: DepsT = None,
|
|
559
470
|
) -> None:
|
|
560
471
|
"""Initializes an instance of `CompiledMachine`."""
|
|
561
472
|
self.fsm = fsm
|
|
@@ -615,7 +526,7 @@ class CompiledMachine(Generic[_P, _R, _DepsT]):
|
|
|
615
526
|
called outside of a context manager.
|
|
616
527
|
RuntimeError: If called with a sync function as the start function.
|
|
617
528
|
"""
|
|
618
|
-
|
|
529
|
+
with self.fsm.context(deps=self.deps):
|
|
619
530
|
result = self.start(*args, **kwargs)
|
|
620
531
|
if inspect.isawaitable(result):
|
|
621
532
|
return await result
|
|
@@ -687,13 +598,13 @@ async def main() -> None:
|
|
|
687
598
|
|
|
688
599
|
# Example 3.5: Using asynchronous context with async functions within boundaries
|
|
689
600
|
print("\nExample 3.5: Asynchronous context with async functions")
|
|
690
|
-
|
|
601
|
+
with fsm.context(deps=Deps(0)):
|
|
691
602
|
operations = await async_reach_zero(5, 3)
|
|
692
603
|
print(f"Async operations in async context: {operations}")
|
|
693
604
|
|
|
694
605
|
# Example 4: Demonstrate context preservation across await boundaries
|
|
695
606
|
print("\nContext preservation example:")
|
|
696
|
-
|
|
607
|
+
with fsm.context(deps=Deps(0)):
|
|
697
608
|
# Create the coroutine task inside the context
|
|
698
609
|
operations_task = async_reach_zero(5, 3)
|
|
699
610
|
print("Task created inside context manager")
|