mirascope 2.0.0a5__py3-none-any.whl → 2.0.1__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 +10 -1
- mirascope/_stubs.py +363 -0
- mirascope/api/__init__.py +8 -0
- mirascope/api/_generated/__init__.py +285 -2
- mirascope/api/_generated/annotations/__init__.py +33 -0
- mirascope/api/_generated/annotations/client.py +506 -0
- mirascope/api/_generated/annotations/raw_client.py +1414 -0
- mirascope/api/_generated/annotations/types/__init__.py +31 -0
- mirascope/api/_generated/annotations/types/annotations_create_request_label.py +5 -0
- mirascope/api/_generated/annotations/types/annotations_create_response.py +48 -0
- mirascope/api/_generated/annotations/types/annotations_create_response_label.py +5 -0
- mirascope/api/_generated/annotations/types/annotations_get_response.py +48 -0
- mirascope/api/_generated/annotations/types/annotations_get_response_label.py +5 -0
- mirascope/api/_generated/annotations/types/annotations_list_request_label.py +5 -0
- mirascope/api/_generated/annotations/types/annotations_list_response.py +21 -0
- mirascope/api/_generated/annotations/types/annotations_list_response_annotations_item.py +50 -0
- mirascope/api/_generated/annotations/types/annotations_list_response_annotations_item_label.py +5 -0
- mirascope/api/_generated/annotations/types/annotations_update_request_label.py +5 -0
- mirascope/api/_generated/annotations/types/annotations_update_response.py +48 -0
- mirascope/api/_generated/annotations/types/annotations_update_response_label.py +5 -0
- mirascope/api/_generated/api_keys/__init__.py +12 -2
- mirascope/api/_generated/api_keys/client.py +77 -0
- mirascope/api/_generated/api_keys/raw_client.py +422 -39
- mirascope/api/_generated/api_keys/types/__init__.py +7 -1
- mirascope/api/_generated/api_keys/types/api_keys_create_response.py +4 -12
- mirascope/api/_generated/api_keys/types/api_keys_get_response.py +4 -12
- mirascope/api/_generated/api_keys/types/api_keys_list_all_for_org_response_item.py +40 -0
- mirascope/api/_generated/api_keys/types/api_keys_list_response_item.py +4 -12
- mirascope/api/_generated/client.py +42 -0
- mirascope/api/_generated/core/client_wrapper.py +2 -14
- mirascope/api/_generated/core/datetime_utils.py +1 -3
- mirascope/api/_generated/core/file.py +2 -5
- mirascope/api/_generated/core/http_client.py +36 -112
- mirascope/api/_generated/core/jsonable_encoder.py +1 -3
- mirascope/api/_generated/core/pydantic_utilities.py +19 -74
- mirascope/api/_generated/core/query_encoder.py +1 -3
- mirascope/api/_generated/core/serialization.py +4 -10
- mirascope/api/_generated/docs/client.py +2 -6
- mirascope/api/_generated/docs/raw_client.py +51 -5
- mirascope/api/_generated/environment.py +3 -3
- mirascope/api/_generated/environments/__init__.py +6 -0
- mirascope/api/_generated/environments/client.py +117 -0
- mirascope/api/_generated/environments/raw_client.py +530 -51
- mirascope/api/_generated/environments/types/__init__.py +10 -0
- mirascope/api/_generated/environments/types/environments_create_response.py +1 -3
- mirascope/api/_generated/environments/types/environments_get_analytics_response.py +60 -0
- mirascope/api/_generated/environments/types/environments_get_analytics_response_top_functions_item.py +24 -0
- mirascope/api/_generated/environments/types/environments_get_analytics_response_top_models_item.py +22 -0
- mirascope/api/_generated/environments/types/environments_get_response.py +1 -3
- mirascope/api/_generated/environments/types/environments_list_response_item.py +1 -3
- mirascope/api/_generated/environments/types/environments_update_response.py +1 -3
- mirascope/api/_generated/errors/__init__.py +8 -0
- mirascope/api/_generated/errors/bad_request_error.py +1 -2
- mirascope/api/_generated/errors/conflict_error.py +1 -2
- mirascope/api/_generated/errors/forbidden_error.py +1 -5
- mirascope/api/_generated/errors/internal_server_error.py +1 -6
- mirascope/api/_generated/errors/not_found_error.py +1 -5
- mirascope/api/_generated/errors/payment_required_error.py +15 -0
- mirascope/api/_generated/errors/service_unavailable_error.py +14 -0
- mirascope/api/_generated/errors/too_many_requests_error.py +15 -0
- mirascope/api/_generated/errors/unauthorized_error.py +11 -0
- mirascope/api/_generated/functions/__init__.py +39 -0
- mirascope/api/_generated/functions/client.py +647 -0
- mirascope/api/_generated/functions/raw_client.py +1890 -0
- mirascope/api/_generated/functions/types/__init__.py +53 -0
- mirascope/api/_generated/functions/types/functions_create_request_dependencies_value.py +20 -0
- mirascope/api/_generated/functions/types/functions_create_response.py +37 -0
- mirascope/api/_generated/functions/types/functions_create_response_dependencies_value.py +20 -0
- mirascope/api/_generated/functions/types/functions_find_by_hash_response.py +39 -0
- mirascope/api/_generated/functions/types/functions_find_by_hash_response_dependencies_value.py +20 -0
- mirascope/api/_generated/functions/types/functions_get_by_env_response.py +53 -0
- mirascope/api/_generated/functions/types/functions_get_by_env_response_dependencies_value.py +22 -0
- mirascope/api/_generated/functions/types/functions_get_response.py +37 -0
- mirascope/api/_generated/functions/types/functions_get_response_dependencies_value.py +20 -0
- mirascope/api/_generated/functions/types/functions_list_by_env_response.py +25 -0
- mirascope/api/_generated/functions/types/functions_list_by_env_response_functions_item.py +56 -0
- mirascope/api/_generated/functions/types/functions_list_by_env_response_functions_item_dependencies_value.py +22 -0
- mirascope/api/_generated/functions/types/functions_list_response.py +21 -0
- mirascope/api/_generated/functions/types/functions_list_response_functions_item.py +41 -0
- mirascope/api/_generated/functions/types/functions_list_response_functions_item_dependencies_value.py +20 -0
- mirascope/api/_generated/health/client.py +2 -6
- mirascope/api/_generated/health/raw_client.py +51 -5
- mirascope/api/_generated/health/types/health_check_response.py +1 -3
- mirascope/api/_generated/organization_invitations/__init__.py +33 -0
- mirascope/api/_generated/organization_invitations/client.py +546 -0
- mirascope/api/_generated/organization_invitations/raw_client.py +1519 -0
- mirascope/api/_generated/organization_invitations/types/__init__.py +53 -0
- mirascope/api/_generated/organization_invitations/types/organization_invitations_accept_response.py +34 -0
- mirascope/api/_generated/organization_invitations/types/organization_invitations_accept_response_role.py +7 -0
- mirascope/api/_generated/organization_invitations/types/organization_invitations_create_request_role.py +7 -0
- mirascope/api/_generated/organization_invitations/types/organization_invitations_create_response.py +48 -0
- mirascope/api/_generated/organization_invitations/types/organization_invitations_create_response_role.py +7 -0
- mirascope/api/_generated/organization_invitations/types/organization_invitations_create_response_status.py +7 -0
- mirascope/api/_generated/organization_invitations/types/organization_invitations_get_response.py +48 -0
- mirascope/api/_generated/organization_invitations/types/organization_invitations_get_response_role.py +7 -0
- mirascope/api/_generated/organization_invitations/types/organization_invitations_get_response_status.py +7 -0
- mirascope/api/_generated/organization_invitations/types/organization_invitations_list_response_item.py +48 -0
- mirascope/api/_generated/organization_invitations/types/organization_invitations_list_response_item_role.py +7 -0
- mirascope/api/_generated/organization_invitations/types/organization_invitations_list_response_item_status.py +7 -0
- mirascope/api/_generated/organization_memberships/__init__.py +19 -0
- mirascope/api/_generated/organization_memberships/client.py +302 -0
- mirascope/api/_generated/organization_memberships/raw_client.py +736 -0
- mirascope/api/_generated/organization_memberships/types/__init__.py +27 -0
- mirascope/api/_generated/organization_memberships/types/organization_memberships_list_response_item.py +33 -0
- mirascope/api/_generated/organization_memberships/types/organization_memberships_list_response_item_role.py +7 -0
- mirascope/api/_generated/organization_memberships/types/organization_memberships_update_request_role.py +7 -0
- mirascope/api/_generated/organization_memberships/types/organization_memberships_update_response.py +31 -0
- mirascope/api/_generated/organization_memberships/types/organization_memberships_update_response_role.py +7 -0
- mirascope/api/_generated/organizations/__init__.py +26 -0
- mirascope/api/_generated/organizations/client.py +465 -0
- mirascope/api/_generated/organizations/raw_client.py +1799 -108
- mirascope/api/_generated/organizations/types/__init__.py +48 -0
- mirascope/api/_generated/organizations/types/organizations_create_payment_intent_response.py +24 -0
- mirascope/api/_generated/organizations/types/organizations_create_response.py +4 -3
- mirascope/api/_generated/organizations/types/organizations_create_response_role.py +1 -3
- mirascope/api/_generated/organizations/types/organizations_get_response.py +4 -3
- mirascope/api/_generated/organizations/types/organizations_get_response_role.py +1 -3
- mirascope/api/_generated/organizations/types/organizations_list_response_item.py +4 -3
- mirascope/api/_generated/organizations/types/organizations_list_response_item_role.py +1 -3
- mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_request_target_plan.py +7 -0
- mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_response.py +47 -0
- mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_response_validation_errors_item.py +33 -0
- mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_response_validation_errors_item_resource.py +7 -0
- mirascope/api/_generated/organizations/types/organizations_router_balance_response.py +24 -0
- mirascope/api/_generated/organizations/types/organizations_subscription_response.py +53 -0
- mirascope/api/_generated/organizations/types/organizations_subscription_response_current_plan.py +7 -0
- mirascope/api/_generated/organizations/types/organizations_subscription_response_payment_method.py +26 -0
- mirascope/api/_generated/organizations/types/organizations_subscription_response_scheduled_change.py +34 -0
- mirascope/api/_generated/organizations/types/organizations_subscription_response_scheduled_change_target_plan.py +7 -0
- mirascope/api/_generated/organizations/types/organizations_update_response.py +4 -3
- mirascope/api/_generated/organizations/types/organizations_update_response_role.py +1 -3
- mirascope/api/_generated/organizations/types/organizations_update_subscription_request_target_plan.py +7 -0
- mirascope/api/_generated/organizations/types/organizations_update_subscription_response.py +35 -0
- mirascope/api/_generated/project_memberships/__init__.py +25 -0
- mirascope/api/_generated/project_memberships/client.py +437 -0
- mirascope/api/_generated/project_memberships/raw_client.py +1039 -0
- mirascope/api/_generated/project_memberships/types/__init__.py +29 -0
- mirascope/api/_generated/project_memberships/types/project_memberships_create_request_role.py +7 -0
- mirascope/api/_generated/project_memberships/types/project_memberships_create_response.py +35 -0
- mirascope/api/_generated/project_memberships/types/project_memberships_create_response_role.py +7 -0
- mirascope/api/_generated/project_memberships/types/project_memberships_list_response_item.py +33 -0
- mirascope/api/_generated/project_memberships/types/project_memberships_list_response_item_role.py +7 -0
- mirascope/api/_generated/project_memberships/types/project_memberships_update_request_role.py +7 -0
- mirascope/api/_generated/project_memberships/types/project_memberships_update_response.py +35 -0
- mirascope/api/_generated/project_memberships/types/project_memberships_update_response_role.py +7 -0
- mirascope/api/_generated/projects/__init__.py +2 -12
- mirascope/api/_generated/projects/client.py +17 -71
- mirascope/api/_generated/projects/raw_client.py +295 -51
- mirascope/api/_generated/projects/types/__init__.py +1 -6
- mirascope/api/_generated/projects/types/projects_create_response.py +3 -9
- mirascope/api/_generated/projects/types/projects_get_response.py +3 -9
- mirascope/api/_generated/projects/types/projects_list_response_item.py +3 -9
- mirascope/api/_generated/projects/types/projects_update_response.py +3 -9
- mirascope/api/_generated/reference.md +3619 -182
- mirascope/api/_generated/tags/__init__.py +19 -0
- mirascope/api/_generated/tags/client.py +504 -0
- mirascope/api/_generated/tags/raw_client.py +1288 -0
- mirascope/api/_generated/tags/types/__init__.py +17 -0
- mirascope/api/_generated/tags/types/tags_create_response.py +41 -0
- mirascope/api/_generated/tags/types/tags_get_response.py +41 -0
- mirascope/api/_generated/tags/types/tags_list_response.py +23 -0
- mirascope/api/_generated/tags/types/tags_list_response_tags_item.py +41 -0
- mirascope/api/_generated/tags/types/tags_update_response.py +41 -0
- mirascope/api/_generated/token_cost/__init__.py +7 -0
- mirascope/api/_generated/token_cost/client.py +160 -0
- mirascope/api/_generated/token_cost/raw_client.py +264 -0
- mirascope/api/_generated/token_cost/types/__init__.py +8 -0
- mirascope/api/_generated/token_cost/types/token_cost_calculate_request_usage.py +54 -0
- mirascope/api/_generated/token_cost/types/token_cost_calculate_response.py +52 -0
- mirascope/api/_generated/traces/__init__.py +42 -0
- mirascope/api/_generated/traces/client.py +941 -0
- mirascope/api/_generated/traces/raw_client.py +2177 -23
- mirascope/api/_generated/traces/types/__init__.py +60 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item.py +4 -11
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource.py +2 -6
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item.py +1 -3
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value.py +8 -24
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_array_value.py +2 -6
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_kvlist_value.py +3 -9
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_kvlist_value_values_item.py +2 -6
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item.py +3 -9
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope.py +4 -8
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item.py +2 -6
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value.py +8 -24
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_array_value.py +2 -6
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_kvlist_value.py +3 -9
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_kvlist_value_values_item.py +1 -3
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item.py +6 -18
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item.py +3 -9
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value.py +8 -24
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_array_value.py +2 -6
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_kvlist_value.py +2 -6
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_kvlist_value_values_item.py +1 -3
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_status.py +2 -6
- mirascope/api/_generated/traces/types/traces_create_response.py +2 -5
- mirascope/api/_generated/traces/types/traces_create_response_partial_success.py +3 -9
- mirascope/api/_generated/traces/types/traces_get_analytics_summary_response.py +60 -0
- mirascope/api/_generated/traces/types/traces_get_analytics_summary_response_top_functions_item.py +24 -0
- mirascope/api/_generated/traces/types/traces_get_analytics_summary_response_top_models_item.py +22 -0
- mirascope/api/_generated/traces/types/traces_get_trace_detail_by_env_response.py +33 -0
- mirascope/api/_generated/traces/types/traces_get_trace_detail_by_env_response_spans_item.py +88 -0
- mirascope/api/_generated/traces/types/traces_get_trace_detail_response.py +33 -0
- mirascope/api/_generated/traces/types/traces_get_trace_detail_response_spans_item.py +88 -0
- mirascope/api/_generated/traces/types/traces_list_by_function_hash_response.py +25 -0
- mirascope/api/_generated/traces/types/traces_list_by_function_hash_response_traces_item.py +44 -0
- mirascope/api/_generated/traces/types/traces_search_by_env_request_attribute_filters_item.py +26 -0
- mirascope/api/_generated/traces/types/traces_search_by_env_request_attribute_filters_item_operator.py +7 -0
- mirascope/api/_generated/traces/types/traces_search_by_env_request_sort_by.py +7 -0
- mirascope/api/_generated/traces/types/traces_search_by_env_request_sort_order.py +7 -0
- mirascope/api/_generated/traces/types/traces_search_by_env_response.py +26 -0
- mirascope/api/_generated/traces/types/traces_search_by_env_response_spans_item.py +50 -0
- mirascope/api/_generated/traces/types/traces_search_request_attribute_filters_item.py +26 -0
- mirascope/api/_generated/traces/types/traces_search_request_attribute_filters_item_operator.py +7 -0
- mirascope/api/_generated/traces/types/traces_search_request_sort_by.py +7 -0
- mirascope/api/_generated/traces/types/traces_search_request_sort_order.py +5 -0
- mirascope/api/_generated/traces/types/traces_search_response.py +26 -0
- mirascope/api/_generated/traces/types/traces_search_response_spans_item.py +50 -0
- mirascope/api/_generated/types/__init__.py +48 -0
- mirascope/api/_generated/types/already_exists_error.py +1 -3
- mirascope/api/_generated/types/bad_request_error_body.py +50 -0
- mirascope/api/_generated/types/click_house_error.py +22 -0
- mirascope/api/_generated/types/database_error.py +1 -3
- mirascope/api/_generated/types/date.py +3 -0
- mirascope/api/_generated/types/http_api_decode_error.py +1 -3
- mirascope/api/_generated/types/immutable_resource_error.py +22 -0
- mirascope/api/_generated/types/internal_server_error_body.py +49 -0
- mirascope/api/_generated/types/issue.py +1 -3
- mirascope/api/_generated/types/issue_tag.py +1 -8
- mirascope/api/_generated/types/not_found_error_body.py +1 -3
- mirascope/api/_generated/types/number_from_string.py +3 -0
- mirascope/api/_generated/types/permission_denied_error.py +1 -3
- mirascope/api/_generated/types/permission_denied_error_tag.py +1 -3
- mirascope/api/_generated/types/plan_limit_exceeded_error.py +32 -0
- mirascope/api/_generated/types/plan_limit_exceeded_error_tag.py +7 -0
- mirascope/api/_generated/types/pricing_unavailable_error.py +23 -0
- mirascope/api/_generated/types/property_key_key.py +1 -3
- mirascope/api/_generated/types/rate_limit_error.py +31 -0
- mirascope/api/_generated/types/rate_limit_error_tag.py +5 -0
- mirascope/api/_generated/types/service_unavailable_error_body.py +24 -0
- mirascope/api/_generated/types/service_unavailable_error_tag.py +7 -0
- mirascope/api/_generated/types/stripe_error.py +20 -0
- mirascope/api/_generated/types/subscription_past_due_error.py +31 -0
- mirascope/api/_generated/types/subscription_past_due_error_tag.py +7 -0
- mirascope/api/_generated/types/unauthorized_error_body.py +21 -0
- mirascope/api/_generated/types/unauthorized_error_tag.py +5 -0
- mirascope/api/settings.py +19 -1
- mirascope/llm/__init__.py +55 -8
- mirascope/llm/calls/__init__.py +2 -1
- mirascope/llm/calls/calls.py +3 -1
- mirascope/llm/calls/decorator.py +21 -7
- mirascope/llm/content/tool_call.py +6 -0
- mirascope/llm/content/tool_output.py +22 -5
- mirascope/llm/exceptions.py +284 -71
- mirascope/llm/formatting/__init__.py +19 -2
- mirascope/llm/formatting/format.py +219 -30
- mirascope/llm/formatting/output_parser.py +178 -0
- mirascope/llm/formatting/partial.py +80 -7
- mirascope/llm/formatting/primitives.py +192 -0
- mirascope/llm/formatting/types.py +21 -64
- mirascope/llm/mcp/__init__.py +2 -2
- mirascope/llm/mcp/mcp_client.py +130 -0
- mirascope/llm/messages/__init__.py +3 -0
- mirascope/llm/messages/_utils.py +34 -0
- mirascope/llm/models/__init__.py +5 -0
- mirascope/llm/models/models.py +137 -69
- mirascope/llm/{providers/base → models}/params.py +16 -37
- mirascope/llm/models/thinking_config.py +61 -0
- mirascope/llm/prompts/_utils.py +0 -32
- mirascope/llm/prompts/decorator.py +16 -5
- mirascope/llm/prompts/prompts.py +131 -68
- mirascope/llm/providers/__init__.py +18 -2
- mirascope/llm/providers/anthropic/__init__.py +3 -21
- mirascope/llm/providers/anthropic/_utils/__init__.py +2 -0
- mirascope/llm/providers/anthropic/_utils/beta_decode.py +22 -11
- mirascope/llm/providers/anthropic/_utils/beta_encode.py +75 -25
- mirascope/llm/providers/anthropic/_utils/decode.py +22 -11
- mirascope/llm/providers/anthropic/_utils/encode.py +82 -20
- mirascope/llm/providers/anthropic/_utils/errors.py +2 -2
- mirascope/llm/providers/anthropic/beta_provider.py +64 -18
- mirascope/llm/providers/anthropic/provider.py +91 -33
- mirascope/llm/providers/base/__init__.py +0 -2
- mirascope/llm/providers/base/_utils.py +55 -11
- mirascope/llm/providers/base/base_provider.py +116 -37
- mirascope/llm/providers/google/__init__.py +2 -17
- mirascope/llm/providers/google/_utils/__init__.py +2 -0
- mirascope/llm/providers/google/_utils/decode.py +37 -15
- mirascope/llm/providers/google/_utils/encode.py +127 -19
- mirascope/llm/providers/google/_utils/errors.py +3 -2
- mirascope/llm/providers/google/model_info.py +1 -0
- mirascope/llm/providers/google/provider.py +68 -19
- mirascope/llm/providers/mirascope/__init__.py +5 -0
- mirascope/llm/providers/mirascope/_utils.py +73 -0
- mirascope/llm/providers/mirascope/provider.py +349 -0
- mirascope/llm/providers/mlx/__init__.py +2 -17
- mirascope/llm/providers/mlx/_utils.py +8 -3
- mirascope/llm/providers/mlx/encoding/base.py +5 -2
- mirascope/llm/providers/mlx/encoding/transformers.py +5 -2
- mirascope/llm/providers/mlx/mlx.py +23 -6
- mirascope/llm/providers/mlx/provider.py +42 -13
- mirascope/llm/providers/ollama/__init__.py +1 -13
- mirascope/llm/providers/openai/_utils/errors.py +2 -2
- mirascope/llm/providers/openai/completions/__init__.py +2 -20
- mirascope/llm/providers/openai/completions/_utils/decode.py +14 -3
- mirascope/llm/providers/openai/completions/_utils/encode.py +35 -28
- mirascope/llm/providers/openai/completions/base_provider.py +40 -11
- mirascope/llm/providers/openai/provider.py +40 -10
- mirascope/llm/providers/openai/responses/__init__.py +1 -17
- mirascope/llm/providers/openai/responses/_utils/__init__.py +2 -0
- mirascope/llm/providers/openai/responses/_utils/decode.py +21 -8
- mirascope/llm/providers/openai/responses/_utils/encode.py +59 -19
- mirascope/llm/providers/openai/responses/provider.py +56 -18
- mirascope/llm/providers/provider_id.py +1 -0
- mirascope/llm/providers/provider_registry.py +96 -19
- mirascope/llm/providers/together/__init__.py +1 -13
- mirascope/llm/responses/__init__.py +6 -1
- mirascope/llm/responses/_utils.py +102 -12
- mirascope/llm/responses/base_response.py +5 -2
- mirascope/llm/responses/base_stream_response.py +139 -45
- mirascope/llm/responses/response.py +2 -1
- mirascope/llm/responses/root_response.py +89 -17
- mirascope/llm/responses/stream_response.py +6 -9
- mirascope/llm/tools/decorator.py +17 -8
- mirascope/llm/tools/tool_schema.py +43 -10
- mirascope/llm/tools/toolkit.py +35 -27
- mirascope/llm/tools/tools.py +123 -30
- mirascope/ops/__init__.py +64 -109
- mirascope/ops/_internal/configuration.py +82 -31
- mirascope/ops/_internal/exporters/exporters.py +64 -11
- mirascope/ops/_internal/instrumentation/llm/common.py +530 -0
- mirascope/ops/_internal/instrumentation/llm/cost.py +190 -0
- mirascope/ops/_internal/instrumentation/llm/encode.py +1 -1
- mirascope/ops/_internal/instrumentation/llm/llm.py +116 -1243
- mirascope/ops/_internal/instrumentation/llm/model.py +1798 -0
- mirascope/ops/_internal/instrumentation/llm/response.py +521 -0
- mirascope/ops/_internal/instrumentation/llm/serialize.py +300 -0
- mirascope/ops/_internal/protocols.py +83 -1
- mirascope/ops/_internal/traced_calls.py +4 -0
- mirascope/ops/_internal/traced_functions.py +141 -12
- mirascope/ops/_internal/tracing.py +78 -1
- mirascope/ops/_internal/utils.py +52 -4
- mirascope/ops/_internal/versioned_functions.py +54 -43
- {mirascope-2.0.0a5.dist-info → mirascope-2.0.1.dist-info}/METADATA +14 -13
- mirascope-2.0.1.dist-info/RECORD +423 -0
- {mirascope-2.0.0a5.dist-info → mirascope-2.0.1.dist-info}/licenses/LICENSE +1 -1
- mirascope/llm/formatting/_utils.py +0 -78
- mirascope/llm/mcp/client.py +0 -118
- mirascope/llm/providers/_missing_import_stubs.py +0 -49
- mirascope-2.0.0a5.dist-info/RECORD +0 -265
- {mirascope-2.0.0a5.dist-info → mirascope-2.0.1.dist-info}/WHEEL +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Beta Anthropic message encoding and request preparation."""
|
|
2
2
|
|
|
3
3
|
from collections.abc import Sequence
|
|
4
|
-
from typing import Any, TypedDict, cast
|
|
4
|
+
from typing import TYPE_CHECKING, Any, TypedDict, cast
|
|
5
5
|
from typing_extensions import Required
|
|
6
6
|
|
|
7
7
|
from anthropic import Omit
|
|
@@ -17,26 +17,28 @@ from anthropic.types.beta import (
|
|
|
17
17
|
from pydantic import BaseModel
|
|
18
18
|
|
|
19
19
|
from ....content import ContentPart
|
|
20
|
-
from ....exceptions import
|
|
20
|
+
from ....exceptions import FeatureNotSupportedError
|
|
21
21
|
from ....formatting import (
|
|
22
22
|
Format,
|
|
23
23
|
FormattableT,
|
|
24
|
-
|
|
24
|
+
OutputParser,
|
|
25
25
|
resolve_format,
|
|
26
26
|
)
|
|
27
27
|
from ....messages import AssistantMessage, Message, UserMessage
|
|
28
28
|
from ....tools import AnyToolSchema, BaseToolkit
|
|
29
|
-
from ...base import
|
|
29
|
+
from ...base import _utils as _base_utils
|
|
30
30
|
from ..model_id import model_name
|
|
31
31
|
from ..model_info import MODELS_WITHOUT_STRICT_STRUCTURED_OUTPUTS
|
|
32
32
|
from .encode import (
|
|
33
33
|
DEFAULT_MAX_TOKENS,
|
|
34
34
|
FORMAT_TOOL_NAME,
|
|
35
|
-
convert_tool_to_tool_param,
|
|
36
35
|
encode_content,
|
|
37
36
|
process_params,
|
|
38
37
|
)
|
|
39
38
|
|
|
39
|
+
if TYPE_CHECKING:
|
|
40
|
+
from ....models import Params
|
|
41
|
+
|
|
40
42
|
DEFAULT_FORMAT_MODE = "strict"
|
|
41
43
|
|
|
42
44
|
|
|
@@ -60,11 +62,11 @@ class BetaParseKwargs(TypedDict, total=False):
|
|
|
60
62
|
|
|
61
63
|
def _beta_encode_content(
|
|
62
64
|
content: Sequence[ContentPart],
|
|
63
|
-
|
|
65
|
+
encode_thoughts_as_text: bool,
|
|
64
66
|
add_cache_control: bool = False,
|
|
65
67
|
) -> str | Sequence[BetaContentBlockParam]:
|
|
66
68
|
"""Convert mirascope content to Beta Anthropic content format."""
|
|
67
|
-
result = encode_content(content,
|
|
69
|
+
result = encode_content(content, encode_thoughts_as_text, add_cache_control)
|
|
68
70
|
if isinstance(result, str):
|
|
69
71
|
return result
|
|
70
72
|
return cast(Sequence[BetaContentBlockParam], result)
|
|
@@ -73,7 +75,7 @@ def _beta_encode_content(
|
|
|
73
75
|
def _beta_encode_message(
|
|
74
76
|
message: UserMessage | AssistantMessage,
|
|
75
77
|
model_id: str,
|
|
76
|
-
|
|
78
|
+
encode_thoughts_as_text: bool,
|
|
77
79
|
add_cache_control: bool = False,
|
|
78
80
|
) -> BetaMessageParam:
|
|
79
81
|
"""Convert user or assistant Message to Beta MessageParam format.
|
|
@@ -81,7 +83,7 @@ def _beta_encode_message(
|
|
|
81
83
|
Args:
|
|
82
84
|
message: The message to encode
|
|
83
85
|
model_id: The Anthropic model ID
|
|
84
|
-
|
|
86
|
+
encode_thoughts_as_text: Whether to encode thought blocks as text
|
|
85
87
|
add_cache_control: Whether to add cache_control to the last content block
|
|
86
88
|
"""
|
|
87
89
|
if (
|
|
@@ -89,7 +91,7 @@ def _beta_encode_message(
|
|
|
89
91
|
and message.provider_id == "anthropic"
|
|
90
92
|
and message.model_id == model_id
|
|
91
93
|
and message.raw_message
|
|
92
|
-
and not
|
|
94
|
+
and not encode_thoughts_as_text
|
|
93
95
|
and not add_cache_control
|
|
94
96
|
):
|
|
95
97
|
raw = cast(dict[str, Any], message.raw_message)
|
|
@@ -98,7 +100,9 @@ def _beta_encode_message(
|
|
|
98
100
|
content=raw["content"],
|
|
99
101
|
)
|
|
100
102
|
|
|
101
|
-
content = _beta_encode_content(
|
|
103
|
+
content = _beta_encode_content(
|
|
104
|
+
message.content, encode_thoughts_as_text, add_cache_control
|
|
105
|
+
)
|
|
102
106
|
|
|
103
107
|
return BetaMessageParam(
|
|
104
108
|
role=message.role,
|
|
@@ -109,7 +113,7 @@ def _beta_encode_message(
|
|
|
109
113
|
def _beta_encode_messages(
|
|
110
114
|
messages: Sequence[UserMessage | AssistantMessage],
|
|
111
115
|
model_id: str,
|
|
112
|
-
|
|
116
|
+
encode_thoughts_as_text: bool,
|
|
113
117
|
) -> Sequence[BetaMessageParam]:
|
|
114
118
|
"""Encode messages and add cache control for multi-turn conversations.
|
|
115
119
|
|
|
@@ -125,14 +129,34 @@ def _beta_encode_messages(
|
|
|
125
129
|
is_last = i == len(messages) - 1
|
|
126
130
|
add_cache = has_assistant_message and is_last
|
|
127
131
|
encoded_messages.append(
|
|
128
|
-
_beta_encode_message(message, model_id,
|
|
132
|
+
_beta_encode_message(message, model_id, encode_thoughts_as_text, add_cache)
|
|
129
133
|
)
|
|
130
134
|
return encoded_messages
|
|
131
135
|
|
|
132
136
|
|
|
133
|
-
def _beta_convert_tool_to_tool_param(
|
|
134
|
-
|
|
135
|
-
|
|
137
|
+
def _beta_convert_tool_to_tool_param(
|
|
138
|
+
tool: AnyToolSchema, model_supports_strict: bool
|
|
139
|
+
) -> BetaToolParam:
|
|
140
|
+
"""Convert a single Mirascope tool to Beta Anthropic tool format.
|
|
141
|
+
|
|
142
|
+
If the tool has strict=True (or None, and the model supports strict), the schema
|
|
143
|
+
is modified to be compatible with Anthropic's strict structured outputs beta
|
|
144
|
+
by adding additionalProperties: false to all object schemas, and strict=True
|
|
145
|
+
is passed to the API.
|
|
146
|
+
"""
|
|
147
|
+
schema_dict = tool.parameters.model_dump(by_alias=True, exclude_none=True)
|
|
148
|
+
schema_dict["type"] = "object"
|
|
149
|
+
|
|
150
|
+
strict = model_supports_strict if tool.strict is None else tool.strict
|
|
151
|
+
if strict:
|
|
152
|
+
_base_utils.ensure_additional_properties_false(schema_dict)
|
|
153
|
+
|
|
154
|
+
return BetaToolParam(
|
|
155
|
+
name=tool.name,
|
|
156
|
+
description=tool.description,
|
|
157
|
+
input_schema=schema_dict,
|
|
158
|
+
strict=strict,
|
|
159
|
+
)
|
|
136
160
|
|
|
137
161
|
|
|
138
162
|
def beta_encode_request(
|
|
@@ -140,13 +164,16 @@ def beta_encode_request(
|
|
|
140
164
|
model_id: str,
|
|
141
165
|
messages: Sequence[Message],
|
|
142
166
|
tools: Sequence[AnyToolSchema] | BaseToolkit[AnyToolSchema] | None,
|
|
143
|
-
format: type[FormattableT]
|
|
144
|
-
|
|
167
|
+
format: type[FormattableT]
|
|
168
|
+
| Format[FormattableT]
|
|
169
|
+
| OutputParser[FormattableT]
|
|
170
|
+
| None,
|
|
171
|
+
params: "Params",
|
|
145
172
|
) -> tuple[Sequence[Message], Format[FormattableT] | None, BetaParseKwargs]:
|
|
146
173
|
"""Prepares a request for the Anthropic beta.messages.parse method."""
|
|
147
174
|
|
|
148
175
|
processed = process_params(params, DEFAULT_MAX_TOKENS)
|
|
149
|
-
|
|
176
|
+
encode_thoughts_as_text = processed.pop("encode_thoughts_as_text", False)
|
|
150
177
|
max_tokens = processed.pop("max_tokens", DEFAULT_MAX_TOKENS)
|
|
151
178
|
|
|
152
179
|
kwargs: BetaParseKwargs = BetaParseKwargs(
|
|
@@ -159,14 +186,33 @@ def beta_encode_request(
|
|
|
159
186
|
)
|
|
160
187
|
|
|
161
188
|
tools = tools.tools if isinstance(tools, BaseToolkit) else tools or []
|
|
162
|
-
|
|
189
|
+
|
|
190
|
+
model_supports_strict = (
|
|
191
|
+
model_name(model_id) not in MODELS_WITHOUT_STRICT_STRUCTURED_OUTPUTS
|
|
192
|
+
)
|
|
193
|
+
# Check for strict tools on models that don't support them
|
|
194
|
+
if _base_utils.has_strict_tools(tools) and not model_supports_strict:
|
|
195
|
+
raise FeatureNotSupportedError(
|
|
196
|
+
feature="strict tools",
|
|
197
|
+
provider_id="anthropic",
|
|
198
|
+
model_id=model_id,
|
|
199
|
+
message="Strict tools require a model that supports structured outputs. "
|
|
200
|
+
"Use a newer model like claude-sonnet-4-5 or set strict=False on your tools.",
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
anthropic_tools = [
|
|
204
|
+
_beta_convert_tool_to_tool_param(
|
|
205
|
+
tool, model_supports_strict=model_supports_strict
|
|
206
|
+
)
|
|
207
|
+
for tool in tools
|
|
208
|
+
]
|
|
163
209
|
format = resolve_format(format, default_mode=DEFAULT_FORMAT_MODE)
|
|
164
210
|
|
|
165
211
|
if format is not None:
|
|
166
212
|
if format.mode == "strict":
|
|
167
213
|
if model_name(model_id) in MODELS_WITHOUT_STRICT_STRUCTURED_OUTPUTS:
|
|
168
|
-
raise
|
|
169
|
-
formatting_mode
|
|
214
|
+
raise FeatureNotSupportedError(
|
|
215
|
+
feature=f"formatting_mode:{format.mode}",
|
|
170
216
|
provider_id="anthropic",
|
|
171
217
|
model_id=model_id,
|
|
172
218
|
)
|
|
@@ -174,8 +220,12 @@ def beta_encode_request(
|
|
|
174
220
|
kwargs["output_format"] = cast(type[BaseModel], format.formattable)
|
|
175
221
|
|
|
176
222
|
if format.mode == "tool":
|
|
177
|
-
format_tool_schema =
|
|
178
|
-
anthropic_tools.append(
|
|
223
|
+
format_tool_schema = format.create_tool_schema()
|
|
224
|
+
anthropic_tools.append(
|
|
225
|
+
_beta_convert_tool_to_tool_param(
|
|
226
|
+
format_tool_schema, model_supports_strict=model_supports_strict
|
|
227
|
+
)
|
|
228
|
+
)
|
|
179
229
|
if tools:
|
|
180
230
|
kwargs["tool_choice"] = {"type": "any"}
|
|
181
231
|
else:
|
|
@@ -201,7 +251,7 @@ def beta_encode_request(
|
|
|
201
251
|
)
|
|
202
252
|
|
|
203
253
|
kwargs["messages"] = _beta_encode_messages(
|
|
204
|
-
remaining_messages, model_id,
|
|
254
|
+
remaining_messages, model_id, encode_thoughts_as_text
|
|
205
255
|
)
|
|
206
256
|
|
|
207
257
|
if system_message_content:
|
|
@@ -83,10 +83,15 @@ def decode_usage(
|
|
|
83
83
|
def decode_response(
|
|
84
84
|
response: anthropic_types.Message,
|
|
85
85
|
model_id: AnthropicModelId,
|
|
86
|
+
*,
|
|
87
|
+
include_thoughts: bool,
|
|
86
88
|
) -> tuple[AssistantMessage, FinishReason | None, Usage]:
|
|
87
89
|
"""Convert Anthropic message to mirascope AssistantMessage and usage."""
|
|
90
|
+
content = [_decode_assistant_content(part) for part in response.content]
|
|
91
|
+
if not include_thoughts:
|
|
92
|
+
content = [part for part in content if part.type != "thought"]
|
|
88
93
|
assistant_message = AssistantMessage(
|
|
89
|
-
content=
|
|
94
|
+
content=content,
|
|
90
95
|
provider_id="anthropic",
|
|
91
96
|
model_id=model_id,
|
|
92
97
|
provider_model_name=model_name(model_id),
|
|
@@ -115,10 +120,11 @@ ContentBlock: TypeAlias = (
|
|
|
115
120
|
class _AnthropicChunkProcessor:
|
|
116
121
|
"""Processes Anthropic stream events and maintains state across events."""
|
|
117
122
|
|
|
118
|
-
def __init__(self) -> None:
|
|
123
|
+
def __init__(self, *, include_thoughts: bool) -> None:
|
|
119
124
|
self.current_block_param: ContentBlock | None = None
|
|
120
125
|
self.accumulated_tool_json: str = ""
|
|
121
126
|
self.accumulated_blocks: list[ContentBlock] = []
|
|
127
|
+
self.include_thoughts = include_thoughts
|
|
122
128
|
|
|
123
129
|
def process_event(
|
|
124
130
|
self, event: anthropic_types.RawMessageStreamEvent
|
|
@@ -153,7 +159,8 @@ class _AnthropicChunkProcessor:
|
|
|
153
159
|
"thinking": "",
|
|
154
160
|
"signature": "",
|
|
155
161
|
}
|
|
156
|
-
|
|
162
|
+
if self.include_thoughts:
|
|
163
|
+
yield ThoughtStartChunk()
|
|
157
164
|
elif content_block.type == "redacted_thinking": # pragma: no cover
|
|
158
165
|
self.current_block_param = {
|
|
159
166
|
"type": "redacted_thinking",
|
|
@@ -180,14 +187,17 @@ class _AnthropicChunkProcessor:
|
|
|
180
187
|
f"Received input_json_delta for {self.current_block_param['type']} block"
|
|
181
188
|
)
|
|
182
189
|
self.accumulated_tool_json += delta.partial_json
|
|
183
|
-
yield ToolCallChunk(
|
|
190
|
+
yield ToolCallChunk(
|
|
191
|
+
id=self.current_block_param["id"], delta=delta.partial_json
|
|
192
|
+
)
|
|
184
193
|
elif delta.type == "thinking_delta":
|
|
185
194
|
if self.current_block_param["type"] != "thinking": # pragma: no cover
|
|
186
195
|
raise RuntimeError(
|
|
187
196
|
f"Received thinking_delta for {self.current_block_param['type']} block"
|
|
188
197
|
)
|
|
189
198
|
self.current_block_param["thinking"] += delta.thinking
|
|
190
|
-
|
|
199
|
+
if self.include_thoughts:
|
|
200
|
+
yield ThoughtChunk(delta=delta.thinking)
|
|
191
201
|
elif delta.type == "signature_delta":
|
|
192
202
|
if self.current_block_param["type"] != "thinking": # pragma: no cover
|
|
193
203
|
raise RuntimeError(
|
|
@@ -217,9 +227,10 @@ class _AnthropicChunkProcessor:
|
|
|
217
227
|
if self.accumulated_tool_json
|
|
218
228
|
else {}
|
|
219
229
|
)
|
|
220
|
-
yield ToolCallEndChunk()
|
|
230
|
+
yield ToolCallEndChunk(id=self.current_block_param["id"])
|
|
221
231
|
elif block_type == "thinking":
|
|
222
|
-
|
|
232
|
+
if self.include_thoughts:
|
|
233
|
+
yield ThoughtEndChunk()
|
|
223
234
|
else:
|
|
224
235
|
raise NotImplementedError
|
|
225
236
|
|
|
@@ -255,10 +266,10 @@ class _AnthropicChunkProcessor:
|
|
|
255
266
|
|
|
256
267
|
|
|
257
268
|
def decode_stream(
|
|
258
|
-
anthropic_stream_manager: MessageStreamManager,
|
|
269
|
+
anthropic_stream_manager: MessageStreamManager, *, include_thoughts: bool
|
|
259
270
|
) -> ChunkIterator:
|
|
260
271
|
"""Returns a ChunkIterator converted from an Anthropic MessageStreamManager."""
|
|
261
|
-
processor = _AnthropicChunkProcessor()
|
|
272
|
+
processor = _AnthropicChunkProcessor(include_thoughts=include_thoughts)
|
|
262
273
|
with anthropic_stream_manager as stream:
|
|
263
274
|
for event in stream._raw_stream: # pyright: ignore[reportPrivateUsage]
|
|
264
275
|
yield from processor.process_event(event)
|
|
@@ -266,10 +277,10 @@ def decode_stream(
|
|
|
266
277
|
|
|
267
278
|
|
|
268
279
|
async def decode_async_stream(
|
|
269
|
-
anthropic_stream_manager: AsyncMessageStreamManager,
|
|
280
|
+
anthropic_stream_manager: AsyncMessageStreamManager, *, include_thoughts: bool
|
|
270
281
|
) -> AsyncChunkIterator:
|
|
271
282
|
"""Returns an AsyncChunkIterator converted from an Anthropic MessageStreamManager."""
|
|
272
|
-
processor = _AnthropicChunkProcessor()
|
|
283
|
+
processor = _AnthropicChunkProcessor(include_thoughts=include_thoughts)
|
|
273
284
|
async with anthropic_stream_manager as stream:
|
|
274
285
|
async for event in stream._raw_stream: # pyright: ignore[reportPrivateUsage]
|
|
275
286
|
for item in processor.process_event(event):
|
|
@@ -1,30 +1,44 @@
|
|
|
1
1
|
"""Shared Anthropic encoding utilities."""
|
|
2
2
|
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
3
5
|
import json
|
|
4
6
|
from collections.abc import Sequence
|
|
5
7
|
from functools import lru_cache
|
|
6
|
-
from typing import Any, Literal, TypedDict, cast
|
|
8
|
+
from typing import TYPE_CHECKING, Any, Literal, TypedDict, cast
|
|
7
9
|
from typing_extensions import Required
|
|
8
10
|
|
|
9
11
|
from anthropic import Omit, types as anthropic_types
|
|
10
12
|
|
|
11
13
|
from ....content import ContentPart, ImageMimeType
|
|
12
|
-
from ....exceptions import FeatureNotSupportedError
|
|
14
|
+
from ....exceptions import FeatureNotSupportedError
|
|
13
15
|
from ....formatting import (
|
|
14
16
|
Format,
|
|
15
17
|
FormattableT,
|
|
16
|
-
|
|
18
|
+
OutputParser,
|
|
17
19
|
resolve_format,
|
|
18
20
|
)
|
|
19
21
|
from ....messages import AssistantMessage, Message, UserMessage
|
|
20
22
|
from ....tools import FORMAT_TOOL_NAME, AnyToolSchema, BaseToolkit
|
|
21
|
-
from ...base import
|
|
23
|
+
from ...base import _utils as _base_utils
|
|
22
24
|
from ..model_id import AnthropicModelId, model_name
|
|
23
25
|
|
|
26
|
+
if TYPE_CHECKING:
|
|
27
|
+
from ....models import Params, ThinkingLevel
|
|
28
|
+
|
|
24
29
|
DEFAULT_MAX_TOKENS = 16000
|
|
25
30
|
# TODO: Change DEFAULT_FORMAT_MODE to strict when strict is no longer a beta feature.
|
|
26
31
|
DEFAULT_FORMAT_MODE = "tool"
|
|
27
32
|
|
|
33
|
+
# Thinking level to a float multiplier % of max tokens
|
|
34
|
+
THINKING_LEVEL_TO_BUDGET_MULTIPLIER: dict[ThinkingLevel, float] = {
|
|
35
|
+
"minimal": 0, # Will become 1024 (actual minimal value)
|
|
36
|
+
"low": 0.2,
|
|
37
|
+
"medium": 0.4,
|
|
38
|
+
"high": 0.6,
|
|
39
|
+
"max": 0.8,
|
|
40
|
+
}
|
|
41
|
+
|
|
28
42
|
AnthropicImageMimeType = Literal["image/jpeg", "image/png", "image/gif", "image/webp"]
|
|
29
43
|
|
|
30
44
|
|
|
@@ -37,6 +51,30 @@ def encode_image_mime_type(mime_type: ImageMimeType) -> AnthropicImageMimeType:
|
|
|
37
51
|
) # pragma: no cover
|
|
38
52
|
|
|
39
53
|
|
|
54
|
+
def compute_thinking_budget(
|
|
55
|
+
level: ThinkingLevel,
|
|
56
|
+
max_tokens: int,
|
|
57
|
+
) -> int:
|
|
58
|
+
"""Compute Anthropic token budget from ThinkingConfig level.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
level: The thinking level from ThinkingConfig
|
|
62
|
+
max_tokens: The max_tokens value for the request
|
|
63
|
+
|
|
64
|
+
Returns:
|
|
65
|
+
Token budget for thinking (0 to disable, positive for budget)
|
|
66
|
+
"""
|
|
67
|
+
|
|
68
|
+
if level == "none":
|
|
69
|
+
return 0
|
|
70
|
+
elif level == "default":
|
|
71
|
+
return -1 # Do not set thinking, leave to provider default
|
|
72
|
+
|
|
73
|
+
multiplier: float = THINKING_LEVEL_TO_BUDGET_MULTIPLIER.get(level, 0.4)
|
|
74
|
+
budget = int(multiplier * max_tokens)
|
|
75
|
+
return max(1024, budget) # Always return at least 1024, minimum allowed budget
|
|
76
|
+
|
|
77
|
+
|
|
40
78
|
class ProcessedParams(TypedDict, total=False):
|
|
41
79
|
"""Common parameters processed from Params."""
|
|
42
80
|
|
|
@@ -46,7 +84,7 @@ class ProcessedParams(TypedDict, total=False):
|
|
|
46
84
|
top_k: int
|
|
47
85
|
stop_sequences: list[str]
|
|
48
86
|
thinking: dict[str, Any]
|
|
49
|
-
|
|
87
|
+
encode_thoughts_as_text: bool
|
|
50
88
|
|
|
51
89
|
|
|
52
90
|
def process_params(params: Params, default_max_tokens: int) -> ProcessedParams:
|
|
@@ -56,7 +94,7 @@ def process_params(params: Params, default_max_tokens: int) -> ProcessedParams:
|
|
|
56
94
|
"""
|
|
57
95
|
result: ProcessedParams = {
|
|
58
96
|
"max_tokens": default_max_tokens,
|
|
59
|
-
"
|
|
97
|
+
"encode_thoughts_as_text": False,
|
|
60
98
|
}
|
|
61
99
|
|
|
62
100
|
with _base_utils.ensure_all_params_accessed(
|
|
@@ -73,13 +111,22 @@ def process_params(params: Params, default_max_tokens: int) -> ProcessedParams:
|
|
|
73
111
|
if param_accessor.stop_sequences is not None:
|
|
74
112
|
result["stop_sequences"] = param_accessor.stop_sequences
|
|
75
113
|
if param_accessor.thinking is not None:
|
|
76
|
-
|
|
77
|
-
|
|
114
|
+
thinking_config = param_accessor.thinking
|
|
115
|
+
level = thinking_config.get("level")
|
|
116
|
+
|
|
117
|
+
# Compute token budget from level
|
|
118
|
+
budget_tokens = compute_thinking_budget(level, result["max_tokens"])
|
|
119
|
+
if budget_tokens == 0:
|
|
120
|
+
result["thinking"] = {"type": "disabled"}
|
|
121
|
+
elif budget_tokens > 0:
|
|
78
122
|
result["thinking"] = {"type": "enabled", "budget_tokens": budget_tokens}
|
|
79
123
|
else:
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
124
|
+
# budget is -1, do not set thinking at all.
|
|
125
|
+
pass
|
|
126
|
+
|
|
127
|
+
# Handle encode_thoughts_as_text from ThinkingConfig
|
|
128
|
+
if thinking_config.get("encode_thoughts_as_text"):
|
|
129
|
+
result["encode_thoughts_as_text"] = True
|
|
83
130
|
|
|
84
131
|
return result
|
|
85
132
|
|
|
@@ -185,7 +232,7 @@ def encode_content(
|
|
|
185
232
|
anthropic_types.ToolResultBlockParam(
|
|
186
233
|
type="tool_result",
|
|
187
234
|
tool_use_id=part.id,
|
|
188
|
-
content=str(part.
|
|
235
|
+
content=str(part.result),
|
|
189
236
|
cache_control={"type": "ephemeral"} if should_add_cache else None,
|
|
190
237
|
)
|
|
191
238
|
)
|
|
@@ -254,7 +301,7 @@ def _encode_message(
|
|
|
254
301
|
def _encode_messages(
|
|
255
302
|
messages: Sequence[UserMessage | AssistantMessage],
|
|
256
303
|
model_id: AnthropicModelId,
|
|
257
|
-
|
|
304
|
+
encode_thoughts_as_text: bool,
|
|
258
305
|
) -> Sequence[anthropic_types.MessageParam]:
|
|
259
306
|
"""Encode messages and add cache control for multi-turn conversations.
|
|
260
307
|
|
|
@@ -270,7 +317,7 @@ def _encode_messages(
|
|
|
270
317
|
is_last = i == len(messages) - 1
|
|
271
318
|
add_cache = has_assistant_message and is_last
|
|
272
319
|
encoded_messages.append(
|
|
273
|
-
_encode_message(message, model_id,
|
|
320
|
+
_encode_message(message, model_id, encode_thoughts_as_text, add_cache)
|
|
274
321
|
)
|
|
275
322
|
return encoded_messages
|
|
276
323
|
|
|
@@ -292,13 +339,16 @@ def encode_request(
|
|
|
292
339
|
model_id: AnthropicModelId,
|
|
293
340
|
messages: Sequence[Message],
|
|
294
341
|
tools: Sequence[AnyToolSchema] | BaseToolkit[AnyToolSchema] | None,
|
|
295
|
-
format: type[FormattableT]
|
|
342
|
+
format: type[FormattableT]
|
|
343
|
+
| Format[FormattableT]
|
|
344
|
+
| OutputParser[FormattableT]
|
|
345
|
+
| None,
|
|
296
346
|
params: Params,
|
|
297
347
|
) -> tuple[Sequence[Message], Format[FormattableT] | None, MessageCreateKwargs]:
|
|
298
348
|
"""Prepares a request for the Anthropic messages.create method."""
|
|
299
349
|
|
|
300
350
|
processed = process_params(params, DEFAULT_MAX_TOKENS)
|
|
301
|
-
|
|
351
|
+
encode_thoughts_as_text = processed.pop("encode_thoughts_as_text", False)
|
|
302
352
|
max_tokens = processed.pop("max_tokens", DEFAULT_MAX_TOKENS)
|
|
303
353
|
|
|
304
354
|
kwargs: MessageCreateKwargs = MessageCreateKwargs(
|
|
@@ -306,17 +356,27 @@ def encode_request(
|
|
|
306
356
|
)
|
|
307
357
|
|
|
308
358
|
tools = tools.tools if isinstance(tools, BaseToolkit) else tools or []
|
|
359
|
+
|
|
360
|
+
# Check for strict tools - the non-beta API doesn't support them
|
|
361
|
+
if _base_utils.has_strict_tools(tools):
|
|
362
|
+
raise FeatureNotSupportedError(
|
|
363
|
+
feature="strict tools",
|
|
364
|
+
provider_id="anthropic",
|
|
365
|
+
model_id=model_id,
|
|
366
|
+
message="Anthropic provider does not support strict tools. Try the beta provider.",
|
|
367
|
+
)
|
|
368
|
+
|
|
309
369
|
anthropic_tools = [convert_tool_to_tool_param(tool) for tool in tools]
|
|
310
370
|
format = resolve_format(format, default_mode=DEFAULT_FORMAT_MODE)
|
|
311
371
|
if format is not None:
|
|
312
372
|
if format.mode == "strict":
|
|
313
|
-
raise
|
|
314
|
-
|
|
373
|
+
raise FeatureNotSupportedError(
|
|
374
|
+
feature="formatting_mode:strict",
|
|
315
375
|
provider_id="anthropic",
|
|
316
376
|
model_id=model_id,
|
|
317
377
|
)
|
|
318
378
|
if format.mode == "tool":
|
|
319
|
-
format_tool_schema =
|
|
379
|
+
format_tool_schema = format.create_tool_schema()
|
|
320
380
|
anthropic_tools.append(convert_tool_to_tool_param(format_tool_schema))
|
|
321
381
|
if tools:
|
|
322
382
|
kwargs["tool_choice"] = {"type": "any"}
|
|
@@ -342,7 +402,9 @@ def encode_request(
|
|
|
342
402
|
messages
|
|
343
403
|
)
|
|
344
404
|
|
|
345
|
-
kwargs["messages"] = _encode_messages(
|
|
405
|
+
kwargs["messages"] = _encode_messages(
|
|
406
|
+
remaining_messages, model_id, encode_thoughts_as_text
|
|
407
|
+
)
|
|
346
408
|
|
|
347
409
|
if system_message_content:
|
|
348
410
|
kwargs["system"] = [
|
|
@@ -16,12 +16,12 @@ from anthropic import (
|
|
|
16
16
|
)
|
|
17
17
|
|
|
18
18
|
from ....exceptions import (
|
|
19
|
-
APIError,
|
|
20
19
|
AuthenticationError,
|
|
21
20
|
BadRequestError,
|
|
22
21
|
ConnectionError,
|
|
23
22
|
NotFoundError,
|
|
24
23
|
PermissionError,
|
|
24
|
+
ProviderError,
|
|
25
25
|
RateLimitError,
|
|
26
26
|
ResponseValidationError,
|
|
27
27
|
ServerError,
|
|
@@ -42,5 +42,5 @@ ANTHROPIC_ERROR_MAP: ProviderErrorMap = {
|
|
|
42
42
|
AnthropicAPITimeoutError: TimeoutError,
|
|
43
43
|
AnthropicAPIConnectionError: ConnectionError,
|
|
44
44
|
AnthropicAPIResponseValidationError: ResponseValidationError,
|
|
45
|
-
AnthropicError:
|
|
45
|
+
AnthropicError: ProviderError, # Catch-all for unknown Anthropic errors
|
|
46
46
|
}
|