mirascope 1.25.7__py3-none-any.whl → 2.0.0a0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mirascope/__init__.py +3 -59
- mirascope/graphs/__init__.py +22 -0
- mirascope/{experimental/graphs → graphs}/finite_state_machine.py +70 -159
- mirascope/llm/__init__.py +206 -16
- mirascope/llm/agents/__init__.py +15 -0
- mirascope/llm/agents/agent.py +97 -0
- mirascope/llm/agents/agent_template.py +45 -0
- mirascope/llm/agents/decorator.py +176 -0
- mirascope/llm/calls/__init__.py +16 -0
- mirascope/llm/calls/base_call.py +33 -0
- mirascope/llm/calls/calls.py +315 -0
- mirascope/llm/calls/decorator.py +255 -0
- mirascope/llm/clients/__init__.py +34 -0
- mirascope/llm/clients/anthropic/__init__.py +11 -0
- mirascope/llm/clients/anthropic/_utils/__init__.py +13 -0
- mirascope/llm/clients/anthropic/_utils/decode.py +244 -0
- mirascope/llm/clients/anthropic/_utils/encode.py +243 -0
- mirascope/llm/clients/anthropic/clients.py +819 -0
- mirascope/llm/clients/anthropic/model_ids.py +8 -0
- mirascope/llm/clients/base/__init__.py +15 -0
- mirascope/llm/clients/base/_utils.py +192 -0
- mirascope/llm/clients/base/client.py +1256 -0
- mirascope/llm/clients/base/kwargs.py +12 -0
- mirascope/llm/clients/base/params.py +93 -0
- mirascope/llm/clients/google/__init__.py +6 -0
- mirascope/llm/clients/google/_utils/__init__.py +13 -0
- mirascope/llm/clients/google/_utils/decode.py +231 -0
- mirascope/llm/clients/google/_utils/encode.py +279 -0
- mirascope/llm/clients/google/clients.py +853 -0
- mirascope/llm/clients/google/message.py +7 -0
- mirascope/llm/clients/google/model_ids.py +15 -0
- mirascope/llm/clients/openai/__init__.py +25 -0
- mirascope/llm/clients/openai/completions/__init__.py +9 -0
- mirascope/llm/clients/openai/completions/_utils/__init__.py +13 -0
- mirascope/llm/clients/openai/completions/_utils/decode.py +187 -0
- mirascope/llm/clients/openai/completions/_utils/encode.py +358 -0
- mirascope/llm/clients/openai/completions/_utils/model_features.py +81 -0
- mirascope/llm/clients/openai/completions/clients.py +833 -0
- mirascope/llm/clients/openai/completions/model_ids.py +8 -0
- mirascope/llm/clients/openai/responses/__init__.py +9 -0
- mirascope/llm/clients/openai/responses/_utils/__init__.py +13 -0
- mirascope/llm/clients/openai/responses/_utils/decode.py +194 -0
- mirascope/llm/clients/openai/responses/_utils/encode.py +333 -0
- mirascope/llm/clients/openai/responses/_utils/model_features.py +87 -0
- mirascope/llm/clients/openai/responses/clients.py +832 -0
- mirascope/llm/clients/openai/responses/model_ids.py +8 -0
- mirascope/llm/clients/openai/shared/__init__.py +7 -0
- mirascope/llm/clients/openai/shared/_utils.py +55 -0
- mirascope/llm/clients/providers.py +175 -0
- mirascope/llm/content/__init__.py +70 -0
- mirascope/llm/content/audio.py +173 -0
- mirascope/llm/content/document.py +94 -0
- mirascope/llm/content/image.py +206 -0
- mirascope/llm/content/text.py +47 -0
- mirascope/llm/content/thought.py +58 -0
- mirascope/llm/content/tool_call.py +63 -0
- mirascope/llm/content/tool_output.py +26 -0
- mirascope/llm/context/__init__.py +6 -0
- mirascope/llm/context/_utils.py +28 -0
- mirascope/llm/context/context.py +24 -0
- mirascope/llm/exceptions.py +105 -0
- mirascope/llm/formatting/__init__.py +22 -0
- mirascope/llm/formatting/_utils.py +74 -0
- mirascope/llm/formatting/format.py +104 -0
- mirascope/llm/formatting/from_call_args.py +30 -0
- mirascope/llm/formatting/partial.py +58 -0
- mirascope/llm/formatting/types.py +109 -0
- mirascope/llm/mcp/__init__.py +5 -0
- mirascope/llm/mcp/client.py +118 -0
- mirascope/llm/messages/__init__.py +32 -0
- mirascope/llm/messages/message.py +182 -0
- mirascope/llm/models/__init__.py +16 -0
- mirascope/llm/models/models.py +1243 -0
- mirascope/llm/prompts/__init__.py +33 -0
- mirascope/llm/prompts/_utils.py +60 -0
- mirascope/llm/prompts/decorator.py +286 -0
- mirascope/llm/prompts/protocols.py +99 -0
- mirascope/llm/responses/__init__.py +57 -0
- mirascope/llm/responses/_utils.py +56 -0
- mirascope/llm/responses/base_response.py +91 -0
- mirascope/llm/responses/base_stream_response.py +697 -0
- mirascope/llm/responses/finish_reason.py +27 -0
- mirascope/llm/responses/response.py +345 -0
- mirascope/llm/responses/root_response.py +177 -0
- mirascope/llm/responses/stream_response.py +572 -0
- mirascope/llm/responses/streams.py +363 -0
- mirascope/llm/tools/__init__.py +40 -0
- mirascope/llm/tools/_utils.py +25 -0
- mirascope/llm/tools/decorator.py +175 -0
- mirascope/llm/tools/protocols.py +96 -0
- mirascope/llm/tools/tool_schema.py +246 -0
- mirascope/llm/tools/toolkit.py +152 -0
- mirascope/llm/tools/tools.py +169 -0
- mirascope/llm/types/__init__.py +22 -0
- mirascope/llm/types/dataclass.py +9 -0
- mirascope/llm/types/jsonable.py +44 -0
- mirascope/llm/types/type_vars.py +19 -0
- mirascope-2.0.0a0.dist-info/METADATA +117 -0
- mirascope-2.0.0a0.dist-info/RECORD +101 -0
- mirascope/beta/__init__.py +0 -3
- mirascope/beta/openai/__init__.py +0 -17
- mirascope/beta/openai/realtime/__init__.py +0 -13
- mirascope/beta/openai/realtime/_utils/__init__.py +0 -3
- mirascope/beta/openai/realtime/_utils/_audio.py +0 -74
- mirascope/beta/openai/realtime/_utils/_protocols.py +0 -50
- mirascope/beta/openai/realtime/realtime.py +0 -500
- mirascope/beta/openai/realtime/recording.py +0 -98
- mirascope/beta/openai/realtime/tool.py +0 -113
- mirascope/beta/rag/__init__.py +0 -24
- mirascope/beta/rag/base/__init__.py +0 -22
- mirascope/beta/rag/base/chunkers/__init__.py +0 -2
- mirascope/beta/rag/base/chunkers/base_chunker.py +0 -37
- mirascope/beta/rag/base/chunkers/text_chunker.py +0 -33
- mirascope/beta/rag/base/config.py +0 -8
- mirascope/beta/rag/base/document.py +0 -11
- mirascope/beta/rag/base/embedders.py +0 -35
- mirascope/beta/rag/base/embedding_params.py +0 -18
- mirascope/beta/rag/base/embedding_response.py +0 -30
- mirascope/beta/rag/base/query_results.py +0 -7
- mirascope/beta/rag/base/vectorstore_params.py +0 -18
- mirascope/beta/rag/base/vectorstores.py +0 -37
- mirascope/beta/rag/chroma/__init__.py +0 -11
- mirascope/beta/rag/chroma/types.py +0 -62
- mirascope/beta/rag/chroma/vectorstores.py +0 -121
- mirascope/beta/rag/cohere/__init__.py +0 -11
- mirascope/beta/rag/cohere/embedders.py +0 -87
- mirascope/beta/rag/cohere/embedding_params.py +0 -29
- mirascope/beta/rag/cohere/embedding_response.py +0 -29
- mirascope/beta/rag/cohere/py.typed +0 -0
- mirascope/beta/rag/openai/__init__.py +0 -11
- mirascope/beta/rag/openai/embedders.py +0 -144
- mirascope/beta/rag/openai/embedding_params.py +0 -18
- mirascope/beta/rag/openai/embedding_response.py +0 -14
- mirascope/beta/rag/openai/py.typed +0 -0
- mirascope/beta/rag/pinecone/__init__.py +0 -19
- mirascope/beta/rag/pinecone/types.py +0 -143
- mirascope/beta/rag/pinecone/vectorstores.py +0 -148
- mirascope/beta/rag/weaviate/__init__.py +0 -6
- mirascope/beta/rag/weaviate/types.py +0 -92
- mirascope/beta/rag/weaviate/vectorstores.py +0 -103
- mirascope/core/__init__.py +0 -109
- mirascope/core/anthropic/__init__.py +0 -31
- mirascope/core/anthropic/_call.py +0 -67
- mirascope/core/anthropic/_call_kwargs.py +0 -13
- mirascope/core/anthropic/_thinking.py +0 -70
- mirascope/core/anthropic/_utils/__init__.py +0 -16
- mirascope/core/anthropic/_utils/_convert_common_call_params.py +0 -25
- mirascope/core/anthropic/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -21
- mirascope/core/anthropic/_utils/_convert_message_params.py +0 -102
- mirascope/core/anthropic/_utils/_get_json_output.py +0 -31
- mirascope/core/anthropic/_utils/_handle_stream.py +0 -113
- mirascope/core/anthropic/_utils/_message_param_converter.py +0 -154
- mirascope/core/anthropic/_utils/_setup_call.py +0 -146
- mirascope/core/anthropic/call_params.py +0 -44
- mirascope/core/anthropic/call_response.py +0 -226
- mirascope/core/anthropic/call_response_chunk.py +0 -152
- mirascope/core/anthropic/dynamic_config.py +0 -40
- mirascope/core/anthropic/py.typed +0 -0
- mirascope/core/anthropic/stream.py +0 -204
- mirascope/core/anthropic/tool.py +0 -101
- mirascope/core/azure/__init__.py +0 -31
- mirascope/core/azure/_call.py +0 -67
- mirascope/core/azure/_call_kwargs.py +0 -13
- mirascope/core/azure/_utils/__init__.py +0 -14
- mirascope/core/azure/_utils/_convert_common_call_params.py +0 -26
- mirascope/core/azure/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -21
- mirascope/core/azure/_utils/_convert_message_params.py +0 -121
- mirascope/core/azure/_utils/_get_credential.py +0 -33
- mirascope/core/azure/_utils/_get_json_output.py +0 -27
- mirascope/core/azure/_utils/_handle_stream.py +0 -130
- mirascope/core/azure/_utils/_message_param_converter.py +0 -117
- mirascope/core/azure/_utils/_setup_call.py +0 -183
- mirascope/core/azure/call_params.py +0 -59
- mirascope/core/azure/call_response.py +0 -215
- mirascope/core/azure/call_response_chunk.py +0 -105
- mirascope/core/azure/dynamic_config.py +0 -30
- mirascope/core/azure/py.typed +0 -0
- mirascope/core/azure/stream.py +0 -147
- mirascope/core/azure/tool.py +0 -93
- mirascope/core/base/__init__.py +0 -86
- mirascope/core/base/_call_factory.py +0 -256
- mirascope/core/base/_create.py +0 -253
- mirascope/core/base/_extract.py +0 -175
- mirascope/core/base/_extract_with_tools.py +0 -189
- mirascope/core/base/_partial.py +0 -95
- mirascope/core/base/_utils/__init__.py +0 -92
- mirascope/core/base/_utils/_base_message_param_converter.py +0 -22
- mirascope/core/base/_utils/_base_type.py +0 -26
- mirascope/core/base/_utils/_convert_base_model_to_base_tool.py +0 -48
- mirascope/core/base/_utils/_convert_base_type_to_base_tool.py +0 -24
- mirascope/core/base/_utils/_convert_function_to_base_tool.py +0 -139
- mirascope/core/base/_utils/_convert_messages_to_message_params.py +0 -178
- mirascope/core/base/_utils/_convert_provider_finish_reason_to_finish_reason.py +0 -20
- mirascope/core/base/_utils/_default_tool_docstring.py +0 -6
- mirascope/core/base/_utils/_extract_tool_return.py +0 -42
- mirascope/core/base/_utils/_fn_is_async.py +0 -24
- mirascope/core/base/_utils/_format_template.py +0 -32
- mirascope/core/base/_utils/_get_audio_type.py +0 -18
- mirascope/core/base/_utils/_get_common_usage.py +0 -20
- mirascope/core/base/_utils/_get_create_fn_or_async_create_fn.py +0 -137
- mirascope/core/base/_utils/_get_document_type.py +0 -7
- mirascope/core/base/_utils/_get_dynamic_configuration.py +0 -69
- mirascope/core/base/_utils/_get_fields_from_call_args.py +0 -34
- mirascope/core/base/_utils/_get_fn_args.py +0 -23
- mirascope/core/base/_utils/_get_image_dimensions.py +0 -39
- mirascope/core/base/_utils/_get_image_type.py +0 -26
- mirascope/core/base/_utils/_get_metadata.py +0 -17
- mirascope/core/base/_utils/_get_possible_user_message_param.py +0 -21
- mirascope/core/base/_utils/_get_prompt_template.py +0 -28
- mirascope/core/base/_utils/_get_template_values.py +0 -51
- mirascope/core/base/_utils/_get_template_variables.py +0 -38
- mirascope/core/base/_utils/_get_unsupported_tool_config_keys.py +0 -10
- mirascope/core/base/_utils/_is_prompt_template.py +0 -24
- mirascope/core/base/_utils/_json_mode_content.py +0 -17
- mirascope/core/base/_utils/_messages_decorator.py +0 -121
- mirascope/core/base/_utils/_parse_content_template.py +0 -323
- mirascope/core/base/_utils/_parse_prompt_messages.py +0 -63
- mirascope/core/base/_utils/_pil_image_to_bytes.py +0 -13
- mirascope/core/base/_utils/_protocols.py +0 -901
- mirascope/core/base/_utils/_setup_call.py +0 -79
- mirascope/core/base/_utils/_setup_extract_tool.py +0 -30
- mirascope/core/base/call_kwargs.py +0 -13
- mirascope/core/base/call_params.py +0 -36
- mirascope/core/base/call_response.py +0 -338
- mirascope/core/base/call_response_chunk.py +0 -130
- mirascope/core/base/dynamic_config.py +0 -82
- mirascope/core/base/from_call_args.py +0 -30
- mirascope/core/base/merge_decorators.py +0 -59
- mirascope/core/base/message_param.py +0 -175
- mirascope/core/base/messages.py +0 -116
- mirascope/core/base/metadata.py +0 -13
- mirascope/core/base/prompt.py +0 -497
- mirascope/core/base/response_model_config_dict.py +0 -9
- mirascope/core/base/stream.py +0 -479
- mirascope/core/base/stream_config.py +0 -11
- mirascope/core/base/structured_stream.py +0 -296
- mirascope/core/base/tool.py +0 -214
- mirascope/core/base/toolkit.py +0 -176
- mirascope/core/base/types.py +0 -344
- mirascope/core/bedrock/__init__.py +0 -34
- mirascope/core/bedrock/_call.py +0 -68
- mirascope/core/bedrock/_call_kwargs.py +0 -12
- mirascope/core/bedrock/_types.py +0 -104
- mirascope/core/bedrock/_utils/__init__.py +0 -14
- mirascope/core/bedrock/_utils/_convert_common_call_params.py +0 -39
- mirascope/core/bedrock/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -23
- mirascope/core/bedrock/_utils/_convert_message_params.py +0 -111
- mirascope/core/bedrock/_utils/_get_json_output.py +0 -30
- mirascope/core/bedrock/_utils/_handle_stream.py +0 -104
- mirascope/core/bedrock/_utils/_message_param_converter.py +0 -172
- mirascope/core/bedrock/_utils/_setup_call.py +0 -258
- mirascope/core/bedrock/call_params.py +0 -38
- mirascope/core/bedrock/call_response.py +0 -248
- mirascope/core/bedrock/call_response_chunk.py +0 -111
- mirascope/core/bedrock/dynamic_config.py +0 -37
- mirascope/core/bedrock/py.typed +0 -0
- mirascope/core/bedrock/stream.py +0 -154
- mirascope/core/bedrock/tool.py +0 -100
- mirascope/core/cohere/__init__.py +0 -30
- mirascope/core/cohere/_call.py +0 -67
- mirascope/core/cohere/_call_kwargs.py +0 -11
- mirascope/core/cohere/_types.py +0 -20
- mirascope/core/cohere/_utils/__init__.py +0 -14
- mirascope/core/cohere/_utils/_convert_common_call_params.py +0 -26
- mirascope/core/cohere/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -24
- mirascope/core/cohere/_utils/_convert_message_params.py +0 -32
- mirascope/core/cohere/_utils/_get_json_output.py +0 -30
- mirascope/core/cohere/_utils/_handle_stream.py +0 -35
- mirascope/core/cohere/_utils/_message_param_converter.py +0 -54
- mirascope/core/cohere/_utils/_setup_call.py +0 -150
- mirascope/core/cohere/call_params.py +0 -62
- mirascope/core/cohere/call_response.py +0 -205
- mirascope/core/cohere/call_response_chunk.py +0 -125
- mirascope/core/cohere/dynamic_config.py +0 -32
- mirascope/core/cohere/py.typed +0 -0
- mirascope/core/cohere/stream.py +0 -113
- mirascope/core/cohere/tool.py +0 -93
- mirascope/core/costs/__init__.py +0 -5
- mirascope/core/costs/_anthropic_calculate_cost.py +0 -219
- mirascope/core/costs/_azure_calculate_cost.py +0 -11
- mirascope/core/costs/_bedrock_calculate_cost.py +0 -15
- mirascope/core/costs/_cohere_calculate_cost.py +0 -44
- mirascope/core/costs/_gemini_calculate_cost.py +0 -67
- mirascope/core/costs/_google_calculate_cost.py +0 -427
- mirascope/core/costs/_groq_calculate_cost.py +0 -156
- mirascope/core/costs/_litellm_calculate_cost.py +0 -11
- mirascope/core/costs/_mistral_calculate_cost.py +0 -64
- mirascope/core/costs/_openai_calculate_cost.py +0 -416
- mirascope/core/costs/_vertex_calculate_cost.py +0 -67
- mirascope/core/costs/_xai_calculate_cost.py +0 -104
- mirascope/core/costs/calculate_cost.py +0 -86
- mirascope/core/gemini/__init__.py +0 -40
- mirascope/core/gemini/_call.py +0 -67
- mirascope/core/gemini/_call_kwargs.py +0 -12
- mirascope/core/gemini/_utils/__init__.py +0 -14
- mirascope/core/gemini/_utils/_convert_common_call_params.py +0 -39
- mirascope/core/gemini/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -23
- mirascope/core/gemini/_utils/_convert_message_params.py +0 -156
- mirascope/core/gemini/_utils/_get_json_output.py +0 -35
- mirascope/core/gemini/_utils/_handle_stream.py +0 -33
- mirascope/core/gemini/_utils/_message_param_converter.py +0 -209
- mirascope/core/gemini/_utils/_setup_call.py +0 -149
- mirascope/core/gemini/call_params.py +0 -52
- mirascope/core/gemini/call_response.py +0 -216
- mirascope/core/gemini/call_response_chunk.py +0 -100
- mirascope/core/gemini/dynamic_config.py +0 -26
- mirascope/core/gemini/stream.py +0 -120
- mirascope/core/gemini/tool.py +0 -104
- mirascope/core/google/__init__.py +0 -29
- mirascope/core/google/_call.py +0 -67
- mirascope/core/google/_call_kwargs.py +0 -13
- mirascope/core/google/_utils/__init__.py +0 -14
- mirascope/core/google/_utils/_convert_common_call_params.py +0 -38
- mirascope/core/google/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -27
- mirascope/core/google/_utils/_convert_message_params.py +0 -297
- mirascope/core/google/_utils/_get_json_output.py +0 -37
- mirascope/core/google/_utils/_handle_stream.py +0 -58
- mirascope/core/google/_utils/_message_param_converter.py +0 -200
- mirascope/core/google/_utils/_setup_call.py +0 -201
- mirascope/core/google/_utils/_validate_media_type.py +0 -58
- mirascope/core/google/call_params.py +0 -22
- mirascope/core/google/call_response.py +0 -255
- mirascope/core/google/call_response_chunk.py +0 -135
- mirascope/core/google/dynamic_config.py +0 -26
- mirascope/core/google/stream.py +0 -199
- mirascope/core/google/tool.py +0 -146
- mirascope/core/groq/__init__.py +0 -30
- mirascope/core/groq/_call.py +0 -67
- mirascope/core/groq/_call_kwargs.py +0 -13
- mirascope/core/groq/_utils/__init__.py +0 -14
- mirascope/core/groq/_utils/_convert_common_call_params.py +0 -26
- mirascope/core/groq/_utils/_convert_message_params.py +0 -112
- mirascope/core/groq/_utils/_get_json_output.py +0 -27
- mirascope/core/groq/_utils/_handle_stream.py +0 -123
- mirascope/core/groq/_utils/_message_param_converter.py +0 -89
- mirascope/core/groq/_utils/_setup_call.py +0 -132
- mirascope/core/groq/call_params.py +0 -52
- mirascope/core/groq/call_response.py +0 -213
- mirascope/core/groq/call_response_chunk.py +0 -104
- mirascope/core/groq/dynamic_config.py +0 -29
- mirascope/core/groq/py.typed +0 -0
- mirascope/core/groq/stream.py +0 -135
- mirascope/core/groq/tool.py +0 -80
- mirascope/core/litellm/__init__.py +0 -28
- mirascope/core/litellm/_call.py +0 -67
- mirascope/core/litellm/_utils/__init__.py +0 -5
- mirascope/core/litellm/_utils/_setup_call.py +0 -109
- mirascope/core/litellm/call_params.py +0 -10
- mirascope/core/litellm/call_response.py +0 -24
- mirascope/core/litellm/call_response_chunk.py +0 -14
- mirascope/core/litellm/dynamic_config.py +0 -8
- mirascope/core/litellm/py.typed +0 -0
- mirascope/core/litellm/stream.py +0 -86
- mirascope/core/litellm/tool.py +0 -13
- mirascope/core/mistral/__init__.py +0 -36
- mirascope/core/mistral/_call.py +0 -65
- mirascope/core/mistral/_call_kwargs.py +0 -19
- mirascope/core/mistral/_utils/__init__.py +0 -14
- mirascope/core/mistral/_utils/_convert_common_call_params.py +0 -24
- mirascope/core/mistral/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -22
- mirascope/core/mistral/_utils/_convert_message_params.py +0 -122
- mirascope/core/mistral/_utils/_get_json_output.py +0 -34
- mirascope/core/mistral/_utils/_handle_stream.py +0 -139
- mirascope/core/mistral/_utils/_message_param_converter.py +0 -176
- mirascope/core/mistral/_utils/_setup_call.py +0 -164
- mirascope/core/mistral/call_params.py +0 -36
- mirascope/core/mistral/call_response.py +0 -205
- mirascope/core/mistral/call_response_chunk.py +0 -105
- mirascope/core/mistral/dynamic_config.py +0 -33
- mirascope/core/mistral/py.typed +0 -0
- mirascope/core/mistral/stream.py +0 -120
- mirascope/core/mistral/tool.py +0 -81
- mirascope/core/openai/__init__.py +0 -31
- mirascope/core/openai/_call.py +0 -67
- mirascope/core/openai/_call_kwargs.py +0 -13
- mirascope/core/openai/_utils/__init__.py +0 -14
- mirascope/core/openai/_utils/_convert_common_call_params.py +0 -26
- mirascope/core/openai/_utils/_convert_message_params.py +0 -148
- mirascope/core/openai/_utils/_get_json_output.py +0 -31
- mirascope/core/openai/_utils/_handle_stream.py +0 -138
- mirascope/core/openai/_utils/_message_param_converter.py +0 -105
- mirascope/core/openai/_utils/_setup_call.py +0 -155
- mirascope/core/openai/call_params.py +0 -92
- mirascope/core/openai/call_response.py +0 -273
- mirascope/core/openai/call_response_chunk.py +0 -139
- mirascope/core/openai/dynamic_config.py +0 -34
- mirascope/core/openai/py.typed +0 -0
- mirascope/core/openai/stream.py +0 -185
- mirascope/core/openai/tool.py +0 -101
- mirascope/core/py.typed +0 -0
- mirascope/core/vertex/__init__.py +0 -45
- mirascope/core/vertex/_call.py +0 -62
- mirascope/core/vertex/_call_kwargs.py +0 -12
- mirascope/core/vertex/_utils/__init__.py +0 -14
- mirascope/core/vertex/_utils/_convert_common_call_params.py +0 -37
- mirascope/core/vertex/_utils/_convert_finish_reason_to_common_finish_reasons.py +0 -23
- mirascope/core/vertex/_utils/_convert_message_params.py +0 -171
- mirascope/core/vertex/_utils/_get_json_output.py +0 -36
- mirascope/core/vertex/_utils/_handle_stream.py +0 -33
- mirascope/core/vertex/_utils/_message_param_converter.py +0 -133
- mirascope/core/vertex/_utils/_setup_call.py +0 -160
- mirascope/core/vertex/call_params.py +0 -24
- mirascope/core/vertex/call_response.py +0 -206
- mirascope/core/vertex/call_response_chunk.py +0 -99
- mirascope/core/vertex/dynamic_config.py +0 -28
- mirascope/core/vertex/stream.py +0 -119
- mirascope/core/vertex/tool.py +0 -101
- mirascope/core/xai/__init__.py +0 -28
- mirascope/core/xai/_call.py +0 -67
- mirascope/core/xai/_utils/__init__.py +0 -5
- mirascope/core/xai/_utils/_setup_call.py +0 -113
- mirascope/core/xai/call_params.py +0 -10
- mirascope/core/xai/call_response.py +0 -16
- mirascope/core/xai/call_response_chunk.py +0 -14
- mirascope/core/xai/dynamic_config.py +0 -8
- mirascope/core/xai/py.typed +0 -0
- mirascope/core/xai/stream.py +0 -57
- mirascope/core/xai/tool.py +0 -13
- mirascope/experimental/graphs/__init__.py +0 -5
- mirascope/integrations/__init__.py +0 -16
- mirascope/integrations/_middleware_factory.py +0 -403
- mirascope/integrations/langfuse/__init__.py +0 -3
- mirascope/integrations/langfuse/_utils.py +0 -114
- mirascope/integrations/langfuse/_with_langfuse.py +0 -70
- mirascope/integrations/logfire/__init__.py +0 -3
- mirascope/integrations/logfire/_utils.py +0 -225
- mirascope/integrations/logfire/_with_logfire.py +0 -63
- mirascope/integrations/otel/__init__.py +0 -10
- mirascope/integrations/otel/_utils.py +0 -270
- mirascope/integrations/otel/_with_hyperdx.py +0 -60
- mirascope/integrations/otel/_with_otel.py +0 -59
- mirascope/integrations/tenacity.py +0 -14
- mirascope/llm/_call.py +0 -401
- mirascope/llm/_context.py +0 -384
- mirascope/llm/_override.py +0 -3639
- mirascope/llm/_protocols.py +0 -500
- mirascope/llm/_response_metaclass.py +0 -31
- mirascope/llm/call_response.py +0 -158
- mirascope/llm/call_response_chunk.py +0 -66
- mirascope/llm/stream.py +0 -162
- mirascope/llm/tool.py +0 -64
- mirascope/mcp/__init__.py +0 -7
- mirascope/mcp/_utils.py +0 -288
- mirascope/mcp/client.py +0 -167
- mirascope/mcp/server.py +0 -356
- mirascope/mcp/tools.py +0 -110
- mirascope/py.typed +0 -0
- mirascope/retries/__init__.py +0 -11
- mirascope/retries/fallback.py +0 -131
- mirascope/retries/tenacity.py +0 -50
- mirascope/tools/__init__.py +0 -37
- mirascope/tools/base.py +0 -98
- mirascope/tools/system/__init__.py +0 -0
- mirascope/tools/system/_docker_operation.py +0 -166
- mirascope/tools/system/_file_system.py +0 -267
- mirascope/tools/web/__init__.py +0 -0
- mirascope/tools/web/_duckduckgo.py +0 -111
- mirascope/tools/web/_httpx.py +0 -125
- mirascope/tools/web/_parse_url_content.py +0 -94
- mirascope/tools/web/_requests.py +0 -54
- mirascope/v0/__init__.py +0 -43
- mirascope/v0/anthropic.py +0 -54
- mirascope/v0/base/__init__.py +0 -12
- mirascope/v0/base/calls.py +0 -118
- mirascope/v0/base/extractors.py +0 -122
- mirascope/v0/base/ops_utils.py +0 -207
- mirascope/v0/base/prompts.py +0 -48
- mirascope/v0/base/types.py +0 -14
- mirascope/v0/base/utils.py +0 -21
- mirascope/v0/openai.py +0 -54
- mirascope-1.25.7.dist-info/METADATA +0 -169
- mirascope-1.25.7.dist-info/RECORD +0 -378
- {mirascope-1.25.7.dist-info → mirascope-2.0.0a0.dist-info}/WHEEL +0 -0
- {mirascope-1.25.7.dist-info → mirascope-2.0.0a0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""The prompt templates module for LLM interactions.
|
|
2
|
+
|
|
3
|
+
This module defines the prompt templates used in LLM interactions, which are written as
|
|
4
|
+
python functions.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from . import _utils
|
|
8
|
+
from .decorator import prompt
|
|
9
|
+
from .protocols import (
|
|
10
|
+
AsyncContextPrompt,
|
|
11
|
+
AsyncContextPromptable,
|
|
12
|
+
AsyncPrompt,
|
|
13
|
+
AsyncPromptable,
|
|
14
|
+
ContextPrompt,
|
|
15
|
+
ContextPromptable,
|
|
16
|
+
Prompt,
|
|
17
|
+
Promptable,
|
|
18
|
+
PromptT,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
__all__ = [
|
|
22
|
+
"AsyncContextPrompt",
|
|
23
|
+
"AsyncContextPromptable",
|
|
24
|
+
"AsyncPrompt",
|
|
25
|
+
"AsyncPromptable",
|
|
26
|
+
"ContextPrompt",
|
|
27
|
+
"ContextPromptable",
|
|
28
|
+
"Prompt",
|
|
29
|
+
"PromptT",
|
|
30
|
+
"Promptable",
|
|
31
|
+
"_utils",
|
|
32
|
+
"prompt",
|
|
33
|
+
]
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import inspect
|
|
2
|
+
from typing_extensions import TypeIs
|
|
3
|
+
|
|
4
|
+
from ..context import DepsT, _utils as _context_utils
|
|
5
|
+
from ..messages import (
|
|
6
|
+
AssistantMessage,
|
|
7
|
+
Message,
|
|
8
|
+
SystemMessage,
|
|
9
|
+
UserContent,
|
|
10
|
+
UserMessage,
|
|
11
|
+
user,
|
|
12
|
+
)
|
|
13
|
+
from ..types import P
|
|
14
|
+
from .protocols import (
|
|
15
|
+
AsyncContextPromptable,
|
|
16
|
+
AsyncPromptable,
|
|
17
|
+
ContextPromptable,
|
|
18
|
+
Promptable,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def is_messages(
|
|
23
|
+
messages_or_content: list[Message] | UserContent,
|
|
24
|
+
) -> TypeIs[list[Message]]:
|
|
25
|
+
if not messages_or_content:
|
|
26
|
+
raise ValueError("Prompt returned empty content")
|
|
27
|
+
return isinstance(messages_or_content, list) and isinstance(
|
|
28
|
+
messages_or_content[0], SystemMessage | UserMessage | AssistantMessage
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def promote_to_messages(result: list[Message] | UserContent) -> list[Message]:
|
|
33
|
+
"""Promote a prompt result to a list of messages.
|
|
34
|
+
|
|
35
|
+
If the result is already a list of Messages, returns it as-is.
|
|
36
|
+
If the result is UserContent, wraps it in a single user message.
|
|
37
|
+
"""
|
|
38
|
+
if is_messages(result):
|
|
39
|
+
return result
|
|
40
|
+
return [user(result)]
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def is_context_promptable(
|
|
44
|
+
fn: ContextPromptable[P, DepsT]
|
|
45
|
+
| AsyncContextPromptable[P, DepsT]
|
|
46
|
+
| Promptable[P]
|
|
47
|
+
| AsyncPromptable[P],
|
|
48
|
+
) -> TypeIs[ContextPromptable[P, DepsT] | AsyncContextPromptable[P, DepsT]]:
|
|
49
|
+
"""Type guard to check if a function is a context promptable function."""
|
|
50
|
+
return _context_utils.first_param_is_context(fn)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def is_async_promptable(
|
|
54
|
+
fn: ContextPromptable[P, DepsT]
|
|
55
|
+
| AsyncContextPromptable[P, DepsT]
|
|
56
|
+
| Promptable[P]
|
|
57
|
+
| AsyncPromptable[P],
|
|
58
|
+
) -> TypeIs[AsyncPromptable[P] | AsyncContextPromptable[P, DepsT]]:
|
|
59
|
+
"""Type guard to check if a function is an async promptable function."""
|
|
60
|
+
return inspect.iscoroutinefunction(fn)
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
"""The `prompt` decorator for writing messages as string templates."""
|
|
2
|
+
|
|
3
|
+
from typing import overload
|
|
4
|
+
|
|
5
|
+
from ..context import Context, DepsT
|
|
6
|
+
from ..messages import (
|
|
7
|
+
Message,
|
|
8
|
+
)
|
|
9
|
+
from ..types import P
|
|
10
|
+
from . import _utils
|
|
11
|
+
from .protocols import (
|
|
12
|
+
AsyncContextPrompt,
|
|
13
|
+
AsyncContextPromptable,
|
|
14
|
+
AsyncPrompt,
|
|
15
|
+
AsyncPromptable,
|
|
16
|
+
ContextPrompt,
|
|
17
|
+
ContextPromptable,
|
|
18
|
+
Prompt,
|
|
19
|
+
Promptable,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class PromptDecorator:
|
|
24
|
+
"""Protocol for the `prompt` decorator when used without a template."""
|
|
25
|
+
|
|
26
|
+
@overload
|
|
27
|
+
def __call__(
|
|
28
|
+
self,
|
|
29
|
+
fn: ContextPromptable[P, DepsT],
|
|
30
|
+
) -> ContextPrompt[P, DepsT]:
|
|
31
|
+
"""Decorator for creating context prompts."""
|
|
32
|
+
...
|
|
33
|
+
|
|
34
|
+
@overload
|
|
35
|
+
def __call__(
|
|
36
|
+
self,
|
|
37
|
+
fn: AsyncContextPromptable[P, DepsT],
|
|
38
|
+
) -> AsyncContextPrompt[P, DepsT]:
|
|
39
|
+
"""Decorator for creating async context prompts."""
|
|
40
|
+
...
|
|
41
|
+
|
|
42
|
+
@overload
|
|
43
|
+
def __call__(
|
|
44
|
+
self,
|
|
45
|
+
fn: Promptable[P],
|
|
46
|
+
) -> Prompt[P]:
|
|
47
|
+
"""Decorator for creating prompts."""
|
|
48
|
+
...
|
|
49
|
+
|
|
50
|
+
@overload
|
|
51
|
+
def __call__(
|
|
52
|
+
self,
|
|
53
|
+
fn: AsyncPromptable[P],
|
|
54
|
+
) -> AsyncPrompt[P]:
|
|
55
|
+
"""Decorator for creating async prompts."""
|
|
56
|
+
...
|
|
57
|
+
|
|
58
|
+
def __call__(
|
|
59
|
+
self,
|
|
60
|
+
fn: ContextPromptable[P, DepsT]
|
|
61
|
+
| AsyncContextPromptable[P, DepsT]
|
|
62
|
+
| Promptable[P]
|
|
63
|
+
| AsyncPromptable[P],
|
|
64
|
+
) -> (
|
|
65
|
+
Prompt[P]
|
|
66
|
+
| AsyncPrompt[P]
|
|
67
|
+
| ContextPrompt[P, DepsT]
|
|
68
|
+
| AsyncContextPrompt[P, DepsT]
|
|
69
|
+
):
|
|
70
|
+
"""Decorator for creating a prompt."""
|
|
71
|
+
is_context = _utils.is_context_promptable(fn)
|
|
72
|
+
is_async = _utils.is_async_promptable(fn)
|
|
73
|
+
|
|
74
|
+
# NOTE: unused `fn` expressions work around a Pyright bug
|
|
75
|
+
# TODO: Clean this up once the following Pyright bug is addressed:
|
|
76
|
+
# https://github.com/microsoft/pyright/issues/10951
|
|
77
|
+
if is_context and is_async:
|
|
78
|
+
fn # pyright: ignore[reportUnusedExpression] # noqa: B018
|
|
79
|
+
|
|
80
|
+
async def async_context_prompt(
|
|
81
|
+
ctx: Context[DepsT], *args: P.args, **kwargs: P.kwargs
|
|
82
|
+
) -> list[Message]:
|
|
83
|
+
result = await fn(ctx, *args, **kwargs)
|
|
84
|
+
return _utils.promote_to_messages(result)
|
|
85
|
+
|
|
86
|
+
return async_context_prompt
|
|
87
|
+
elif is_context:
|
|
88
|
+
fn # pyright: ignore[reportUnusedExpression] # noqa: B018
|
|
89
|
+
|
|
90
|
+
def context_prompt(
|
|
91
|
+
ctx: Context[DepsT], *args: P.args, **kwargs: P.kwargs
|
|
92
|
+
) -> list[Message]:
|
|
93
|
+
result = fn(ctx, *args, **kwargs)
|
|
94
|
+
return _utils.promote_to_messages(result)
|
|
95
|
+
|
|
96
|
+
return context_prompt
|
|
97
|
+
elif is_async:
|
|
98
|
+
fn # pyright: ignore[reportUnusedExpression] # noqa: B018
|
|
99
|
+
|
|
100
|
+
async def async_prompt(*args: P.args, **kwargs: P.kwargs) -> list[Message]:
|
|
101
|
+
result = await fn(*args, **kwargs)
|
|
102
|
+
return _utils.promote_to_messages(result)
|
|
103
|
+
|
|
104
|
+
return async_prompt
|
|
105
|
+
else:
|
|
106
|
+
fn # pyright: ignore[reportUnusedExpression] # noqa: B018
|
|
107
|
+
|
|
108
|
+
def prompt(*args: P.args, **kwargs: P.kwargs) -> list[Message]:
|
|
109
|
+
result = fn(*args, **kwargs)
|
|
110
|
+
return _utils.promote_to_messages(result)
|
|
111
|
+
|
|
112
|
+
return prompt
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
class PromptTemplateDecorator:
|
|
116
|
+
"""Protocol for the `prompt` decorator when used with a template."""
|
|
117
|
+
|
|
118
|
+
@overload
|
|
119
|
+
def __call__(
|
|
120
|
+
self,
|
|
121
|
+
fn: ContextPromptable[P, DepsT],
|
|
122
|
+
) -> ContextPrompt[P, DepsT]:
|
|
123
|
+
"""Decorator for creating context prompts from template functions."""
|
|
124
|
+
...
|
|
125
|
+
|
|
126
|
+
@overload
|
|
127
|
+
def __call__(
|
|
128
|
+
self,
|
|
129
|
+
fn: AsyncContextPromptable[P, DepsT],
|
|
130
|
+
) -> AsyncContextPrompt[P, DepsT]:
|
|
131
|
+
"""Decorator for creating async context prompts from template functions."""
|
|
132
|
+
...
|
|
133
|
+
|
|
134
|
+
@overload
|
|
135
|
+
def __call__(
|
|
136
|
+
self,
|
|
137
|
+
fn: Promptable[P],
|
|
138
|
+
) -> Prompt[P]:
|
|
139
|
+
"""Decorator for creating prompts from template functions."""
|
|
140
|
+
...
|
|
141
|
+
|
|
142
|
+
@overload
|
|
143
|
+
def __call__(
|
|
144
|
+
self,
|
|
145
|
+
fn: AsyncPromptable[P],
|
|
146
|
+
) -> AsyncPrompt[P]:
|
|
147
|
+
"""Decorator for creating async prompts from template functions."""
|
|
148
|
+
...
|
|
149
|
+
|
|
150
|
+
def __call__(
|
|
151
|
+
self,
|
|
152
|
+
fn: ContextPromptable[P, DepsT]
|
|
153
|
+
| AsyncContextPromptable[P, DepsT]
|
|
154
|
+
| Promptable[P]
|
|
155
|
+
| AsyncPromptable[P],
|
|
156
|
+
) -> (
|
|
157
|
+
Prompt[P]
|
|
158
|
+
| AsyncPrompt[P]
|
|
159
|
+
| ContextPrompt[P, DepsT]
|
|
160
|
+
| AsyncContextPrompt[P, DepsT]
|
|
161
|
+
):
|
|
162
|
+
"""Decorator for creating a prompt from a template function."""
|
|
163
|
+
raise NotImplementedError()
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
@overload
|
|
167
|
+
def prompt(
|
|
168
|
+
__fn: ContextPromptable[P, DepsT],
|
|
169
|
+
) -> ContextPrompt[P, DepsT]:
|
|
170
|
+
"""Create a decorator for sync ContextPrompt functions (no arguments)."""
|
|
171
|
+
...
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
@overload
|
|
175
|
+
def prompt(
|
|
176
|
+
__fn: AsyncContextPromptable[P, DepsT],
|
|
177
|
+
) -> AsyncContextPrompt[P, DepsT]:
|
|
178
|
+
"""Create a decorator for async ContextPrompt functions (no arguments)."""
|
|
179
|
+
...
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
@overload
|
|
183
|
+
def prompt(
|
|
184
|
+
__fn: Promptable[P],
|
|
185
|
+
) -> Prompt[P]:
|
|
186
|
+
"""Create a decorator for sync Prompt functions (no arguments)."""
|
|
187
|
+
...
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
@overload
|
|
191
|
+
def prompt(
|
|
192
|
+
__fn: AsyncPromptable[P],
|
|
193
|
+
) -> AsyncPrompt[P]:
|
|
194
|
+
"""Create a decorator for async Prompt functions (no arguments)."""
|
|
195
|
+
...
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
@overload
|
|
199
|
+
def prompt(
|
|
200
|
+
*,
|
|
201
|
+
template: None = None,
|
|
202
|
+
) -> PromptDecorator:
|
|
203
|
+
"""Create a decorator for Prompt functions (no template)"""
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
@overload
|
|
207
|
+
def prompt(
|
|
208
|
+
*,
|
|
209
|
+
template: str,
|
|
210
|
+
) -> PromptTemplateDecorator:
|
|
211
|
+
"""Create a decorator for template functions."""
|
|
212
|
+
...
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def prompt(
|
|
216
|
+
__fn: ContextPromptable[P, DepsT]
|
|
217
|
+
| AsyncContextPromptable[P, DepsT]
|
|
218
|
+
| Promptable[P]
|
|
219
|
+
| AsyncPromptable[P]
|
|
220
|
+
| None = None,
|
|
221
|
+
*,
|
|
222
|
+
template: str | None = None,
|
|
223
|
+
) -> (
|
|
224
|
+
ContextPrompt[P, DepsT]
|
|
225
|
+
| AsyncContextPrompt[P, DepsT]
|
|
226
|
+
| Prompt[P]
|
|
227
|
+
| AsyncPrompt[P]
|
|
228
|
+
| PromptDecorator
|
|
229
|
+
| PromptTemplateDecorator
|
|
230
|
+
):
|
|
231
|
+
"""Prompt decorator for turning functions (or "Prompts") into prompts.
|
|
232
|
+
|
|
233
|
+
This decorator transforms a function into a Prompt, i.e. a function that
|
|
234
|
+
returns `list[llm.Message]`. Its behavior depends on whether it's called with a spec
|
|
235
|
+
string.
|
|
236
|
+
|
|
237
|
+
If the first parameter is named 'ctx' or typed as `llm.Context[T]`, it creates
|
|
238
|
+
a ContextPrompt. Otherwise, it creates a regular Prompt.
|
|
239
|
+
|
|
240
|
+
With a template string, it returns a PromptTemplateDecorator, in which case it uses
|
|
241
|
+
the provided template to decorate an function with an empty body, and uses arguments
|
|
242
|
+
to the function for variable substitution in the template. The resulting PromptTemplate
|
|
243
|
+
returns messages based on the template.
|
|
244
|
+
|
|
245
|
+
Without a template string, it returns a PromptFunctionalDecorator, which
|
|
246
|
+
transforms a Prompt (a function returning either message content, or messages) into
|
|
247
|
+
a PromptTemplate. The resulting prompt template either promotes the content into a
|
|
248
|
+
list containing a single user message, or passes along the messages returned by the
|
|
249
|
+
decorated function.
|
|
250
|
+
|
|
251
|
+
Args:
|
|
252
|
+
template: A string template with placeholders using `{{ variable_name }}`
|
|
253
|
+
and optional role markers like [SYSTEM], [USER], and [ASSISTANT].
|
|
254
|
+
|
|
255
|
+
Returns:
|
|
256
|
+
A PromptTemplateDecorator or PromptFunctionalDecorator that converts
|
|
257
|
+
the decorated function into a prompt.
|
|
258
|
+
|
|
259
|
+
Spec substitution rules:
|
|
260
|
+
- [USER], [ASSISTANT], [SYSTEM] demarcate the start of a new message with that role
|
|
261
|
+
- [MESSAGES] indicates the next variable contains a list of messages to include
|
|
262
|
+
- `{{ variable }}` injects the variable as a string, unless annotated
|
|
263
|
+
- Annotations: `{{ variable:annotation }}` where annotation is one of:
|
|
264
|
+
image, images, audio, audios, document, documents
|
|
265
|
+
- Single content annotations (image, audio, document) expect a file path,
|
|
266
|
+
URL, base64 string, or bytes, which becomes a content part with inferred mime-type
|
|
267
|
+
- Multiple content annotations (images, audios, documents) expect a list
|
|
268
|
+
of strings or bytes, each becoming a content part with inferred mime-type
|
|
269
|
+
|
|
270
|
+
Examples:
|
|
271
|
+
```python
|
|
272
|
+
@llm.prompt
|
|
273
|
+
def answer_question(question: str) -> str:
|
|
274
|
+
return f"Answer this question: {question}"
|
|
275
|
+
|
|
276
|
+
@llm.prompt
|
|
277
|
+
def answer_with_context(ctx: llm.Context[str], question: str) -> str:
|
|
278
|
+
return f"Using context {ctx.deps}, answer: {question}"
|
|
279
|
+
```
|
|
280
|
+
""" # TODO(docs): Update this docstring
|
|
281
|
+
if template:
|
|
282
|
+
raise NotImplementedError()
|
|
283
|
+
decorator = PromptDecorator()
|
|
284
|
+
if __fn is None:
|
|
285
|
+
return decorator
|
|
286
|
+
return decorator(__fn)
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"""Types for prompt functions."""
|
|
2
|
+
|
|
3
|
+
from typing import Protocol, TypeVar
|
|
4
|
+
|
|
5
|
+
from ..context import Context, DepsT
|
|
6
|
+
from ..messages import Message, UserContent
|
|
7
|
+
from ..types import P
|
|
8
|
+
|
|
9
|
+
PromptT = TypeVar(
|
|
10
|
+
"PromptT", bound="Prompt | AsyncPrompt | ContextPrompt | AsyncContextPrompt"
|
|
11
|
+
)
|
|
12
|
+
"""Type variable for prompt types.
|
|
13
|
+
|
|
14
|
+
This type var represents a resolved prompt, i.e. one that returns a list of messages.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class Prompt(Protocol[P]):
|
|
19
|
+
"""Protocol for a `Prompt`, which returns `list[Message]`."""
|
|
20
|
+
|
|
21
|
+
def __call__(self, *args: P.args, **kwargs: P.kwargs) -> list[Message]: ...
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class Promptable(Protocol[P]):
|
|
25
|
+
"""Protocol for a `Promptable` that returns `UserContent` or `list[Message]`.
|
|
26
|
+
|
|
27
|
+
May be be converted by the `prompt` decorator into a `Prompt`.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
def __call__(
|
|
31
|
+
self, *args: P.args, **kwargs: P.kwargs
|
|
32
|
+
) -> UserContent | list[Message]: ...
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class AsyncPrompt(Protocol[P]):
|
|
36
|
+
"""Protocol for an `AsyncPrompt`, which returns `list[Message]`."""
|
|
37
|
+
|
|
38
|
+
async def __call__(self, *args: P.args, **kwargs: P.kwargs) -> list[Message]: ...
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class AsyncPromptable(Protocol[P]):
|
|
42
|
+
"""Protocol for an `AsyncPromptable` that returns `UserContent` or `list[Message]`.
|
|
43
|
+
|
|
44
|
+
May be converted by the `prompt` decorator into an `AsyncPrompt`.
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
async def __call__(
|
|
48
|
+
self, *args: P.args, **kwargs: P.kwargs
|
|
49
|
+
) -> UserContent | list[Message]: ...
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class ContextPrompt(Protocol[P, DepsT]):
|
|
53
|
+
"""Protocol for a `ContextPrompt`, which returns `list[Message]`."""
|
|
54
|
+
|
|
55
|
+
def __call__(
|
|
56
|
+
self,
|
|
57
|
+
ctx: Context[DepsT],
|
|
58
|
+
*args: P.args,
|
|
59
|
+
**kwargs: P.kwargs,
|
|
60
|
+
) -> list[Message]: ...
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class ContextPromptable(Protocol[P, DepsT]):
|
|
64
|
+
"""Protocol for a `ContextPromptable` that returns `UserContent` or `list[Message]`.
|
|
65
|
+
|
|
66
|
+
May be converted by the `prompt` decorator into a `ContextPrompt`.
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
def __call__(
|
|
70
|
+
self,
|
|
71
|
+
ctx: Context[DepsT],
|
|
72
|
+
*args: P.args,
|
|
73
|
+
**kwargs: P.kwargs,
|
|
74
|
+
) -> UserContent | list[Message]: ...
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class AsyncContextPrompt(Protocol[P, DepsT]):
|
|
78
|
+
"""Protocol for an `AsyncContextPrompt`, which returns `list[Message]`."""
|
|
79
|
+
|
|
80
|
+
async def __call__(
|
|
81
|
+
self,
|
|
82
|
+
ctx: Context[DepsT],
|
|
83
|
+
*args: P.args,
|
|
84
|
+
**kwargs: P.kwargs,
|
|
85
|
+
) -> list[Message]: ...
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class AsyncContextPromptable(Protocol[P, DepsT]):
|
|
89
|
+
"""Protocol for an `AsyncContextPromptable` that returns `UserContent` or `list[Message]`.
|
|
90
|
+
|
|
91
|
+
May be converted by the `prompt` decorator into an `AsyncContextPrompt`.
|
|
92
|
+
"""
|
|
93
|
+
|
|
94
|
+
async def __call__(
|
|
95
|
+
self,
|
|
96
|
+
ctx: Context[DepsT],
|
|
97
|
+
*args: P.args,
|
|
98
|
+
**kwargs: P.kwargs,
|
|
99
|
+
) -> UserContent | list[Message]: ...
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""The Responses module for LLM responses."""
|
|
2
|
+
|
|
3
|
+
from . import _utils
|
|
4
|
+
from .base_stream_response import (
|
|
5
|
+
AsyncChunkIterator,
|
|
6
|
+
ChunkIterator,
|
|
7
|
+
RawMessageChunk,
|
|
8
|
+
RawStreamEventChunk,
|
|
9
|
+
StreamResponseChunk,
|
|
10
|
+
)
|
|
11
|
+
from .finish_reason import FinishReason, FinishReasonChunk
|
|
12
|
+
from .response import AsyncContextResponse, AsyncResponse, ContextResponse, Response
|
|
13
|
+
from .root_response import RootResponse
|
|
14
|
+
from .stream_response import (
|
|
15
|
+
AsyncContextStreamResponse,
|
|
16
|
+
AsyncStreamResponse,
|
|
17
|
+
ContextStreamResponse,
|
|
18
|
+
StreamResponse,
|
|
19
|
+
)
|
|
20
|
+
from .streams import (
|
|
21
|
+
AsyncStream,
|
|
22
|
+
AsyncTextStream,
|
|
23
|
+
AsyncThoughtStream,
|
|
24
|
+
AsyncToolCallStream,
|
|
25
|
+
Stream,
|
|
26
|
+
TextStream,
|
|
27
|
+
ThoughtStream,
|
|
28
|
+
ToolCallStream,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
__all__ = [
|
|
32
|
+
"AsyncChunkIterator",
|
|
33
|
+
"AsyncContextResponse",
|
|
34
|
+
"AsyncContextStreamResponse",
|
|
35
|
+
"AsyncResponse",
|
|
36
|
+
"AsyncStream",
|
|
37
|
+
"AsyncStreamResponse",
|
|
38
|
+
"AsyncTextStream",
|
|
39
|
+
"AsyncThoughtStream",
|
|
40
|
+
"AsyncToolCallStream",
|
|
41
|
+
"ChunkIterator",
|
|
42
|
+
"ContextResponse",
|
|
43
|
+
"ContextStreamResponse",
|
|
44
|
+
"FinishReason",
|
|
45
|
+
"FinishReasonChunk",
|
|
46
|
+
"RawMessageChunk",
|
|
47
|
+
"RawStreamEventChunk",
|
|
48
|
+
"Response",
|
|
49
|
+
"RootResponse",
|
|
50
|
+
"Stream",
|
|
51
|
+
"StreamResponse",
|
|
52
|
+
"StreamResponseChunk",
|
|
53
|
+
"TextStream",
|
|
54
|
+
"ThoughtStream",
|
|
55
|
+
"ToolCallStream",
|
|
56
|
+
"_utils",
|
|
57
|
+
]
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
def extract_serialized_json(text: str) -> str:
|
|
2
|
+
"""Extract the serialized JSON string from text that may contain extra content.
|
|
3
|
+
|
|
4
|
+
Handles cases where models output text before JSON like:
|
|
5
|
+
"Sure thing! Here's the JSON:\n{...}"
|
|
6
|
+
|
|
7
|
+
Or cases where the model wraps the JSON in code blocks like:
|
|
8
|
+
"```json\n{...}\n```"
|
|
9
|
+
|
|
10
|
+
Args:
|
|
11
|
+
text: The raw text that may contain a JSON object
|
|
12
|
+
|
|
13
|
+
Raises:
|
|
14
|
+
ValueError: If no serialized json object string was found.
|
|
15
|
+
|
|
16
|
+
Returns:
|
|
17
|
+
The extracted serialized JSON string
|
|
18
|
+
"""
|
|
19
|
+
code_block_start_marker = "```json"
|
|
20
|
+
code_block_start = text.find(code_block_start_marker)
|
|
21
|
+
if code_block_start > -1:
|
|
22
|
+
# Discard text prior to code block; it takes precedence over brackets that
|
|
23
|
+
# may be found before it.
|
|
24
|
+
text = text[code_block_start:]
|
|
25
|
+
|
|
26
|
+
json_start = text.find("{")
|
|
27
|
+
if json_start == -1:
|
|
28
|
+
raise ValueError("Could not extract json: no opening `{`")
|
|
29
|
+
|
|
30
|
+
# Find the matching closing brace
|
|
31
|
+
brace_count = 0
|
|
32
|
+
in_string = False
|
|
33
|
+
escaped = False
|
|
34
|
+
|
|
35
|
+
for i, char in enumerate(text[json_start:], json_start):
|
|
36
|
+
if escaped:
|
|
37
|
+
escaped = False
|
|
38
|
+
continue
|
|
39
|
+
|
|
40
|
+
if char == "\\":
|
|
41
|
+
escaped = True
|
|
42
|
+
continue
|
|
43
|
+
|
|
44
|
+
if char == '"' and not escaped:
|
|
45
|
+
in_string = not in_string
|
|
46
|
+
continue
|
|
47
|
+
|
|
48
|
+
if not in_string:
|
|
49
|
+
if char == "{":
|
|
50
|
+
brace_count += 1
|
|
51
|
+
elif char == "}":
|
|
52
|
+
brace_count -= 1
|
|
53
|
+
if brace_count == 0:
|
|
54
|
+
return text[json_start : i + 1]
|
|
55
|
+
|
|
56
|
+
raise ValueError("Could not extract json: no closing `}`")
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"""Shared base of Response and AsyncResponse."""
|
|
2
|
+
|
|
3
|
+
from collections.abc import Sequence
|
|
4
|
+
from typing import TYPE_CHECKING, Any
|
|
5
|
+
|
|
6
|
+
from ..content import Text, Thought, ToolCall
|
|
7
|
+
from ..formatting import Format, FormattableT
|
|
8
|
+
from ..messages import AssistantMessage, Message
|
|
9
|
+
from ..tools import FORMAT_TOOL_NAME, ToolkitT
|
|
10
|
+
from .finish_reason import FinishReason
|
|
11
|
+
from .root_response import RootResponse
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from ..clients import ModelId, Params, Provider
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class BaseResponse(RootResponse[ToolkitT, FormattableT]):
|
|
18
|
+
"""The response generated by an LLM."""
|
|
19
|
+
|
|
20
|
+
def __init__(
|
|
21
|
+
self,
|
|
22
|
+
*,
|
|
23
|
+
raw: Any, # noqa: ANN401
|
|
24
|
+
provider: "Provider",
|
|
25
|
+
model_id: "ModelId",
|
|
26
|
+
params: "Params",
|
|
27
|
+
toolkit: ToolkitT,
|
|
28
|
+
format: Format[FormattableT] | None = None,
|
|
29
|
+
input_messages: Sequence[Message],
|
|
30
|
+
assistant_message: AssistantMessage,
|
|
31
|
+
finish_reason: FinishReason | None,
|
|
32
|
+
) -> None:
|
|
33
|
+
"""Initialize a Response.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
raw: The raw response from the LLM.
|
|
37
|
+
provider: The provider name (e.g. "anthropic", "openai:completions").
|
|
38
|
+
model_id: The model identifier that generated the response.
|
|
39
|
+
params: The params used to generate the response (or None).
|
|
40
|
+
toolkit: Toolkit containing all the tools used to generate the response.
|
|
41
|
+
format: The `Format` for the expected structured output format (or None).
|
|
42
|
+
input_messages: The message history before the final assistant message.
|
|
43
|
+
assistant_message: The final assistant message containing the response content.
|
|
44
|
+
finish_reason: The reason why the LLM finished generating a response.
|
|
45
|
+
"""
|
|
46
|
+
self.raw = raw
|
|
47
|
+
self.provider = provider
|
|
48
|
+
self.model_id = model_id
|
|
49
|
+
self.params = params
|
|
50
|
+
self.toolkit = toolkit
|
|
51
|
+
self.finish_reason = finish_reason
|
|
52
|
+
self.format = format
|
|
53
|
+
|
|
54
|
+
# Process content in the assistant message, organizing it by type and
|
|
55
|
+
# transforming ToolCalls to the special format tool into text (as calls to the
|
|
56
|
+
# formatting tool are not "real" tool calls, and response.parse() expects to
|
|
57
|
+
# operate on text content).
|
|
58
|
+
self.texts = []
|
|
59
|
+
self.tool_calls = []
|
|
60
|
+
self.thoughts = []
|
|
61
|
+
self.content = []
|
|
62
|
+
found_format_tool = False
|
|
63
|
+
|
|
64
|
+
for part in assistant_message.content:
|
|
65
|
+
if isinstance(part, ToolCall) and part.name.startswith(FORMAT_TOOL_NAME):
|
|
66
|
+
part = Text(text=part.args)
|
|
67
|
+
found_format_tool = True
|
|
68
|
+
|
|
69
|
+
self.content.append(part)
|
|
70
|
+
if isinstance(part, Text):
|
|
71
|
+
self.texts.append(part)
|
|
72
|
+
elif isinstance(part, ToolCall):
|
|
73
|
+
self.tool_calls.append(part)
|
|
74
|
+
elif isinstance(part, Thought):
|
|
75
|
+
self.thoughts.append(part)
|
|
76
|
+
else:
|
|
77
|
+
raise NotImplementedError
|
|
78
|
+
|
|
79
|
+
if found_format_tool:
|
|
80
|
+
# We create a new assistant message if we found a formatting ToolCall
|
|
81
|
+
# since this indicates we've transformed the content from the original
|
|
82
|
+
# NOTE: we copy over the assistant message `name` field, although in
|
|
83
|
+
# practice we don't know of any providers that set the name themselves.
|
|
84
|
+
assistant_message = AssistantMessage(
|
|
85
|
+
content=self.content,
|
|
86
|
+
name=assistant_message.name,
|
|
87
|
+
provider=assistant_message.provider,
|
|
88
|
+
model_id=assistant_message.model_id,
|
|
89
|
+
raw_message=assistant_message.raw_message,
|
|
90
|
+
)
|
|
91
|
+
self.messages = list(input_messages) + [assistant_message]
|