mirascope 2.0.0__py3-none-any.whl → 2.0.0a1__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 +2 -11
- mirascope/graphs/__init__.py +22 -0
- mirascope/graphs/finite_state_machine.py +625 -0
- mirascope/llm/__init__.py +15 -96
- 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 +1 -2
- mirascope/llm/calls/base_call.py +33 -0
- mirascope/llm/calls/calls.py +58 -84
- mirascope/llm/calls/decorator.py +120 -140
- mirascope/llm/clients/__init__.py +34 -0
- mirascope/llm/clients/_missing_import_stubs.py +47 -0
- mirascope/llm/clients/anthropic/__init__.py +25 -0
- mirascope/llm/{providers/openai/completions → clients/anthropic}/_utils/__init__.py +0 -2
- mirascope/llm/{providers → clients}/anthropic/_utils/decode.py +22 -66
- 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/{providers → clients}/base/__init__.py +5 -4
- mirascope/llm/{providers → clients}/base/_utils.py +17 -78
- mirascope/llm/{providers/base/base_provider.py → clients/base/client.py} +145 -468
- mirascope/llm/{models → clients/base}/params.py +37 -16
- mirascope/llm/clients/google/__init__.py +20 -0
- mirascope/llm/{providers/openai/responses → clients/google}/_utils/__init__.py +0 -2
- mirascope/llm/{providers → clients}/google/_utils/decode.py +22 -98
- mirascope/llm/{providers → clients}/google/_utils/encode.py +46 -168
- mirascope/llm/clients/google/clients.py +853 -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 +28 -0
- mirascope/llm/{providers/google → clients/openai/completions}/_utils/__init__.py +0 -4
- mirascope/llm/{providers → clients}/openai/completions/_utils/decode.py +9 -74
- mirascope/llm/{providers → clients}/openai/completions/_utils/encode.py +52 -70
- 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 +26 -0
- mirascope/llm/clients/openai/responses/_utils/__init__.py +13 -0
- mirascope/llm/{providers → clients}/openai/responses/_utils/decode.py +14 -80
- mirascope/llm/{providers → clients}/openai/responses/_utils/encode.py +41 -92
- 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 +2 -3
- mirascope/llm/content/tool_call.py +0 -6
- mirascope/llm/content/tool_output.py +5 -22
- mirascope/llm/context/_utils.py +6 -19
- mirascope/llm/exceptions.py +43 -298
- mirascope/llm/formatting/__init__.py +2 -19
- mirascope/llm/formatting/_utils.py +74 -0
- mirascope/llm/formatting/format.py +30 -219
- mirascope/llm/formatting/from_call_args.py +2 -2
- mirascope/llm/formatting/partial.py +7 -80
- mirascope/llm/formatting/types.py +64 -21
- mirascope/llm/mcp/__init__.py +2 -2
- mirascope/llm/mcp/client.py +118 -0
- mirascope/llm/messages/__init__.py +0 -3
- mirascope/llm/messages/message.py +5 -13
- mirascope/llm/models/__init__.py +2 -7
- mirascope/llm/models/models.py +139 -315
- mirascope/llm/prompts/__init__.py +12 -13
- mirascope/llm/prompts/_utils.py +43 -14
- mirascope/llm/prompts/decorator.py +204 -144
- mirascope/llm/prompts/protocols.py +59 -25
- mirascope/llm/responses/__init__.py +1 -9
- mirascope/llm/responses/_utils.py +12 -102
- mirascope/llm/responses/base_response.py +6 -18
- mirascope/llm/responses/base_stream_response.py +50 -173
- mirascope/llm/responses/finish_reason.py +0 -1
- mirascope/llm/responses/response.py +13 -34
- mirascope/llm/responses/root_response.py +29 -100
- mirascope/llm/responses/stream_response.py +31 -40
- mirascope/llm/tools/__init__.py +2 -9
- mirascope/llm/tools/_utils.py +3 -12
- mirascope/llm/tools/decorator.py +16 -25
- mirascope/llm/tools/protocols.py +4 -4
- mirascope/llm/tools/tool_schema.py +19 -87
- mirascope/llm/tools/toolkit.py +27 -35
- mirascope/llm/tools/tools.py +41 -135
- {mirascope-2.0.0.dist-info → mirascope-2.0.0a1.dist-info}/METADATA +13 -90
- mirascope-2.0.0a1.dist-info/RECORD +102 -0
- {mirascope-2.0.0.dist-info → mirascope-2.0.0a1.dist-info}/WHEEL +1 -1
- {mirascope-2.0.0.dist-info → mirascope-2.0.0a1.dist-info}/licenses/LICENSE +1 -1
- mirascope/_stubs.py +0 -363
- mirascope/api/__init__.py +0 -14
- mirascope/api/_generated/README.md +0 -207
- mirascope/api/_generated/__init__.py +0 -440
- mirascope/api/_generated/annotations/__init__.py +0 -33
- mirascope/api/_generated/annotations/client.py +0 -506
- mirascope/api/_generated/annotations/raw_client.py +0 -1414
- mirascope/api/_generated/annotations/types/__init__.py +0 -31
- mirascope/api/_generated/annotations/types/annotations_create_request_label.py +0 -5
- mirascope/api/_generated/annotations/types/annotations_create_response.py +0 -48
- mirascope/api/_generated/annotations/types/annotations_create_response_label.py +0 -5
- mirascope/api/_generated/annotations/types/annotations_get_response.py +0 -48
- mirascope/api/_generated/annotations/types/annotations_get_response_label.py +0 -5
- mirascope/api/_generated/annotations/types/annotations_list_request_label.py +0 -5
- mirascope/api/_generated/annotations/types/annotations_list_response.py +0 -21
- mirascope/api/_generated/annotations/types/annotations_list_response_annotations_item.py +0 -50
- mirascope/api/_generated/annotations/types/annotations_list_response_annotations_item_label.py +0 -5
- mirascope/api/_generated/annotations/types/annotations_update_request_label.py +0 -5
- mirascope/api/_generated/annotations/types/annotations_update_response.py +0 -48
- mirascope/api/_generated/annotations/types/annotations_update_response_label.py +0 -5
- mirascope/api/_generated/api_keys/__init__.py +0 -17
- mirascope/api/_generated/api_keys/client.py +0 -530
- mirascope/api/_generated/api_keys/raw_client.py +0 -1236
- mirascope/api/_generated/api_keys/types/__init__.py +0 -15
- mirascope/api/_generated/api_keys/types/api_keys_create_response.py +0 -28
- mirascope/api/_generated/api_keys/types/api_keys_get_response.py +0 -27
- mirascope/api/_generated/api_keys/types/api_keys_list_all_for_org_response_item.py +0 -40
- mirascope/api/_generated/api_keys/types/api_keys_list_response_item.py +0 -27
- mirascope/api/_generated/client.py +0 -211
- mirascope/api/_generated/core/__init__.py +0 -52
- mirascope/api/_generated/core/api_error.py +0 -23
- mirascope/api/_generated/core/client_wrapper.py +0 -46
- mirascope/api/_generated/core/datetime_utils.py +0 -28
- mirascope/api/_generated/core/file.py +0 -67
- mirascope/api/_generated/core/force_multipart.py +0 -16
- mirascope/api/_generated/core/http_client.py +0 -543
- mirascope/api/_generated/core/http_response.py +0 -55
- mirascope/api/_generated/core/jsonable_encoder.py +0 -100
- mirascope/api/_generated/core/pydantic_utilities.py +0 -255
- mirascope/api/_generated/core/query_encoder.py +0 -58
- mirascope/api/_generated/core/remove_none_from_dict.py +0 -11
- mirascope/api/_generated/core/request_options.py +0 -35
- mirascope/api/_generated/core/serialization.py +0 -276
- mirascope/api/_generated/docs/__init__.py +0 -4
- mirascope/api/_generated/docs/client.py +0 -91
- mirascope/api/_generated/docs/raw_client.py +0 -178
- mirascope/api/_generated/environment.py +0 -9
- mirascope/api/_generated/environments/__init__.py +0 -23
- mirascope/api/_generated/environments/client.py +0 -649
- mirascope/api/_generated/environments/raw_client.py +0 -1567
- mirascope/api/_generated/environments/types/__init__.py +0 -25
- mirascope/api/_generated/environments/types/environments_create_response.py +0 -24
- mirascope/api/_generated/environments/types/environments_get_analytics_response.py +0 -60
- mirascope/api/_generated/environments/types/environments_get_analytics_response_top_functions_item.py +0 -24
- mirascope/api/_generated/environments/types/environments_get_analytics_response_top_models_item.py +0 -22
- mirascope/api/_generated/environments/types/environments_get_response.py +0 -24
- mirascope/api/_generated/environments/types/environments_list_response_item.py +0 -24
- mirascope/api/_generated/environments/types/environments_update_response.py +0 -24
- mirascope/api/_generated/errors/__init__.py +0 -25
- mirascope/api/_generated/errors/bad_request_error.py +0 -14
- mirascope/api/_generated/errors/conflict_error.py +0 -14
- mirascope/api/_generated/errors/forbidden_error.py +0 -11
- mirascope/api/_generated/errors/internal_server_error.py +0 -10
- mirascope/api/_generated/errors/not_found_error.py +0 -11
- mirascope/api/_generated/errors/payment_required_error.py +0 -15
- mirascope/api/_generated/errors/service_unavailable_error.py +0 -14
- mirascope/api/_generated/errors/too_many_requests_error.py +0 -15
- mirascope/api/_generated/errors/unauthorized_error.py +0 -11
- mirascope/api/_generated/functions/__init__.py +0 -39
- mirascope/api/_generated/functions/client.py +0 -647
- mirascope/api/_generated/functions/raw_client.py +0 -1890
- mirascope/api/_generated/functions/types/__init__.py +0 -53
- mirascope/api/_generated/functions/types/functions_create_request_dependencies_value.py +0 -20
- mirascope/api/_generated/functions/types/functions_create_response.py +0 -37
- mirascope/api/_generated/functions/types/functions_create_response_dependencies_value.py +0 -20
- mirascope/api/_generated/functions/types/functions_find_by_hash_response.py +0 -39
- mirascope/api/_generated/functions/types/functions_find_by_hash_response_dependencies_value.py +0 -20
- mirascope/api/_generated/functions/types/functions_get_by_env_response.py +0 -53
- mirascope/api/_generated/functions/types/functions_get_by_env_response_dependencies_value.py +0 -22
- mirascope/api/_generated/functions/types/functions_get_response.py +0 -37
- mirascope/api/_generated/functions/types/functions_get_response_dependencies_value.py +0 -20
- mirascope/api/_generated/functions/types/functions_list_by_env_response.py +0 -25
- mirascope/api/_generated/functions/types/functions_list_by_env_response_functions_item.py +0 -56
- mirascope/api/_generated/functions/types/functions_list_by_env_response_functions_item_dependencies_value.py +0 -22
- mirascope/api/_generated/functions/types/functions_list_response.py +0 -21
- mirascope/api/_generated/functions/types/functions_list_response_functions_item.py +0 -41
- mirascope/api/_generated/functions/types/functions_list_response_functions_item_dependencies_value.py +0 -20
- mirascope/api/_generated/health/__init__.py +0 -7
- mirascope/api/_generated/health/client.py +0 -92
- mirascope/api/_generated/health/raw_client.py +0 -175
- mirascope/api/_generated/health/types/__init__.py +0 -8
- mirascope/api/_generated/health/types/health_check_response.py +0 -22
- mirascope/api/_generated/health/types/health_check_response_status.py +0 -5
- mirascope/api/_generated/organization_invitations/__init__.py +0 -33
- mirascope/api/_generated/organization_invitations/client.py +0 -546
- mirascope/api/_generated/organization_invitations/raw_client.py +0 -1519
- mirascope/api/_generated/organization_invitations/types/__init__.py +0 -53
- mirascope/api/_generated/organization_invitations/types/organization_invitations_accept_response.py +0 -34
- mirascope/api/_generated/organization_invitations/types/organization_invitations_accept_response_role.py +0 -7
- mirascope/api/_generated/organization_invitations/types/organization_invitations_create_request_role.py +0 -7
- mirascope/api/_generated/organization_invitations/types/organization_invitations_create_response.py +0 -48
- mirascope/api/_generated/organization_invitations/types/organization_invitations_create_response_role.py +0 -7
- mirascope/api/_generated/organization_invitations/types/organization_invitations_create_response_status.py +0 -7
- mirascope/api/_generated/organization_invitations/types/organization_invitations_get_response.py +0 -48
- mirascope/api/_generated/organization_invitations/types/organization_invitations_get_response_role.py +0 -7
- mirascope/api/_generated/organization_invitations/types/organization_invitations_get_response_status.py +0 -7
- mirascope/api/_generated/organization_invitations/types/organization_invitations_list_response_item.py +0 -48
- mirascope/api/_generated/organization_invitations/types/organization_invitations_list_response_item_role.py +0 -7
- mirascope/api/_generated/organization_invitations/types/organization_invitations_list_response_item_status.py +0 -7
- mirascope/api/_generated/organization_memberships/__init__.py +0 -19
- mirascope/api/_generated/organization_memberships/client.py +0 -302
- mirascope/api/_generated/organization_memberships/raw_client.py +0 -736
- mirascope/api/_generated/organization_memberships/types/__init__.py +0 -27
- mirascope/api/_generated/organization_memberships/types/organization_memberships_list_response_item.py +0 -33
- mirascope/api/_generated/organization_memberships/types/organization_memberships_list_response_item_role.py +0 -7
- mirascope/api/_generated/organization_memberships/types/organization_memberships_update_request_role.py +0 -7
- mirascope/api/_generated/organization_memberships/types/organization_memberships_update_response.py +0 -31
- mirascope/api/_generated/organization_memberships/types/organization_memberships_update_response_role.py +0 -7
- mirascope/api/_generated/organizations/__init__.py +0 -51
- mirascope/api/_generated/organizations/client.py +0 -869
- mirascope/api/_generated/organizations/raw_client.py +0 -2593
- mirascope/api/_generated/organizations/types/__init__.py +0 -71
- mirascope/api/_generated/organizations/types/organizations_create_payment_intent_response.py +0 -24
- mirascope/api/_generated/organizations/types/organizations_create_response.py +0 -26
- mirascope/api/_generated/organizations/types/organizations_create_response_role.py +0 -5
- mirascope/api/_generated/organizations/types/organizations_get_response.py +0 -26
- mirascope/api/_generated/organizations/types/organizations_get_response_role.py +0 -5
- mirascope/api/_generated/organizations/types/organizations_list_response_item.py +0 -26
- mirascope/api/_generated/organizations/types/organizations_list_response_item_role.py +0 -5
- mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_request_target_plan.py +0 -7
- mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_response.py +0 -47
- mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_response_validation_errors_item.py +0 -33
- mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_response_validation_errors_item_resource.py +0 -7
- mirascope/api/_generated/organizations/types/organizations_router_balance_response.py +0 -24
- mirascope/api/_generated/organizations/types/organizations_subscription_response.py +0 -53
- mirascope/api/_generated/organizations/types/organizations_subscription_response_current_plan.py +0 -7
- mirascope/api/_generated/organizations/types/organizations_subscription_response_payment_method.py +0 -26
- mirascope/api/_generated/organizations/types/organizations_subscription_response_scheduled_change.py +0 -34
- mirascope/api/_generated/organizations/types/organizations_subscription_response_scheduled_change_target_plan.py +0 -7
- mirascope/api/_generated/organizations/types/organizations_update_response.py +0 -26
- mirascope/api/_generated/organizations/types/organizations_update_response_role.py +0 -5
- mirascope/api/_generated/organizations/types/organizations_update_subscription_request_target_plan.py +0 -7
- mirascope/api/_generated/organizations/types/organizations_update_subscription_response.py +0 -35
- mirascope/api/_generated/project_memberships/__init__.py +0 -25
- mirascope/api/_generated/project_memberships/client.py +0 -437
- mirascope/api/_generated/project_memberships/raw_client.py +0 -1039
- mirascope/api/_generated/project_memberships/types/__init__.py +0 -29
- mirascope/api/_generated/project_memberships/types/project_memberships_create_request_role.py +0 -7
- mirascope/api/_generated/project_memberships/types/project_memberships_create_response.py +0 -35
- mirascope/api/_generated/project_memberships/types/project_memberships_create_response_role.py +0 -7
- mirascope/api/_generated/project_memberships/types/project_memberships_list_response_item.py +0 -33
- mirascope/api/_generated/project_memberships/types/project_memberships_list_response_item_role.py +0 -7
- mirascope/api/_generated/project_memberships/types/project_memberships_update_request_role.py +0 -7
- mirascope/api/_generated/project_memberships/types/project_memberships_update_response.py +0 -35
- mirascope/api/_generated/project_memberships/types/project_memberships_update_response_role.py +0 -7
- mirascope/api/_generated/projects/__init__.py +0 -7
- mirascope/api/_generated/projects/client.py +0 -428
- mirascope/api/_generated/projects/raw_client.py +0 -1302
- mirascope/api/_generated/projects/types/__init__.py +0 -10
- mirascope/api/_generated/projects/types/projects_create_response.py +0 -25
- mirascope/api/_generated/projects/types/projects_get_response.py +0 -25
- mirascope/api/_generated/projects/types/projects_list_response_item.py +0 -25
- mirascope/api/_generated/projects/types/projects_update_response.py +0 -25
- mirascope/api/_generated/reference.md +0 -4915
- mirascope/api/_generated/tags/__init__.py +0 -19
- mirascope/api/_generated/tags/client.py +0 -504
- mirascope/api/_generated/tags/raw_client.py +0 -1288
- mirascope/api/_generated/tags/types/__init__.py +0 -17
- mirascope/api/_generated/tags/types/tags_create_response.py +0 -41
- mirascope/api/_generated/tags/types/tags_get_response.py +0 -41
- mirascope/api/_generated/tags/types/tags_list_response.py +0 -23
- mirascope/api/_generated/tags/types/tags_list_response_tags_item.py +0 -41
- mirascope/api/_generated/tags/types/tags_update_response.py +0 -41
- mirascope/api/_generated/token_cost/__init__.py +0 -7
- mirascope/api/_generated/token_cost/client.py +0 -160
- mirascope/api/_generated/token_cost/raw_client.py +0 -264
- mirascope/api/_generated/token_cost/types/__init__.py +0 -8
- mirascope/api/_generated/token_cost/types/token_cost_calculate_request_usage.py +0 -54
- mirascope/api/_generated/token_cost/types/token_cost_calculate_response.py +0 -52
- mirascope/api/_generated/traces/__init__.py +0 -97
- mirascope/api/_generated/traces/client.py +0 -1103
- mirascope/api/_generated/traces/raw_client.py +0 -2322
- mirascope/api/_generated/traces/types/__init__.py +0 -155
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item.py +0 -29
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource.py +0 -27
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item.py +0 -23
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value.py +0 -38
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_array_value.py +0 -19
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_kvlist_value.py +0 -22
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_kvlist_value_values_item.py +0 -20
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item.py +0 -29
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope.py +0 -31
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item.py +0 -23
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value.py +0 -38
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_array_value.py +0 -19
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_kvlist_value.py +0 -22
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_kvlist_value_values_item.py +0 -22
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item.py +0 -48
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item.py +0 -23
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value.py +0 -38
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_array_value.py +0 -19
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_kvlist_value.py +0 -24
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_kvlist_value_values_item.py +0 -22
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_status.py +0 -20
- mirascope/api/_generated/traces/types/traces_create_response.py +0 -24
- mirascope/api/_generated/traces/types/traces_create_response_partial_success.py +0 -22
- mirascope/api/_generated/traces/types/traces_get_analytics_summary_response.py +0 -60
- mirascope/api/_generated/traces/types/traces_get_analytics_summary_response_top_functions_item.py +0 -24
- mirascope/api/_generated/traces/types/traces_get_analytics_summary_response_top_models_item.py +0 -22
- mirascope/api/_generated/traces/types/traces_get_trace_detail_by_env_response.py +0 -33
- mirascope/api/_generated/traces/types/traces_get_trace_detail_by_env_response_spans_item.py +0 -88
- mirascope/api/_generated/traces/types/traces_get_trace_detail_response.py +0 -33
- mirascope/api/_generated/traces/types/traces_get_trace_detail_response_spans_item.py +0 -88
- mirascope/api/_generated/traces/types/traces_list_by_function_hash_response.py +0 -25
- mirascope/api/_generated/traces/types/traces_list_by_function_hash_response_traces_item.py +0 -44
- mirascope/api/_generated/traces/types/traces_search_by_env_request_attribute_filters_item.py +0 -26
- mirascope/api/_generated/traces/types/traces_search_by_env_request_attribute_filters_item_operator.py +0 -7
- mirascope/api/_generated/traces/types/traces_search_by_env_request_sort_by.py +0 -7
- mirascope/api/_generated/traces/types/traces_search_by_env_request_sort_order.py +0 -7
- mirascope/api/_generated/traces/types/traces_search_by_env_response.py +0 -26
- mirascope/api/_generated/traces/types/traces_search_by_env_response_spans_item.py +0 -50
- mirascope/api/_generated/traces/types/traces_search_request_attribute_filters_item.py +0 -26
- mirascope/api/_generated/traces/types/traces_search_request_attribute_filters_item_operator.py +0 -7
- mirascope/api/_generated/traces/types/traces_search_request_sort_by.py +0 -7
- mirascope/api/_generated/traces/types/traces_search_request_sort_order.py +0 -5
- mirascope/api/_generated/traces/types/traces_search_response.py +0 -26
- mirascope/api/_generated/traces/types/traces_search_response_spans_item.py +0 -50
- mirascope/api/_generated/types/__init__.py +0 -85
- mirascope/api/_generated/types/already_exists_error.py +0 -22
- mirascope/api/_generated/types/already_exists_error_tag.py +0 -5
- mirascope/api/_generated/types/bad_request_error_body.py +0 -50
- mirascope/api/_generated/types/click_house_error.py +0 -22
- mirascope/api/_generated/types/database_error.py +0 -22
- mirascope/api/_generated/types/database_error_tag.py +0 -5
- mirascope/api/_generated/types/date.py +0 -3
- mirascope/api/_generated/types/http_api_decode_error.py +0 -27
- mirascope/api/_generated/types/http_api_decode_error_tag.py +0 -5
- mirascope/api/_generated/types/immutable_resource_error.py +0 -22
- mirascope/api/_generated/types/internal_server_error_body.py +0 -49
- mirascope/api/_generated/types/issue.py +0 -38
- mirascope/api/_generated/types/issue_tag.py +0 -10
- mirascope/api/_generated/types/not_found_error_body.py +0 -22
- mirascope/api/_generated/types/not_found_error_tag.py +0 -5
- mirascope/api/_generated/types/number_from_string.py +0 -3
- mirascope/api/_generated/types/permission_denied_error.py +0 -22
- mirascope/api/_generated/types/permission_denied_error_tag.py +0 -5
- mirascope/api/_generated/types/plan_limit_exceeded_error.py +0 -32
- mirascope/api/_generated/types/plan_limit_exceeded_error_tag.py +0 -7
- mirascope/api/_generated/types/pricing_unavailable_error.py +0 -23
- mirascope/api/_generated/types/property_key.py +0 -7
- mirascope/api/_generated/types/property_key_key.py +0 -25
- mirascope/api/_generated/types/property_key_key_tag.py +0 -5
- mirascope/api/_generated/types/rate_limit_error.py +0 -31
- mirascope/api/_generated/types/rate_limit_error_tag.py +0 -5
- mirascope/api/_generated/types/service_unavailable_error_body.py +0 -24
- mirascope/api/_generated/types/service_unavailable_error_tag.py +0 -7
- mirascope/api/_generated/types/stripe_error.py +0 -20
- mirascope/api/_generated/types/subscription_past_due_error.py +0 -31
- mirascope/api/_generated/types/subscription_past_due_error_tag.py +0 -7
- mirascope/api/_generated/types/unauthorized_error_body.py +0 -21
- mirascope/api/_generated/types/unauthorized_error_tag.py +0 -5
- mirascope/api/client.py +0 -255
- mirascope/api/settings.py +0 -99
- mirascope/llm/formatting/output_parser.py +0 -178
- mirascope/llm/formatting/primitives.py +0 -192
- mirascope/llm/mcp/mcp_client.py +0 -130
- mirascope/llm/messages/_utils.py +0 -34
- mirascope/llm/models/thinking_config.py +0 -61
- mirascope/llm/prompts/prompts.py +0 -487
- mirascope/llm/providers/__init__.py +0 -62
- mirascope/llm/providers/anthropic/__init__.py +0 -11
- mirascope/llm/providers/anthropic/_utils/__init__.py +0 -27
- mirascope/llm/providers/anthropic/_utils/beta_decode.py +0 -282
- mirascope/llm/providers/anthropic/_utils/beta_encode.py +0 -266
- mirascope/llm/providers/anthropic/_utils/encode.py +0 -418
- mirascope/llm/providers/anthropic/_utils/errors.py +0 -46
- mirascope/llm/providers/anthropic/beta_provider.py +0 -374
- mirascope/llm/providers/anthropic/model_id.py +0 -23
- mirascope/llm/providers/anthropic/model_info.py +0 -87
- mirascope/llm/providers/anthropic/provider.py +0 -479
- mirascope/llm/providers/google/__init__.py +0 -6
- mirascope/llm/providers/google/_utils/errors.py +0 -50
- mirascope/llm/providers/google/model_id.py +0 -22
- mirascope/llm/providers/google/model_info.py +0 -63
- mirascope/llm/providers/google/provider.py +0 -492
- mirascope/llm/providers/mirascope/__init__.py +0 -5
- mirascope/llm/providers/mirascope/_utils.py +0 -73
- mirascope/llm/providers/mirascope/provider.py +0 -349
- mirascope/llm/providers/mlx/__init__.py +0 -9
- mirascope/llm/providers/mlx/_utils.py +0 -141
- mirascope/llm/providers/mlx/encoding/__init__.py +0 -8
- mirascope/llm/providers/mlx/encoding/base.py +0 -72
- mirascope/llm/providers/mlx/encoding/transformers.py +0 -150
- mirascope/llm/providers/mlx/mlx.py +0 -254
- mirascope/llm/providers/mlx/model_id.py +0 -17
- mirascope/llm/providers/mlx/provider.py +0 -452
- mirascope/llm/providers/model_id.py +0 -16
- mirascope/llm/providers/ollama/__init__.py +0 -7
- mirascope/llm/providers/ollama/provider.py +0 -71
- mirascope/llm/providers/openai/__init__.py +0 -15
- mirascope/llm/providers/openai/_utils/__init__.py +0 -5
- mirascope/llm/providers/openai/_utils/errors.py +0 -46
- mirascope/llm/providers/openai/completions/__init__.py +0 -7
- mirascope/llm/providers/openai/completions/base_provider.py +0 -542
- mirascope/llm/providers/openai/completions/provider.py +0 -22
- mirascope/llm/providers/openai/model_id.py +0 -31
- mirascope/llm/providers/openai/model_info.py +0 -303
- mirascope/llm/providers/openai/provider.py +0 -441
- mirascope/llm/providers/openai/responses/__init__.py +0 -5
- mirascope/llm/providers/openai/responses/provider.py +0 -513
- mirascope/llm/providers/provider_id.py +0 -24
- mirascope/llm/providers/provider_registry.py +0 -299
- mirascope/llm/providers/together/__init__.py +0 -7
- mirascope/llm/providers/together/provider.py +0 -40
- mirascope/llm/responses/usage.py +0 -95
- mirascope/ops/__init__.py +0 -111
- mirascope/ops/_internal/__init__.py +0 -5
- mirascope/ops/_internal/closure.py +0 -1169
- mirascope/ops/_internal/configuration.py +0 -177
- mirascope/ops/_internal/context.py +0 -76
- mirascope/ops/_internal/exporters/__init__.py +0 -26
- mirascope/ops/_internal/exporters/exporters.py +0 -395
- mirascope/ops/_internal/exporters/processors.py +0 -104
- mirascope/ops/_internal/exporters/types.py +0 -165
- mirascope/ops/_internal/exporters/utils.py +0 -29
- mirascope/ops/_internal/instrumentation/__init__.py +0 -8
- mirascope/ops/_internal/instrumentation/llm/__init__.py +0 -8
- mirascope/ops/_internal/instrumentation/llm/common.py +0 -530
- mirascope/ops/_internal/instrumentation/llm/cost.py +0 -190
- mirascope/ops/_internal/instrumentation/llm/encode.py +0 -238
- mirascope/ops/_internal/instrumentation/llm/gen_ai_types/__init__.py +0 -38
- mirascope/ops/_internal/instrumentation/llm/gen_ai_types/gen_ai_input_messages.py +0 -31
- mirascope/ops/_internal/instrumentation/llm/gen_ai_types/gen_ai_output_messages.py +0 -38
- mirascope/ops/_internal/instrumentation/llm/gen_ai_types/gen_ai_system_instructions.py +0 -18
- mirascope/ops/_internal/instrumentation/llm/gen_ai_types/shared.py +0 -100
- mirascope/ops/_internal/instrumentation/llm/llm.py +0 -161
- mirascope/ops/_internal/instrumentation/llm/model.py +0 -1798
- mirascope/ops/_internal/instrumentation/llm/response.py +0 -521
- mirascope/ops/_internal/instrumentation/llm/serialize.py +0 -300
- mirascope/ops/_internal/propagation.py +0 -198
- mirascope/ops/_internal/protocols.py +0 -133
- mirascope/ops/_internal/session.py +0 -139
- mirascope/ops/_internal/spans.py +0 -232
- mirascope/ops/_internal/traced_calls.py +0 -375
- mirascope/ops/_internal/traced_functions.py +0 -523
- mirascope/ops/_internal/tracing.py +0 -353
- mirascope/ops/_internal/types.py +0 -13
- mirascope/ops/_internal/utils.py +0 -123
- mirascope/ops/_internal/versioned_calls.py +0 -512
- mirascope/ops/_internal/versioned_functions.py +0 -357
- mirascope/ops/_internal/versioning.py +0 -303
- mirascope/ops/exceptions.py +0 -21
- mirascope-2.0.0.dist-info/RECORD +0 -423
- /mirascope/llm/{providers → clients}/base/kwargs.py +0 -0
- /mirascope/llm/{providers → clients}/google/message.py +0 -0
mirascope/llm/exceptions.py
CHANGED
|
@@ -1,360 +1,105 @@
|
|
|
1
|
-
"""Mirascope
|
|
1
|
+
"""Mirascope exception hierarchy for unified error handling across providers."""
|
|
2
2
|
|
|
3
|
-
import json
|
|
4
3
|
from typing import TYPE_CHECKING
|
|
5
4
|
|
|
6
|
-
from pydantic import ValidationError
|
|
7
|
-
|
|
8
5
|
if TYPE_CHECKING:
|
|
9
|
-
from .
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class Error(Exception):
|
|
13
|
-
"""Base exception for all Mirascope LLM errors."""
|
|
14
|
-
|
|
6
|
+
from .clients import ModelId, Provider
|
|
7
|
+
from .formatting import FormattingMode
|
|
15
8
|
|
|
16
|
-
class ProviderError(Error):
|
|
17
|
-
"""Base class for errors that originate from a provider SDK.
|
|
18
9
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
"""
|
|
22
|
-
|
|
23
|
-
provider: "ProviderId"
|
|
24
|
-
"""The provider that raised this error."""
|
|
10
|
+
class MirascopeError(Exception):
|
|
11
|
+
"""Base exception for all Mirascope errors."""
|
|
25
12
|
|
|
26
13
|
original_exception: Exception | None
|
|
27
|
-
"""The original exception from the provider SDK, if available."""
|
|
28
|
-
|
|
29
|
-
def __init__(
|
|
30
|
-
self,
|
|
31
|
-
message: str,
|
|
32
|
-
provider: "ProviderId",
|
|
33
|
-
original_exception: Exception | None = None,
|
|
34
|
-
) -> None:
|
|
35
|
-
super().__init__(message)
|
|
36
|
-
self.provider = provider
|
|
37
|
-
self.original_exception = original_exception
|
|
38
|
-
if original_exception is not None:
|
|
39
|
-
self.__cause__ = original_exception
|
|
40
14
|
|
|
41
15
|
|
|
42
|
-
class APIError(
|
|
43
|
-
"""Base class for
|
|
16
|
+
class APIError(MirascopeError):
|
|
17
|
+
"""Base class for API-related errors."""
|
|
44
18
|
|
|
45
19
|
status_code: int | None
|
|
46
|
-
"""The HTTP status code, if available."""
|
|
47
20
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
provider: "ProviderId",
|
|
52
|
-
status_code: int | None = None,
|
|
53
|
-
original_exception: Exception | None = None,
|
|
54
|
-
) -> None:
|
|
55
|
-
super().__init__(message, provider, original_exception)
|
|
56
|
-
self.status_code = status_code
|
|
21
|
+
|
|
22
|
+
class ConnectionError(MirascopeError):
|
|
23
|
+
"""Raised when unable to connect to the API (network issues, timeouts)."""
|
|
57
24
|
|
|
58
25
|
|
|
59
26
|
class AuthenticationError(APIError):
|
|
60
27
|
"""Raised for authentication failures (401, invalid API keys)."""
|
|
61
28
|
|
|
62
|
-
def __init__(
|
|
63
|
-
self,
|
|
64
|
-
message: str,
|
|
65
|
-
provider: "ProviderId",
|
|
66
|
-
status_code: int | None = None,
|
|
67
|
-
original_exception: Exception | None = None,
|
|
68
|
-
) -> None:
|
|
69
|
-
super().__init__(
|
|
70
|
-
message,
|
|
71
|
-
provider,
|
|
72
|
-
status_code=status_code or 401,
|
|
73
|
-
original_exception=original_exception,
|
|
74
|
-
)
|
|
75
|
-
|
|
76
29
|
|
|
77
30
|
class PermissionError(APIError):
|
|
78
31
|
"""Raised for permission/authorization failures (403)."""
|
|
79
32
|
|
|
80
|
-
def __init__(
|
|
81
|
-
self,
|
|
82
|
-
message: str,
|
|
83
|
-
provider: "ProviderId",
|
|
84
|
-
status_code: int | None = None,
|
|
85
|
-
original_exception: Exception | None = None,
|
|
86
|
-
) -> None:
|
|
87
|
-
super().__init__(
|
|
88
|
-
message,
|
|
89
|
-
provider,
|
|
90
|
-
status_code=status_code or 403,
|
|
91
|
-
original_exception=original_exception,
|
|
92
|
-
)
|
|
93
|
-
|
|
94
33
|
|
|
95
34
|
class BadRequestError(APIError):
|
|
96
35
|
"""Raised for malformed requests (400, 422)."""
|
|
97
36
|
|
|
98
|
-
def __init__(
|
|
99
|
-
self,
|
|
100
|
-
message: str,
|
|
101
|
-
provider: "ProviderId",
|
|
102
|
-
status_code: int | None = None,
|
|
103
|
-
original_exception: Exception | None = None,
|
|
104
|
-
) -> None:
|
|
105
|
-
super().__init__(
|
|
106
|
-
message,
|
|
107
|
-
provider,
|
|
108
|
-
status_code=status_code or 400,
|
|
109
|
-
original_exception=original_exception,
|
|
110
|
-
)
|
|
111
|
-
|
|
112
37
|
|
|
113
38
|
class NotFoundError(APIError):
|
|
114
39
|
"""Raised when requested resource is not found (404)."""
|
|
115
40
|
|
|
116
|
-
def __init__(
|
|
117
|
-
self,
|
|
118
|
-
message: str,
|
|
119
|
-
provider: "ProviderId",
|
|
120
|
-
status_code: int | None = None,
|
|
121
|
-
original_exception: Exception | None = None,
|
|
122
|
-
) -> None:
|
|
123
|
-
super().__init__(
|
|
124
|
-
message,
|
|
125
|
-
provider,
|
|
126
|
-
status_code=status_code or 404,
|
|
127
|
-
original_exception=original_exception,
|
|
128
|
-
)
|
|
129
41
|
|
|
42
|
+
class ToolNotFoundError(MirascopeError):
|
|
43
|
+
"""Raised if a tool_call cannot be converted to any corresponding tool."""
|
|
130
44
|
|
|
131
|
-
class RateLimitError(APIError):
|
|
132
|
-
"""Raised when rate limits are exceeded (429)."""
|
|
133
45
|
|
|
134
|
-
|
|
135
|
-
self,
|
|
136
|
-
message: str,
|
|
137
|
-
provider: "ProviderId",
|
|
138
|
-
status_code: int | None = None,
|
|
139
|
-
original_exception: Exception | None = None,
|
|
140
|
-
) -> None:
|
|
141
|
-
super().__init__(
|
|
142
|
-
message,
|
|
143
|
-
provider,
|
|
144
|
-
status_code=status_code or 429,
|
|
145
|
-
original_exception=original_exception,
|
|
146
|
-
)
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
class ServerError(APIError):
|
|
150
|
-
"""Raised for server-side errors (500+)."""
|
|
151
|
-
|
|
152
|
-
def __init__(
|
|
153
|
-
self,
|
|
154
|
-
message: str,
|
|
155
|
-
provider: "ProviderId",
|
|
156
|
-
status_code: int | None = None,
|
|
157
|
-
original_exception: Exception | None = None,
|
|
158
|
-
) -> None:
|
|
159
|
-
super().__init__(
|
|
160
|
-
message,
|
|
161
|
-
provider,
|
|
162
|
-
status_code=status_code or 500,
|
|
163
|
-
original_exception=original_exception,
|
|
164
|
-
)
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
class ConnectionError(ProviderError):
|
|
168
|
-
"""Raised when unable to connect to the API (network issues, timeouts)."""
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
class TimeoutError(ProviderError):
|
|
172
|
-
"""Raised when requests timeout or deadline exceeded."""
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
class ResponseValidationError(ProviderError):
|
|
176
|
-
"""Raised when API response fails validation.
|
|
177
|
-
|
|
178
|
-
This wraps the APIResponseValidationErrors that OpenAI and Anthropic both return.
|
|
179
|
-
"""
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
class ToolError(Error):
|
|
183
|
-
"""Base class for errors that occur during tool execution."""
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
class ToolExecutionError(ToolError):
|
|
187
|
-
"""Raised if an uncaught exception is thrown while executing a tool."""
|
|
188
|
-
|
|
189
|
-
tool_exception: Exception
|
|
190
|
-
"""The exception that was thrown while executing the tool."""
|
|
191
|
-
|
|
192
|
-
def __init__(self, tool_exception: Exception | str) -> None:
|
|
193
|
-
if isinstance(tool_exception, str):
|
|
194
|
-
# Support string for snapshot reconstruction
|
|
195
|
-
message = tool_exception
|
|
196
|
-
tool_exception = ValueError(message)
|
|
197
|
-
else:
|
|
198
|
-
message = str(tool_exception)
|
|
199
|
-
super().__init__(message)
|
|
200
|
-
self.tool_exception = tool_exception
|
|
201
|
-
self.__cause__ = tool_exception
|
|
202
|
-
|
|
203
|
-
def __eq__(self, other: object) -> bool:
|
|
204
|
-
if not isinstance(other, ToolExecutionError):
|
|
205
|
-
return False
|
|
206
|
-
# Needed for snapshot tests.
|
|
207
|
-
return str(self) == str(other)
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
class ToolNotFoundError(ToolError):
|
|
211
|
-
"""Raised if a tool call does not match any registered tool."""
|
|
212
|
-
|
|
213
|
-
tool_name: str
|
|
214
|
-
"""The name of the tool that was not found."""
|
|
215
|
-
|
|
216
|
-
def __init__(self, tool_name: str) -> None:
|
|
217
|
-
super().__init__(f"Tool '{tool_name}' not found in registered tools")
|
|
218
|
-
self.tool_name = tool_name
|
|
219
|
-
|
|
220
|
-
def __repr__(self) -> str:
|
|
221
|
-
return f"ToolNotFoundError({self.tool_name!r})"
|
|
222
|
-
|
|
223
|
-
def __eq__(self, other: object) -> bool:
|
|
224
|
-
if not isinstance(other, ToolNotFoundError):
|
|
225
|
-
return NotImplemented
|
|
226
|
-
return self.tool_name == other.tool_name
|
|
227
|
-
|
|
228
|
-
def __hash__(self) -> int:
|
|
229
|
-
return hash((type(self), self.tool_name))
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
class ParseError(Error):
|
|
233
|
-
"""Raised when response.parse() fails to parse the response content.
|
|
234
|
-
|
|
235
|
-
This wraps errors from JSON extraction, JSON parsing, Pydantic validation,
|
|
236
|
-
or custom OutputParser functions.
|
|
237
|
-
"""
|
|
238
|
-
|
|
239
|
-
original_exception: Exception
|
|
240
|
-
"""The original exception that caused the parse failure."""
|
|
241
|
-
|
|
242
|
-
def __init__(
|
|
243
|
-
self,
|
|
244
|
-
message: str,
|
|
245
|
-
original_exception: Exception,
|
|
246
|
-
) -> None:
|
|
247
|
-
super().__init__(message)
|
|
248
|
-
self.original_exception = original_exception
|
|
249
|
-
self.__cause__ = original_exception
|
|
250
|
-
|
|
251
|
-
def retry_message(self) -> str:
|
|
252
|
-
"""Generate a message suitable for retrying with the LLM.
|
|
253
|
-
|
|
254
|
-
Returns a user-friendly message describing what went wrong,
|
|
255
|
-
suitable for including in a retry prompt.
|
|
256
|
-
"""
|
|
257
|
-
|
|
258
|
-
if isinstance(self.original_exception, ValidationError):
|
|
259
|
-
return (
|
|
260
|
-
f"Your response failed schema validation:\n"
|
|
261
|
-
f"{self.original_exception}\n\n"
|
|
262
|
-
"Please correct these issues and respond again."
|
|
263
|
-
)
|
|
264
|
-
elif isinstance(self.original_exception, json.JSONDecodeError):
|
|
265
|
-
# JSON syntax error
|
|
266
|
-
return (
|
|
267
|
-
"Your response could not be parsed because no valid JSON object "
|
|
268
|
-
"was found. Please ensure your response contains a JSON object "
|
|
269
|
-
"with opening '{' and closing '}' braces."
|
|
270
|
-
)
|
|
271
|
-
else:
|
|
272
|
-
# ValueError from JSON extraction, or OutputParser error
|
|
273
|
-
return (
|
|
274
|
-
f"Your response could not be parsed: {self.original_exception}\n\n"
|
|
275
|
-
"Please ensure your response matches the expected format."
|
|
276
|
-
)
|
|
277
|
-
|
|
278
|
-
def __eq__(self, other: object) -> bool:
|
|
279
|
-
if not isinstance(other, ParseError):
|
|
280
|
-
return False
|
|
281
|
-
return str(self) == str(other)
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
class FeatureNotSupportedError(Error):
|
|
46
|
+
class FeatureNotSupportedError(MirascopeError):
|
|
285
47
|
"""Raised if a Mirascope feature is unsupported by chosen provider.
|
|
286
48
|
|
|
287
49
|
If compatibility is model-specific, then `model_id` should be specified.
|
|
288
|
-
If the feature is not supported by the provider at all, then it may be `None`.
|
|
289
|
-
"""
|
|
50
|
+
If the feature is not supported by the provider at all, then it may be `None`."""
|
|
290
51
|
|
|
291
|
-
|
|
52
|
+
provider: "Provider"
|
|
292
53
|
model_id: "ModelId | None"
|
|
293
54
|
feature: str
|
|
294
55
|
|
|
295
56
|
def __init__(
|
|
296
57
|
self,
|
|
297
58
|
feature: str,
|
|
298
|
-
|
|
59
|
+
provider: "Provider",
|
|
299
60
|
model_id: "ModelId | None" = None,
|
|
300
61
|
message: str | None = None,
|
|
301
62
|
) -> None:
|
|
302
63
|
if message is None:
|
|
303
64
|
model_msg = f" for model '{model_id}'" if model_id is not None else ""
|
|
304
|
-
message = f"Feature '{feature}' is not supported by provider '{
|
|
65
|
+
message = f"Feature '{feature}' is not supported by provider '{provider}'{model_msg}"
|
|
305
66
|
super().__init__(message)
|
|
306
67
|
self.feature = feature
|
|
307
|
-
self.
|
|
68
|
+
self.provider = provider
|
|
308
69
|
self.model_id = model_id
|
|
309
70
|
|
|
310
71
|
|
|
311
|
-
class
|
|
312
|
-
"""Raised when
|
|
72
|
+
class FormattingModeNotSupportedError(FeatureNotSupportedError):
|
|
73
|
+
"""Raised when trying to use a formatting mode that is not supported by the chosen model."""
|
|
313
74
|
|
|
314
|
-
|
|
75
|
+
formatting_mode: "FormattingMode"
|
|
315
76
|
|
|
316
|
-
def __init__(
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
77
|
+
def __init__(
|
|
78
|
+
self,
|
|
79
|
+
formatting_mode: "FormattingMode",
|
|
80
|
+
provider: "Provider",
|
|
81
|
+
model_id: "ModelId | None" = None,
|
|
82
|
+
message: str | None = None,
|
|
83
|
+
) -> None:
|
|
84
|
+
if message is None:
|
|
85
|
+
model_msg = f" for model '{model_id}'" if model_id is not None else ""
|
|
86
|
+
message = f"Formatting mode '{formatting_mode}' is not supported by provider '{provider}'{model_msg}"
|
|
87
|
+
super().__init__(
|
|
88
|
+
feature=f"formatting_mode:{formatting_mode}",
|
|
89
|
+
provider=provider,
|
|
90
|
+
model_id=model_id,
|
|
91
|
+
message=message,
|
|
320
92
|
)
|
|
321
|
-
|
|
322
|
-
self.model_id = model_id
|
|
93
|
+
self.formatting_mode = formatting_mode
|
|
323
94
|
|
|
324
95
|
|
|
325
|
-
class
|
|
326
|
-
"""Raised when
|
|
96
|
+
class RateLimitError(APIError):
|
|
97
|
+
"""Raised when rate limits are exceeded (429)."""
|
|
327
98
|
|
|
328
|
-
This error is raised during auto-registration when the required API key
|
|
329
|
-
environment variable is not set. If a Mirascope fallback is available,
|
|
330
|
-
the error message will suggest using MIRASCOPE_API_KEY as an alternative.
|
|
331
|
-
"""
|
|
332
99
|
|
|
333
|
-
|
|
334
|
-
"""
|
|
100
|
+
class ServerError(APIError):
|
|
101
|
+
"""Raised for server-side errors (500+)."""
|
|
335
102
|
|
|
336
|
-
env_var: str
|
|
337
|
-
"""The environment variable that should contain the API key."""
|
|
338
103
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
provider_id: str,
|
|
342
|
-
env_var: str,
|
|
343
|
-
has_mirascope_fallback: bool = False,
|
|
344
|
-
) -> None:
|
|
345
|
-
if has_mirascope_fallback:
|
|
346
|
-
message = (
|
|
347
|
-
f"No API key found for {provider_id}. Either:\n"
|
|
348
|
-
f" 1. Set {env_var} environment variable, or\n"
|
|
349
|
-
f" 2. Set MIRASCOPE_API_KEY for cross-provider support "
|
|
350
|
-
f"via Mirascope Router\n"
|
|
351
|
-
f" (Learn more: https://mirascope.com/docs/router)"
|
|
352
|
-
)
|
|
353
|
-
else:
|
|
354
|
-
message = (
|
|
355
|
-
f"No API key found for {provider_id}. "
|
|
356
|
-
f"Set the {env_var} environment variable."
|
|
357
|
-
)
|
|
358
|
-
super().__init__(message)
|
|
359
|
-
self.provider_id = provider_id
|
|
360
|
-
self.env_var = env_var
|
|
104
|
+
class TimeoutError(MirascopeError):
|
|
105
|
+
"""Raised when requests timeout or deadline exceeded."""
|
|
@@ -3,22 +3,12 @@
|
|
|
3
3
|
This module provides a way to define structured output formats for LLM responses.
|
|
4
4
|
The `@format` decorator can be applied to classes to specify how LLM
|
|
5
5
|
outputs should be structured and parsed.
|
|
6
|
-
|
|
7
|
-
The `@output_parser` decorator can be used to create custom parsers for non-JSON
|
|
8
|
-
formats like XML, YAML, CSV, or any custom text structure.
|
|
9
6
|
"""
|
|
10
7
|
|
|
11
|
-
from .format import
|
|
8
|
+
from .format import format, resolve_format
|
|
12
9
|
from .from_call_args import FromCallArgs
|
|
13
|
-
from .output_parser import OutputParser, is_output_parser, output_parser
|
|
14
10
|
from .partial import Partial
|
|
15
|
-
from .
|
|
16
|
-
PrimitiveType,
|
|
17
|
-
PrimitiveWrapperModel,
|
|
18
|
-
create_wrapper_model,
|
|
19
|
-
is_primitive_type,
|
|
20
|
-
)
|
|
21
|
-
from .types import FormattableT, FormattingMode
|
|
11
|
+
from .types import Format, FormattableT, FormattingMode
|
|
22
12
|
|
|
23
13
|
__all__ = [
|
|
24
14
|
"Format",
|
|
@@ -26,14 +16,7 @@ __all__ = [
|
|
|
26
16
|
"FormattableT",
|
|
27
17
|
"FormattingMode",
|
|
28
18
|
"FromCallArgs",
|
|
29
|
-
"OutputParser",
|
|
30
19
|
"Partial",
|
|
31
|
-
"PrimitiveType",
|
|
32
|
-
"PrimitiveWrapperModel",
|
|
33
|
-
"create_wrapper_model",
|
|
34
20
|
"format",
|
|
35
|
-
"is_output_parser",
|
|
36
|
-
"is_primitive_type",
|
|
37
|
-
"output_parser",
|
|
38
21
|
"resolve_format",
|
|
39
22
|
]
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"""Utilities for the formatting module."""
|
|
2
|
+
|
|
3
|
+
import inspect
|
|
4
|
+
import json
|
|
5
|
+
|
|
6
|
+
from ..tools import FORMAT_TOOL_NAME, ToolParameterSchema, ToolSchema
|
|
7
|
+
from .types import Format, FormattableT, FormattingMode
|
|
8
|
+
|
|
9
|
+
TOOL_MODE_INSTRUCTIONS = f"""Always respond to the user's query using the {FORMAT_TOOL_NAME} tool for structured output."""
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
JSON_MODE_INSTRUCTIONS = (
|
|
13
|
+
"Respond only with valid JSON that matches this exact schema:\n{json_schema}"
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def default_formatting_instructions(
|
|
18
|
+
schema: dict[str, object], mode: FormattingMode
|
|
19
|
+
) -> str | None:
|
|
20
|
+
"""Generate formatting instructions for the given mode and format info."""
|
|
21
|
+
|
|
22
|
+
if mode == "tool":
|
|
23
|
+
return TOOL_MODE_INSTRUCTIONS
|
|
24
|
+
elif mode == "json":
|
|
25
|
+
json_schema = json.dumps(schema, indent=2)
|
|
26
|
+
instructions = JSON_MODE_INSTRUCTIONS.format(json_schema=json_schema)
|
|
27
|
+
return inspect.cleandoc(instructions)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def create_tool_schema(format: Format[FormattableT]) -> ToolSchema:
|
|
31
|
+
"""Convert a `Format` to a `ToolSchema` for format parsing.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
format: The `Format` instance containing schema and metadata
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
`ToolSchema` for the format tool
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
schema_dict = format.schema.copy()
|
|
41
|
+
schema_dict["type"] = "object"
|
|
42
|
+
|
|
43
|
+
properties = schema_dict.get("properties")
|
|
44
|
+
if not properties or not isinstance(properties, dict):
|
|
45
|
+
properties = {} # pragma: no cover
|
|
46
|
+
required = list(properties.keys())
|
|
47
|
+
|
|
48
|
+
description = (
|
|
49
|
+
f"Use this tool to extract data in {format.name} format for a final response."
|
|
50
|
+
)
|
|
51
|
+
if format.description:
|
|
52
|
+
description += "\n" + format.description
|
|
53
|
+
|
|
54
|
+
parameters = ToolParameterSchema(
|
|
55
|
+
properties=properties,
|
|
56
|
+
required=required,
|
|
57
|
+
additionalProperties=False,
|
|
58
|
+
)
|
|
59
|
+
if "$defs" in schema_dict and isinstance(schema_dict["$defs"], dict):
|
|
60
|
+
parameters.defs = schema_dict["$defs"]
|
|
61
|
+
|
|
62
|
+
def _unused_format_fn() -> None:
|
|
63
|
+
raise TypeError(
|
|
64
|
+
"Format tool function should not be called."
|
|
65
|
+
) # pragma: no cover
|
|
66
|
+
|
|
67
|
+
tool_schema = ToolSchema.__new__(ToolSchema)
|
|
68
|
+
tool_schema.fn = _unused_format_fn
|
|
69
|
+
tool_schema.name = FORMAT_TOOL_NAME
|
|
70
|
+
tool_schema.description = description
|
|
71
|
+
tool_schema.parameters = parameters
|
|
72
|
+
tool_schema.strict = True
|
|
73
|
+
|
|
74
|
+
return tool_schema
|