mirascope 1.0.5__py3-none-any.whl → 2.1.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 +6 -6
- mirascope/_stubs.py +384 -0
- mirascope/_utils.py +34 -0
- mirascope/api/__init__.py +14 -0
- mirascope/api/_generated/README.md +207 -0
- mirascope/api/_generated/__init__.py +444 -0
- 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 +17 -0
- mirascope/api/_generated/api_keys/client.py +530 -0
- mirascope/api/_generated/api_keys/raw_client.py +1236 -0
- mirascope/api/_generated/api_keys/types/__init__.py +15 -0
- mirascope/api/_generated/api_keys/types/api_keys_create_response.py +28 -0
- mirascope/api/_generated/api_keys/types/api_keys_get_response.py +27 -0
- 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 +27 -0
- mirascope/api/_generated/client.py +211 -0
- mirascope/api/_generated/core/__init__.py +52 -0
- mirascope/api/_generated/core/api_error.py +23 -0
- mirascope/api/_generated/core/client_wrapper.py +46 -0
- mirascope/api/_generated/core/datetime_utils.py +28 -0
- mirascope/api/_generated/core/file.py +67 -0
- mirascope/api/_generated/core/force_multipart.py +16 -0
- mirascope/api/_generated/core/http_client.py +543 -0
- mirascope/api/_generated/core/http_response.py +55 -0
- mirascope/api/_generated/core/jsonable_encoder.py +100 -0
- mirascope/api/_generated/core/pydantic_utilities.py +255 -0
- mirascope/api/_generated/core/query_encoder.py +58 -0
- mirascope/api/_generated/core/remove_none_from_dict.py +11 -0
- mirascope/api/_generated/core/request_options.py +35 -0
- mirascope/api/_generated/core/serialization.py +276 -0
- mirascope/api/_generated/docs/__init__.py +4 -0
- mirascope/api/_generated/docs/client.py +91 -0
- mirascope/api/_generated/docs/raw_client.py +178 -0
- mirascope/api/_generated/environment.py +9 -0
- mirascope/api/_generated/environments/__init__.py +23 -0
- mirascope/api/_generated/environments/client.py +649 -0
- mirascope/api/_generated/environments/raw_client.py +1567 -0
- mirascope/api/_generated/environments/types/__init__.py +25 -0
- mirascope/api/_generated/environments/types/environments_create_response.py +24 -0
- 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 +24 -0
- mirascope/api/_generated/environments/types/environments_list_response_item.py +24 -0
- mirascope/api/_generated/environments/types/environments_update_response.py +24 -0
- mirascope/api/_generated/errors/__init__.py +25 -0
- mirascope/api/_generated/errors/bad_request_error.py +14 -0
- mirascope/api/_generated/errors/conflict_error.py +14 -0
- mirascope/api/_generated/errors/forbidden_error.py +11 -0
- mirascope/api/_generated/errors/internal_server_error.py +10 -0
- mirascope/api/_generated/errors/not_found_error.py +11 -0
- 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/__init__.py +7 -0
- mirascope/api/_generated/health/client.py +92 -0
- mirascope/api/_generated/health/raw_client.py +175 -0
- mirascope/api/_generated/health/types/__init__.py +8 -0
- mirascope/api/_generated/health/types/health_check_response.py +22 -0
- mirascope/api/_generated/health/types/health_check_response_status.py +5 -0
- 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 +51 -0
- mirascope/api/_generated/organizations/client.py +869 -0
- mirascope/api/_generated/organizations/raw_client.py +2593 -0
- mirascope/api/_generated/organizations/types/__init__.py +71 -0
- mirascope/api/_generated/organizations/types/organizations_create_payment_intent_response.py +24 -0
- mirascope/api/_generated/organizations/types/organizations_create_response.py +26 -0
- mirascope/api/_generated/organizations/types/organizations_create_response_role.py +5 -0
- mirascope/api/_generated/organizations/types/organizations_get_response.py +26 -0
- mirascope/api/_generated/organizations/types/organizations_get_response_role.py +5 -0
- mirascope/api/_generated/organizations/types/organizations_list_response_item.py +26 -0
- mirascope/api/_generated/organizations/types/organizations_list_response_item_role.py +5 -0
- 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 +26 -0
- mirascope/api/_generated/organizations/types/organizations_update_response_role.py +5 -0
- 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 +29 -0
- mirascope/api/_generated/project_memberships/client.py +528 -0
- mirascope/api/_generated/project_memberships/raw_client.py +1278 -0
- mirascope/api/_generated/project_memberships/types/__init__.py +33 -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_get_response.py +33 -0
- mirascope/api/_generated/project_memberships/types/project_memberships_get_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 +7 -0
- mirascope/api/_generated/projects/client.py +428 -0
- mirascope/api/_generated/projects/raw_client.py +1302 -0
- mirascope/api/_generated/projects/types/__init__.py +10 -0
- mirascope/api/_generated/projects/types/projects_create_response.py +25 -0
- mirascope/api/_generated/projects/types/projects_get_response.py +25 -0
- mirascope/api/_generated/projects/types/projects_list_response_item.py +25 -0
- mirascope/api/_generated/projects/types/projects_update_response.py +25 -0
- mirascope/api/_generated/reference.md +4987 -0
- 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 +97 -0
- mirascope/api/_generated/traces/client.py +1103 -0
- mirascope/api/_generated/traces/raw_client.py +2322 -0
- mirascope/api/_generated/traces/types/__init__.py +155 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item.py +29 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource.py +27 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item.py +23 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value.py +38 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_array_value.py +19 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_kvlist_value.py +22 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_kvlist_value_values_item.py +20 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item.py +29 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope.py +31 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item.py +23 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value.py +38 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_array_value.py +19 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_kvlist_value.py +22 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_kvlist_value_values_item.py +22 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item.py +48 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item.py +23 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value.py +38 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_array_value.py +19 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_kvlist_value.py +24 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_kvlist_value_values_item.py +22 -0
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_status.py +20 -0
- mirascope/api/_generated/traces/types/traces_create_response.py +24 -0
- mirascope/api/_generated/traces/types/traces_create_response_partial_success.py +22 -0
- 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 +85 -0
- mirascope/api/_generated/types/already_exists_error.py +22 -0
- mirascope/api/_generated/types/already_exists_error_tag.py +5 -0
- 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 +22 -0
- mirascope/api/_generated/types/database_error_tag.py +5 -0
- mirascope/api/_generated/types/date.py +3 -0
- mirascope/api/_generated/types/http_api_decode_error.py +27 -0
- mirascope/api/_generated/types/http_api_decode_error_tag.py +5 -0
- 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 +38 -0
- mirascope/api/_generated/types/issue_tag.py +10 -0
- mirascope/api/_generated/types/not_found_error_body.py +22 -0
- mirascope/api/_generated/types/not_found_error_tag.py +5 -0
- mirascope/api/_generated/types/number_from_string.py +3 -0
- mirascope/api/_generated/types/permission_denied_error.py +22 -0
- mirascope/api/_generated/types/permission_denied_error_tag.py +5 -0
- 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.py +7 -0
- mirascope/api/_generated/types/property_key_key.py +25 -0
- mirascope/api/_generated/types/property_key_key_tag.py +5 -0
- 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/client.py +255 -0
- mirascope/api/settings.py +99 -0
- mirascope/llm/__init__.py +316 -0
- mirascope/llm/calls/__init__.py +17 -0
- mirascope/llm/calls/calls.py +348 -0
- mirascope/llm/calls/decorator.py +268 -0
- mirascope/llm/content/__init__.py +71 -0
- mirascope/llm/content/audio.py +173 -0
- mirascope/llm/content/document.py +94 -0
- mirascope/llm/content/image.py +206 -0
- mirascope/llm/content/text.py +47 -0
- mirascope/llm/content/thought.py +58 -0
- mirascope/llm/content/tool_call.py +69 -0
- mirascope/llm/content/tool_output.py +43 -0
- mirascope/llm/context/__init__.py +6 -0
- mirascope/llm/context/_utils.py +41 -0
- mirascope/llm/context/context.py +24 -0
- mirascope/llm/exceptions.py +360 -0
- mirascope/llm/formatting/__init__.py +39 -0
- mirascope/llm/formatting/format.py +291 -0
- mirascope/llm/formatting/from_call_args.py +30 -0
- mirascope/llm/formatting/output_parser.py +178 -0
- mirascope/llm/formatting/partial.py +131 -0
- mirascope/llm/formatting/primitives.py +192 -0
- mirascope/llm/formatting/types.py +83 -0
- mirascope/llm/mcp/__init__.py +5 -0
- mirascope/llm/mcp/mcp_client.py +130 -0
- mirascope/llm/messages/__init__.py +35 -0
- mirascope/llm/messages/_utils.py +34 -0
- mirascope/llm/messages/message.py +190 -0
- mirascope/llm/models/__init__.py +21 -0
- mirascope/llm/models/models.py +1339 -0
- mirascope/llm/models/params.py +72 -0
- mirascope/llm/models/thinking_config.py +61 -0
- mirascope/llm/prompts/__init__.py +34 -0
- mirascope/llm/prompts/_utils.py +31 -0
- mirascope/llm/prompts/decorator.py +215 -0
- mirascope/llm/prompts/prompts.py +484 -0
- mirascope/llm/prompts/protocols.py +65 -0
- mirascope/llm/providers/__init__.py +65 -0
- mirascope/llm/providers/anthropic/__init__.py +11 -0
- mirascope/llm/providers/anthropic/_utils/__init__.py +27 -0
- mirascope/llm/providers/anthropic/_utils/beta_decode.py +297 -0
- mirascope/llm/providers/anthropic/_utils/beta_encode.py +272 -0
- mirascope/llm/providers/anthropic/_utils/decode.py +326 -0
- mirascope/llm/providers/anthropic/_utils/encode.py +431 -0
- mirascope/llm/providers/anthropic/_utils/errors.py +46 -0
- mirascope/llm/providers/anthropic/beta_provider.py +338 -0
- mirascope/llm/providers/anthropic/model_id.py +23 -0
- mirascope/llm/providers/anthropic/model_info.py +87 -0
- mirascope/llm/providers/anthropic/provider.py +440 -0
- mirascope/llm/providers/base/__init__.py +14 -0
- mirascope/llm/providers/base/_utils.py +248 -0
- mirascope/llm/providers/base/base_provider.py +1463 -0
- mirascope/llm/providers/base/kwargs.py +12 -0
- mirascope/llm/providers/google/__init__.py +6 -0
- mirascope/llm/providers/google/_utils/__init__.py +17 -0
- mirascope/llm/providers/google/_utils/decode.py +357 -0
- mirascope/llm/providers/google/_utils/encode.py +418 -0
- mirascope/llm/providers/google/_utils/errors.py +50 -0
- mirascope/llm/providers/google/message.py +7 -0
- mirascope/llm/providers/google/model_id.py +22 -0
- mirascope/llm/providers/google/model_info.py +63 -0
- mirascope/llm/providers/google/provider.py +456 -0
- mirascope/llm/providers/mirascope/__init__.py +5 -0
- mirascope/llm/providers/mirascope/_utils.py +73 -0
- mirascope/llm/providers/mirascope/provider.py +313 -0
- mirascope/llm/providers/mlx/__init__.py +9 -0
- mirascope/llm/providers/mlx/_utils.py +141 -0
- mirascope/llm/providers/mlx/encoding/__init__.py +8 -0
- mirascope/llm/providers/mlx/encoding/base.py +69 -0
- mirascope/llm/providers/mlx/encoding/transformers.py +146 -0
- mirascope/llm/providers/mlx/mlx.py +242 -0
- mirascope/llm/providers/mlx/model_id.py +17 -0
- mirascope/llm/providers/mlx/provider.py +416 -0
- mirascope/llm/providers/model_id.py +16 -0
- mirascope/llm/providers/ollama/__init__.py +7 -0
- mirascope/llm/providers/ollama/provider.py +71 -0
- mirascope/llm/providers/openai/__init__.py +15 -0
- mirascope/llm/providers/openai/_utils/__init__.py +5 -0
- mirascope/llm/providers/openai/_utils/errors.py +46 -0
- mirascope/llm/providers/openai/completions/__init__.py +7 -0
- mirascope/llm/providers/openai/completions/_utils/__init__.py +18 -0
- mirascope/llm/providers/openai/completions/_utils/decode.py +252 -0
- mirascope/llm/providers/openai/completions/_utils/encode.py +390 -0
- mirascope/llm/providers/openai/completions/_utils/feature_info.py +50 -0
- mirascope/llm/providers/openai/completions/base_provider.py +522 -0
- mirascope/llm/providers/openai/completions/provider.py +28 -0
- mirascope/llm/providers/openai/model_id.py +31 -0
- mirascope/llm/providers/openai/model_info.py +303 -0
- mirascope/llm/providers/openai/provider.py +405 -0
- mirascope/llm/providers/openai/responses/__init__.py +5 -0
- mirascope/llm/providers/openai/responses/_utils/__init__.py +15 -0
- mirascope/llm/providers/openai/responses/_utils/decode.py +289 -0
- mirascope/llm/providers/openai/responses/_utils/encode.py +399 -0
- mirascope/llm/providers/openai/responses/provider.py +472 -0
- mirascope/llm/providers/openrouter/__init__.py +5 -0
- mirascope/llm/providers/openrouter/provider.py +67 -0
- mirascope/llm/providers/provider_id.py +26 -0
- mirascope/llm/providers/provider_registry.py +305 -0
- mirascope/llm/providers/together/__init__.py +7 -0
- mirascope/llm/providers/together/provider.py +40 -0
- mirascope/llm/responses/__init__.py +66 -0
- mirascope/llm/responses/_utils.py +146 -0
- mirascope/llm/responses/base_response.py +103 -0
- mirascope/llm/responses/base_stream_response.py +824 -0
- mirascope/llm/responses/finish_reason.py +28 -0
- mirascope/llm/responses/response.py +362 -0
- mirascope/llm/responses/root_response.py +248 -0
- mirascope/llm/responses/stream_response.py +577 -0
- mirascope/llm/responses/streams.py +363 -0
- mirascope/llm/responses/usage.py +139 -0
- mirascope/llm/tools/__init__.py +71 -0
- mirascope/llm/tools/_utils.py +34 -0
- mirascope/llm/tools/decorator.py +184 -0
- mirascope/llm/tools/protocols.py +96 -0
- mirascope/llm/tools/provider_tools.py +18 -0
- mirascope/llm/tools/tool_schema.py +321 -0
- mirascope/llm/tools/toolkit.py +178 -0
- mirascope/llm/tools/tools.py +263 -0
- mirascope/llm/tools/types.py +112 -0
- mirascope/llm/tools/web_search_tool.py +32 -0
- mirascope/llm/types/__init__.py +22 -0
- mirascope/llm/types/dataclass.py +9 -0
- mirascope/llm/types/jsonable.py +44 -0
- mirascope/llm/types/type_vars.py +19 -0
- mirascope/ops/__init__.py +129 -0
- mirascope/ops/_internal/__init__.py +5 -0
- mirascope/ops/_internal/closure.py +1172 -0
- mirascope/ops/_internal/configuration.py +177 -0
- mirascope/ops/_internal/context.py +76 -0
- mirascope/ops/_internal/exporters/__init__.py +26 -0
- mirascope/ops/_internal/exporters/exporters.py +362 -0
- mirascope/ops/_internal/exporters/processors.py +104 -0
- mirascope/ops/_internal/exporters/types.py +165 -0
- mirascope/ops/_internal/exporters/utils.py +66 -0
- mirascope/ops/_internal/instrumentation/__init__.py +28 -0
- mirascope/ops/_internal/instrumentation/llm/__init__.py +8 -0
- mirascope/ops/_internal/instrumentation/llm/common.py +500 -0
- mirascope/ops/_internal/instrumentation/llm/cost.py +190 -0
- mirascope/ops/_internal/instrumentation/llm/encode.py +238 -0
- mirascope/ops/_internal/instrumentation/llm/gen_ai_types/__init__.py +38 -0
- mirascope/ops/_internal/instrumentation/llm/gen_ai_types/gen_ai_input_messages.py +31 -0
- mirascope/ops/_internal/instrumentation/llm/gen_ai_types/gen_ai_output_messages.py +38 -0
- mirascope/ops/_internal/instrumentation/llm/gen_ai_types/gen_ai_system_instructions.py +18 -0
- mirascope/ops/_internal/instrumentation/llm/gen_ai_types/shared.py +100 -0
- mirascope/ops/_internal/instrumentation/llm/llm.py +161 -0
- mirascope/ops/_internal/instrumentation/llm/model.py +1777 -0
- mirascope/ops/_internal/instrumentation/llm/response.py +521 -0
- mirascope/ops/_internal/instrumentation/llm/serialize.py +324 -0
- mirascope/ops/_internal/instrumentation/providers/__init__.py +29 -0
- mirascope/ops/_internal/instrumentation/providers/anthropic.py +78 -0
- mirascope/ops/_internal/instrumentation/providers/base.py +179 -0
- mirascope/ops/_internal/instrumentation/providers/google_genai.py +85 -0
- mirascope/ops/_internal/instrumentation/providers/openai.py +82 -0
- mirascope/ops/_internal/propagation.py +198 -0
- mirascope/ops/_internal/protocols.py +133 -0
- mirascope/ops/_internal/session.py +139 -0
- mirascope/ops/_internal/spans.py +232 -0
- mirascope/ops/_internal/traced_calls.py +389 -0
- mirascope/ops/_internal/traced_functions.py +528 -0
- mirascope/ops/_internal/tracing.py +353 -0
- mirascope/ops/_internal/types.py +13 -0
- mirascope/ops/_internal/utils.py +131 -0
- mirascope/ops/_internal/versioned_calls.py +512 -0
- mirascope/ops/_internal/versioned_functions.py +357 -0
- mirascope/ops/_internal/versioning.py +303 -0
- mirascope/ops/exceptions.py +21 -0
- mirascope-2.1.1.dist-info/METADATA +231 -0
- mirascope-2.1.1.dist-info/RECORD +437 -0
- {mirascope-1.0.5.dist-info → mirascope-2.1.1.dist-info}/WHEEL +1 -1
- {mirascope-1.0.5.dist-info → mirascope-2.1.1.dist-info}/licenses/LICENSE +1 -1
- mirascope/beta/__init__.py +0 -0
- mirascope/beta/openai/__init__.py +0 -5
- mirascope/beta/openai/parse.py +0 -129
- mirascope/beta/rag/__init__.py +0 -24
- mirascope/beta/rag/base/__init__.py +0 -22
- mirascope/beta/rag/base/chunkers/__init__.py +0 -2
- mirascope/beta/rag/base/chunkers/base_chunker.py +0 -37
- mirascope/beta/rag/base/chunkers/text_chunker.py +0 -33
- mirascope/beta/rag/base/config.py +0 -8
- mirascope/beta/rag/base/document.py +0 -11
- mirascope/beta/rag/base/embedders.py +0 -35
- mirascope/beta/rag/base/embedding_params.py +0 -18
- mirascope/beta/rag/base/embedding_response.py +0 -30
- mirascope/beta/rag/base/query_results.py +0 -7
- mirascope/beta/rag/base/vectorstore_params.py +0 -18
- mirascope/beta/rag/base/vectorstores.py +0 -37
- mirascope/beta/rag/chroma/__init__.py +0 -11
- mirascope/beta/rag/chroma/types.py +0 -57
- mirascope/beta/rag/chroma/vectorstores.py +0 -97
- mirascope/beta/rag/cohere/__init__.py +0 -11
- mirascope/beta/rag/cohere/embedders.py +0 -87
- mirascope/beta/rag/cohere/embedding_params.py +0 -29
- mirascope/beta/rag/cohere/embedding_response.py +0 -29
- mirascope/beta/rag/cohere/py.typed +0 -0
- mirascope/beta/rag/openai/__init__.py +0 -11
- mirascope/beta/rag/openai/embedders.py +0 -144
- mirascope/beta/rag/openai/embedding_params.py +0 -18
- mirascope/beta/rag/openai/embedding_response.py +0 -14
- mirascope/beta/rag/openai/py.typed +0 -0
- mirascope/beta/rag/pinecone/__init__.py +0 -19
- mirascope/beta/rag/pinecone/types.py +0 -143
- mirascope/beta/rag/pinecone/vectorstores.py +0 -148
- mirascope/beta/rag/weaviate/__init__.py +0 -6
- mirascope/beta/rag/weaviate/types.py +0 -92
- mirascope/beta/rag/weaviate/vectorstores.py +0 -103
- mirascope/core/__init__.py +0 -55
- mirascope/core/anthropic/__init__.py +0 -21
- mirascope/core/anthropic/_call.py +0 -71
- mirascope/core/anthropic/_utils/__init__.py +0 -16
- mirascope/core/anthropic/_utils/_calculate_cost.py +0 -63
- mirascope/core/anthropic/_utils/_convert_message_params.py +0 -54
- mirascope/core/anthropic/_utils/_get_json_output.py +0 -34
- mirascope/core/anthropic/_utils/_handle_stream.py +0 -89
- mirascope/core/anthropic/_utils/_setup_call.py +0 -76
- mirascope/core/anthropic/call_params.py +0 -36
- mirascope/core/anthropic/call_response.py +0 -158
- mirascope/core/anthropic/call_response_chunk.py +0 -104
- mirascope/core/anthropic/dynamic_config.py +0 -26
- mirascope/core/anthropic/py.typed +0 -0
- mirascope/core/anthropic/stream.py +0 -140
- mirascope/core/anthropic/tool.py +0 -77
- mirascope/core/base/__init__.py +0 -40
- mirascope/core/base/_call_factory.py +0 -323
- mirascope/core/base/_create.py +0 -167
- mirascope/core/base/_extract.py +0 -139
- mirascope/core/base/_partial.py +0 -63
- mirascope/core/base/_utils/__init__.py +0 -64
- mirascope/core/base/_utils/_base_type.py +0 -17
- mirascope/core/base/_utils/_convert_base_model_to_base_tool.py +0 -45
- mirascope/core/base/_utils/_convert_base_type_to_base_tool.py +0 -24
- mirascope/core/base/_utils/_convert_function_to_base_tool.py +0 -126
- mirascope/core/base/_utils/_default_tool_docstring.py +0 -6
- mirascope/core/base/_utils/_extract_tool_return.py +0 -36
- mirascope/core/base/_utils/_format_template.py +0 -29
- mirascope/core/base/_utils/_get_audio_type.py +0 -18
- mirascope/core/base/_utils/_get_fn_args.py +0 -14
- mirascope/core/base/_utils/_get_image_type.py +0 -26
- mirascope/core/base/_utils/_get_metadata.py +0 -17
- mirascope/core/base/_utils/_get_possible_user_message_param.py +0 -21
- mirascope/core/base/_utils/_get_prompt_template.py +0 -25
- mirascope/core/base/_utils/_get_template_values.py +0 -52
- mirascope/core/base/_utils/_get_template_variables.py +0 -38
- mirascope/core/base/_utils/_json_mode_content.py +0 -15
- mirascope/core/base/_utils/_parse_content_template.py +0 -157
- mirascope/core/base/_utils/_parse_prompt_messages.py +0 -51
- mirascope/core/base/_utils/_protocols.py +0 -215
- mirascope/core/base/_utils/_setup_call.py +0 -64
- mirascope/core/base/_utils/_setup_extract_tool.py +0 -24
- mirascope/core/base/call_params.py +0 -6
- mirascope/core/base/call_response.py +0 -189
- mirascope/core/base/call_response_chunk.py +0 -91
- mirascope/core/base/dynamic_config.py +0 -55
- mirascope/core/base/message_param.py +0 -61
- mirascope/core/base/metadata.py +0 -13
- mirascope/core/base/prompt.py +0 -415
- mirascope/core/base/stream.py +0 -365
- mirascope/core/base/structured_stream.py +0 -251
- mirascope/core/base/tool.py +0 -126
- mirascope/core/base/toolkit.py +0 -146
- mirascope/core/cohere/__init__.py +0 -21
- mirascope/core/cohere/_call.py +0 -71
- mirascope/core/cohere/_utils/__init__.py +0 -16
- mirascope/core/cohere/_utils/_calculate_cost.py +0 -39
- mirascope/core/cohere/_utils/_convert_message_params.py +0 -31
- mirascope/core/cohere/_utils/_get_json_output.py +0 -31
- mirascope/core/cohere/_utils/_handle_stream.py +0 -33
- mirascope/core/cohere/_utils/_setup_call.py +0 -89
- mirascope/core/cohere/call_params.py +0 -57
- mirascope/core/cohere/call_response.py +0 -167
- mirascope/core/cohere/call_response_chunk.py +0 -101
- mirascope/core/cohere/dynamic_config.py +0 -24
- mirascope/core/cohere/py.typed +0 -0
- mirascope/core/cohere/stream.py +0 -113
- mirascope/core/cohere/tool.py +0 -92
- mirascope/core/gemini/__init__.py +0 -21
- mirascope/core/gemini/_call.py +0 -71
- mirascope/core/gemini/_utils/__init__.py +0 -16
- mirascope/core/gemini/_utils/_calculate_cost.py +0 -8
- mirascope/core/gemini/_utils/_convert_message_params.py +0 -74
- mirascope/core/gemini/_utils/_get_json_output.py +0 -33
- mirascope/core/gemini/_utils/_handle_stream.py +0 -33
- mirascope/core/gemini/_utils/_setup_call.py +0 -68
- mirascope/core/gemini/call_params.py +0 -28
- mirascope/core/gemini/call_response.py +0 -173
- mirascope/core/gemini/call_response_chunk.py +0 -85
- mirascope/core/gemini/dynamic_config.py +0 -26
- mirascope/core/gemini/stream.py +0 -121
- mirascope/core/gemini/tool.py +0 -104
- mirascope/core/groq/__init__.py +0 -21
- mirascope/core/groq/_call.py +0 -71
- mirascope/core/groq/_utils/__init__.py +0 -16
- mirascope/core/groq/_utils/_calculate_cost.py +0 -68
- mirascope/core/groq/_utils/_convert_message_params.py +0 -23
- mirascope/core/groq/_utils/_get_json_output.py +0 -27
- mirascope/core/groq/_utils/_handle_stream.py +0 -121
- mirascope/core/groq/_utils/_setup_call.py +0 -67
- mirascope/core/groq/call_params.py +0 -51
- mirascope/core/groq/call_response.py +0 -160
- mirascope/core/groq/call_response_chunk.py +0 -89
- mirascope/core/groq/dynamic_config.py +0 -26
- mirascope/core/groq/py.typed +0 -0
- mirascope/core/groq/stream.py +0 -136
- mirascope/core/groq/tool.py +0 -79
- mirascope/core/litellm/__init__.py +0 -6
- mirascope/core/litellm/_call.py +0 -73
- mirascope/core/litellm/_utils/__init__.py +0 -5
- mirascope/core/litellm/_utils/_setup_call.py +0 -46
- mirascope/core/litellm/py.typed +0 -0
- mirascope/core/mistral/__init__.py +0 -21
- mirascope/core/mistral/_call.py +0 -69
- mirascope/core/mistral/_utils/__init__.py +0 -16
- mirascope/core/mistral/_utils/_calculate_cost.py +0 -47
- mirascope/core/mistral/_utils/_convert_message_params.py +0 -23
- mirascope/core/mistral/_utils/_get_json_output.py +0 -28
- mirascope/core/mistral/_utils/_handle_stream.py +0 -121
- mirascope/core/mistral/_utils/_setup_call.py +0 -86
- mirascope/core/mistral/call_params.py +0 -36
- mirascope/core/mistral/call_response.py +0 -156
- mirascope/core/mistral/call_response_chunk.py +0 -84
- mirascope/core/mistral/dynamic_config.py +0 -24
- mirascope/core/mistral/py.typed +0 -0
- mirascope/core/mistral/stream.py +0 -117
- mirascope/core/mistral/tool.py +0 -77
- mirascope/core/openai/__init__.py +0 -21
- mirascope/core/openai/_call.py +0 -71
- mirascope/core/openai/_utils/__init__.py +0 -16
- mirascope/core/openai/_utils/_calculate_cost.py +0 -110
- mirascope/core/openai/_utils/_convert_message_params.py +0 -53
- mirascope/core/openai/_utils/_get_json_output.py +0 -27
- mirascope/core/openai/_utils/_handle_stream.py +0 -125
- mirascope/core/openai/_utils/_setup_call.py +0 -62
- mirascope/core/openai/call_params.py +0 -54
- mirascope/core/openai/call_response.py +0 -162
- mirascope/core/openai/call_response_chunk.py +0 -90
- mirascope/core/openai/dynamic_config.py +0 -26
- mirascope/core/openai/py.typed +0 -0
- mirascope/core/openai/stream.py +0 -148
- mirascope/core/openai/tool.py +0 -79
- mirascope/core/py.typed +0 -0
- mirascope/integrations/__init__.py +0 -20
- mirascope/integrations/_middleware_factory.py +0 -277
- mirascope/integrations/langfuse/__init__.py +0 -3
- mirascope/integrations/langfuse/_utils.py +0 -114
- mirascope/integrations/langfuse/_with_langfuse.py +0 -71
- mirascope/integrations/logfire/__init__.py +0 -3
- mirascope/integrations/logfire/_utils.py +0 -188
- mirascope/integrations/logfire/_with_logfire.py +0 -60
- mirascope/integrations/otel/__init__.py +0 -5
- mirascope/integrations/otel/_utils.py +0 -268
- mirascope/integrations/otel/_with_hyperdx.py +0 -61
- mirascope/integrations/otel/_with_otel.py +0 -60
- mirascope/integrations/tenacity.py +0 -50
- mirascope/py.typed +0 -0
- mirascope/v0/__init__.py +0 -43
- mirascope/v0/anthropic.py +0 -54
- mirascope/v0/base/__init__.py +0 -12
- mirascope/v0/base/calls.py +0 -118
- mirascope/v0/base/extractors.py +0 -122
- mirascope/v0/base/ops_utils.py +0 -207
- mirascope/v0/base/prompts.py +0 -48
- mirascope/v0/base/types.py +0 -14
- mirascope/v0/base/utils.py +0 -21
- mirascope/v0/openai.py +0 -54
- mirascope-1.0.5.dist-info/METADATA +0 -519
- mirascope-1.0.5.dist-info/RECORD +0 -198
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
"""Mirascope Router provider that routes requests through the Mirascope Router API."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
from collections.abc import Sequence
|
|
7
|
+
from typing import TYPE_CHECKING
|
|
8
|
+
from typing_extensions import Unpack
|
|
9
|
+
|
|
10
|
+
from ...context import Context, DepsT
|
|
11
|
+
from ...formatting import FormatSpec, FormattableT
|
|
12
|
+
from ...messages import Message
|
|
13
|
+
from ...responses import (
|
|
14
|
+
AsyncContextResponse,
|
|
15
|
+
AsyncContextStreamResponse,
|
|
16
|
+
AsyncResponse,
|
|
17
|
+
AsyncStreamResponse,
|
|
18
|
+
ContextResponse,
|
|
19
|
+
ContextStreamResponse,
|
|
20
|
+
Response,
|
|
21
|
+
StreamResponse,
|
|
22
|
+
)
|
|
23
|
+
from ...tools import (
|
|
24
|
+
AsyncContextToolkit,
|
|
25
|
+
AsyncToolkit,
|
|
26
|
+
ContextToolkit,
|
|
27
|
+
Toolkit,
|
|
28
|
+
)
|
|
29
|
+
from ..base import BaseProvider, Provider
|
|
30
|
+
from . import _utils
|
|
31
|
+
|
|
32
|
+
if TYPE_CHECKING:
|
|
33
|
+
from ...models import Params
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class MirascopeProvider(BaseProvider[None]):
|
|
37
|
+
"""Provider that routes LLM requests through the Mirascope Router API.
|
|
38
|
+
|
|
39
|
+
The Mirascope Router provides a unified API for multiple LLM providers
|
|
40
|
+
(Anthropic, Google, OpenAI) with usage tracking and cost calculation.
|
|
41
|
+
|
|
42
|
+
This provider:
|
|
43
|
+
- Takes model IDs in the format "scope/model-name" (e.g., "openai/gpt-4")
|
|
44
|
+
- Routes requests to the Mirascope Router endpoint
|
|
45
|
+
- Delegates to the appropriate underlying provider (Anthropic, Google, or OpenAI)
|
|
46
|
+
- Uses MIRASCOPE_API_KEY for authentication
|
|
47
|
+
|
|
48
|
+
Environment Variables:
|
|
49
|
+
MIRASCOPE_API_KEY: Required API key for Mirascope Router authentication
|
|
50
|
+
MIRASCOPE_ROUTER_BASE_URL: Optional base URL override
|
|
51
|
+
(default: https://mirascope.com/router/v2)
|
|
52
|
+
|
|
53
|
+
Example:
|
|
54
|
+
```python
|
|
55
|
+
import os
|
|
56
|
+
from mirascope import llm
|
|
57
|
+
|
|
58
|
+
os.environ["MIRASCOPE_API_KEY"] = "mk..."
|
|
59
|
+
|
|
60
|
+
# Register the Mirascope provider
|
|
61
|
+
llm.register_provider(
|
|
62
|
+
"mirascope",
|
|
63
|
+
scope=["anthropic/", "google/", "openai/"],
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
# Use with llm.call decorator
|
|
67
|
+
@llm.call("openai/gpt-4")
|
|
68
|
+
def recommend_book(genre: str):
|
|
69
|
+
return f"Recommend a {genre} book"
|
|
70
|
+
|
|
71
|
+
response = recommend_book("fantasy")
|
|
72
|
+
print(response.content)
|
|
73
|
+
```
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
id = "mirascope"
|
|
77
|
+
default_scope = ["anthropic/", "google/", "openai/"]
|
|
78
|
+
error_map = {}
|
|
79
|
+
"""Empty error map since MirascopeProvider delegates to underlying providers.
|
|
80
|
+
|
|
81
|
+
Error handling is performed by the underlying provider instances (Anthropic,
|
|
82
|
+
Google, OpenAI), which have their own error maps. Any exceptions that bubble
|
|
83
|
+
up from underlying providers are already converted to Mirascope exceptions.
|
|
84
|
+
"""
|
|
85
|
+
|
|
86
|
+
def __init__(
|
|
87
|
+
self, *, api_key: str | None = None, base_url: str | None = None
|
|
88
|
+
) -> None:
|
|
89
|
+
"""Initialize the Mirascope provider.
|
|
90
|
+
|
|
91
|
+
Args:
|
|
92
|
+
api_key: Mirascope API key. If not provided, reads from MIRASCOPE_API_KEY
|
|
93
|
+
environment variable.
|
|
94
|
+
base_url: Optional base URL override for the Mirascope Router. If not
|
|
95
|
+
provided, reads from MIRASCOPE_ROUTER_BASE_URL environment variable
|
|
96
|
+
or defaults to https://mirascope.com/router/v2
|
|
97
|
+
"""
|
|
98
|
+
api_key = api_key or os.environ.get("MIRASCOPE_API_KEY")
|
|
99
|
+
if not api_key:
|
|
100
|
+
raise ValueError(
|
|
101
|
+
"Mirascope API key not found. "
|
|
102
|
+
"Set MIRASCOPE_API_KEY environment variable or pass api_key parameter."
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
self.api_key = api_key
|
|
106
|
+
self.router_base_url = base_url or _utils.get_default_router_base_url()
|
|
107
|
+
self.client = None # No single client; we create per-provider clients
|
|
108
|
+
|
|
109
|
+
def get_error_status(self, e: Exception) -> int | None:
|
|
110
|
+
"""Extract HTTP status code from exception.
|
|
111
|
+
|
|
112
|
+
Since MirascopeProvider delegates to underlying providers, this method
|
|
113
|
+
is not used for direct error extraction. Underlying providers handle
|
|
114
|
+
their own status code extraction.
|
|
115
|
+
|
|
116
|
+
Args:
|
|
117
|
+
e: The exception to extract status code from.
|
|
118
|
+
|
|
119
|
+
Returns:
|
|
120
|
+
None, as status extraction is handled by underlying providers.
|
|
121
|
+
"""
|
|
122
|
+
return None
|
|
123
|
+
|
|
124
|
+
def _get_underlying_provider(self, model_id: str) -> Provider:
|
|
125
|
+
"""Get the underlying provider for a model ID.
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
model_id: Model identifier in format "scope/model-name"
|
|
129
|
+
|
|
130
|
+
Returns:
|
|
131
|
+
The appropriate cached provider instance (Anthropic, Google, or OpenAI)
|
|
132
|
+
|
|
133
|
+
Raises:
|
|
134
|
+
ValueError: If the model ID format is invalid or provider is unsupported
|
|
135
|
+
"""
|
|
136
|
+
model_scope = _utils.extract_model_scope(model_id)
|
|
137
|
+
if not model_scope:
|
|
138
|
+
raise ValueError(
|
|
139
|
+
f"Invalid model ID format: {model_id}. "
|
|
140
|
+
f"Expected format 'scope/model-name' (e.g., 'openai/gpt-4')"
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
# Use the cached function to get/create the provider
|
|
144
|
+
return _utils.create_underlying_provider(
|
|
145
|
+
model_scope=model_scope,
|
|
146
|
+
api_key=self.api_key,
|
|
147
|
+
router_base_url=self.router_base_url,
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
def _call(
|
|
151
|
+
self,
|
|
152
|
+
*,
|
|
153
|
+
model_id: str,
|
|
154
|
+
messages: Sequence[Message],
|
|
155
|
+
toolkit: Toolkit,
|
|
156
|
+
format: FormatSpec[FormattableT] | None = None,
|
|
157
|
+
**params: Unpack[Params],
|
|
158
|
+
) -> Response | Response[FormattableT]:
|
|
159
|
+
"""Generate an `llm.Response` by calling through the Mirascope Router."""
|
|
160
|
+
provider = self._get_underlying_provider(model_id)
|
|
161
|
+
return provider.call(
|
|
162
|
+
model_id=model_id,
|
|
163
|
+
messages=messages,
|
|
164
|
+
toolkit=toolkit,
|
|
165
|
+
format=format,
|
|
166
|
+
**params,
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
def _context_call(
|
|
170
|
+
self,
|
|
171
|
+
*,
|
|
172
|
+
ctx: Context[DepsT],
|
|
173
|
+
model_id: str,
|
|
174
|
+
messages: Sequence[Message],
|
|
175
|
+
toolkit: ContextToolkit[DepsT],
|
|
176
|
+
format: FormatSpec[FormattableT] | None = None,
|
|
177
|
+
**params: Unpack[Params],
|
|
178
|
+
) -> ContextResponse[DepsT, None] | ContextResponse[DepsT, FormattableT]:
|
|
179
|
+
"""Generate an `llm.ContextResponse` by calling through the Mirascope Router."""
|
|
180
|
+
provider = self._get_underlying_provider(model_id)
|
|
181
|
+
return provider.context_call(
|
|
182
|
+
ctx=ctx,
|
|
183
|
+
model_id=model_id,
|
|
184
|
+
messages=messages,
|
|
185
|
+
toolkit=toolkit,
|
|
186
|
+
format=format,
|
|
187
|
+
**params,
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
async def _call_async(
|
|
191
|
+
self,
|
|
192
|
+
*,
|
|
193
|
+
model_id: str,
|
|
194
|
+
messages: Sequence[Message],
|
|
195
|
+
toolkit: AsyncToolkit,
|
|
196
|
+
format: FormatSpec[FormattableT] | None = None,
|
|
197
|
+
**params: Unpack[Params],
|
|
198
|
+
) -> AsyncResponse | AsyncResponse[FormattableT]:
|
|
199
|
+
"""Generate an `llm.AsyncResponse` by calling through the Mirascope Router."""
|
|
200
|
+
provider = self._get_underlying_provider(model_id)
|
|
201
|
+
return await provider.call_async(
|
|
202
|
+
model_id=model_id,
|
|
203
|
+
messages=messages,
|
|
204
|
+
toolkit=toolkit,
|
|
205
|
+
format=format,
|
|
206
|
+
**params,
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
async def _context_call_async(
|
|
210
|
+
self,
|
|
211
|
+
*,
|
|
212
|
+
ctx: Context[DepsT],
|
|
213
|
+
model_id: str,
|
|
214
|
+
messages: Sequence[Message],
|
|
215
|
+
toolkit: AsyncContextToolkit[DepsT],
|
|
216
|
+
format: FormatSpec[FormattableT] | None = None,
|
|
217
|
+
**params: Unpack[Params],
|
|
218
|
+
) -> AsyncContextResponse[DepsT, None] | AsyncContextResponse[DepsT, FormattableT]:
|
|
219
|
+
"""Generate an `llm.AsyncContextResponse` by calling through the Mirascope Router."""
|
|
220
|
+
provider = self._get_underlying_provider(model_id)
|
|
221
|
+
return await provider.context_call_async(
|
|
222
|
+
ctx=ctx,
|
|
223
|
+
model_id=model_id,
|
|
224
|
+
messages=messages,
|
|
225
|
+
toolkit=toolkit,
|
|
226
|
+
format=format,
|
|
227
|
+
**params,
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
def _stream(
|
|
231
|
+
self,
|
|
232
|
+
*,
|
|
233
|
+
model_id: str,
|
|
234
|
+
messages: Sequence[Message],
|
|
235
|
+
toolkit: Toolkit,
|
|
236
|
+
format: FormatSpec[FormattableT] | None = None,
|
|
237
|
+
**params: Unpack[Params],
|
|
238
|
+
) -> StreamResponse | StreamResponse[FormattableT]:
|
|
239
|
+
"""Stream an `llm.StreamResponse` by calling through the Mirascope Router."""
|
|
240
|
+
provider = self._get_underlying_provider(model_id)
|
|
241
|
+
return provider.stream(
|
|
242
|
+
model_id=model_id,
|
|
243
|
+
messages=messages,
|
|
244
|
+
toolkit=toolkit,
|
|
245
|
+
format=format,
|
|
246
|
+
**params,
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
def _context_stream(
|
|
250
|
+
self,
|
|
251
|
+
*,
|
|
252
|
+
ctx: Context[DepsT],
|
|
253
|
+
model_id: str,
|
|
254
|
+
messages: Sequence[Message],
|
|
255
|
+
toolkit: ContextToolkit[DepsT],
|
|
256
|
+
format: FormatSpec[FormattableT] | None = None,
|
|
257
|
+
**params: Unpack[Params],
|
|
258
|
+
) -> (
|
|
259
|
+
ContextStreamResponse[DepsT, None] | ContextStreamResponse[DepsT, FormattableT]
|
|
260
|
+
):
|
|
261
|
+
"""Stream an `llm.ContextStreamResponse` by calling through the Mirascope Router."""
|
|
262
|
+
provider = self._get_underlying_provider(model_id)
|
|
263
|
+
return provider.context_stream(
|
|
264
|
+
ctx=ctx,
|
|
265
|
+
model_id=model_id,
|
|
266
|
+
messages=messages,
|
|
267
|
+
toolkit=toolkit,
|
|
268
|
+
format=format,
|
|
269
|
+
**params,
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
async def _stream_async(
|
|
273
|
+
self,
|
|
274
|
+
*,
|
|
275
|
+
model_id: str,
|
|
276
|
+
messages: Sequence[Message],
|
|
277
|
+
toolkit: AsyncToolkit,
|
|
278
|
+
format: FormatSpec[FormattableT] | None = None,
|
|
279
|
+
**params: Unpack[Params],
|
|
280
|
+
) -> AsyncStreamResponse | AsyncStreamResponse[FormattableT]:
|
|
281
|
+
"""Stream an `llm.AsyncStreamResponse` by calling through the Mirascope Router."""
|
|
282
|
+
provider = self._get_underlying_provider(model_id)
|
|
283
|
+
return await provider.stream_async(
|
|
284
|
+
model_id=model_id,
|
|
285
|
+
messages=messages,
|
|
286
|
+
toolkit=toolkit,
|
|
287
|
+
format=format,
|
|
288
|
+
**params,
|
|
289
|
+
)
|
|
290
|
+
|
|
291
|
+
async def _context_stream_async(
|
|
292
|
+
self,
|
|
293
|
+
*,
|
|
294
|
+
ctx: Context[DepsT],
|
|
295
|
+
model_id: str,
|
|
296
|
+
messages: Sequence[Message],
|
|
297
|
+
toolkit: AsyncContextToolkit[DepsT],
|
|
298
|
+
format: FormatSpec[FormattableT] | None = None,
|
|
299
|
+
**params: Unpack[Params],
|
|
300
|
+
) -> (
|
|
301
|
+
AsyncContextStreamResponse[DepsT, None]
|
|
302
|
+
| AsyncContextStreamResponse[DepsT, FormattableT]
|
|
303
|
+
):
|
|
304
|
+
"""Stream an `llm.AsyncContextStreamResponse` by calling through the Mirascope Router."""
|
|
305
|
+
provider = self._get_underlying_provider(model_id)
|
|
306
|
+
return await provider.context_stream_async(
|
|
307
|
+
ctx=ctx,
|
|
308
|
+
model_id=model_id,
|
|
309
|
+
messages=messages,
|
|
310
|
+
toolkit=toolkit,
|
|
311
|
+
format=format,
|
|
312
|
+
**params,
|
|
313
|
+
)
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections.abc import Callable
|
|
4
|
+
from typing import TYPE_CHECKING, TypeAlias, TypedDict
|
|
5
|
+
|
|
6
|
+
import mlx.core as mx
|
|
7
|
+
from huggingface_hub.errors import LocalEntryNotFoundError
|
|
8
|
+
from mlx_lm.generate import GenerationResponse
|
|
9
|
+
from mlx_lm.sample_utils import make_sampler
|
|
10
|
+
|
|
11
|
+
from ...exceptions import NotFoundError
|
|
12
|
+
from ...responses import FinishReason, Usage
|
|
13
|
+
from ..base import ProviderErrorMap, _utils as _base_utils
|
|
14
|
+
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
from ...models import Params
|
|
17
|
+
|
|
18
|
+
Sampler: TypeAlias = Callable[[mx.array], mx.array]
|
|
19
|
+
|
|
20
|
+
# Error mapping for MLX provider
|
|
21
|
+
MLX_ERROR_MAP: ProviderErrorMap = {
|
|
22
|
+
LocalEntryNotFoundError: NotFoundError,
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class MakeSamplerKwargs(TypedDict, total=False):
|
|
27
|
+
"""Keyword arguments to be used for `mlx_lm`-s `make_sampler` function.
|
|
28
|
+
|
|
29
|
+
Some of these settings are directly match the generic client parameters
|
|
30
|
+
as defined in the `Params` class. See mirascope.llm.providers.Params for
|
|
31
|
+
more details.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
temp: float
|
|
35
|
+
"The temperature for sampling, if 0 the argmax is used."
|
|
36
|
+
|
|
37
|
+
top_p: float
|
|
38
|
+
"Nulceus sampling, higher means model considers more less likely words."
|
|
39
|
+
|
|
40
|
+
min_p: float
|
|
41
|
+
"""The minimum value (scaled by the top token's probability) that a token
|
|
42
|
+
probability must have to be considered."""
|
|
43
|
+
|
|
44
|
+
min_tokens_to_keep: int
|
|
45
|
+
"Minimum number of tokens that cannot be filtered by min_p sampling."
|
|
46
|
+
|
|
47
|
+
top_k: int
|
|
48
|
+
"The top k tokens ranked by probability to constrain the sampling to."
|
|
49
|
+
|
|
50
|
+
xtc_probability: float
|
|
51
|
+
"The probability of applying XTC sampling."
|
|
52
|
+
|
|
53
|
+
xtc_threshold: float
|
|
54
|
+
"The threshold the probs need to reach for being sampled."
|
|
55
|
+
|
|
56
|
+
xtc_special_tokens: list[int]
|
|
57
|
+
"List of special tokens IDs to be excluded from XTC sampling."
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class StreamGenerateKwargs(TypedDict, total=False):
|
|
61
|
+
"""Keyword arguments for the `mlx-lm.stream_generate` function."""
|
|
62
|
+
|
|
63
|
+
max_tokens: int
|
|
64
|
+
"The maximum number of tokens to generate."
|
|
65
|
+
|
|
66
|
+
sampler: Sampler
|
|
67
|
+
"A sampler for sampling token from a vector of logits."
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def encode_params(params: Params) -> tuple[int | None, StreamGenerateKwargs]:
|
|
71
|
+
"""Convert generic params to mlx-lm stream_generate kwargs.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
params: The generic parameters.
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
The mlx-lm specific stream_generate keyword arguments.
|
|
78
|
+
"""
|
|
79
|
+
kwargs: StreamGenerateKwargs = {}
|
|
80
|
+
|
|
81
|
+
with _base_utils.ensure_all_params_accessed(
|
|
82
|
+
params=params,
|
|
83
|
+
provider_id="mlx",
|
|
84
|
+
unsupported_params=["stop_sequences", "thinking"],
|
|
85
|
+
) as param_accessor:
|
|
86
|
+
if param_accessor.max_tokens is not None:
|
|
87
|
+
kwargs["max_tokens"] = param_accessor.max_tokens
|
|
88
|
+
else:
|
|
89
|
+
kwargs["max_tokens"] = -1
|
|
90
|
+
|
|
91
|
+
sampler_kwargs = MakeSamplerKwargs({})
|
|
92
|
+
if param_accessor.temperature is not None:
|
|
93
|
+
sampler_kwargs["temp"] = param_accessor.temperature
|
|
94
|
+
if param_accessor.top_k is not None:
|
|
95
|
+
sampler_kwargs["top_k"] = param_accessor.top_k
|
|
96
|
+
if param_accessor.top_p is not None:
|
|
97
|
+
sampler_kwargs["top_p"] = param_accessor.top_p
|
|
98
|
+
|
|
99
|
+
kwargs["sampler"] = make_sampler(**sampler_kwargs)
|
|
100
|
+
|
|
101
|
+
return param_accessor.seed, kwargs
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def extract_finish_reason(response: GenerationResponse | None) -> FinishReason | None:
|
|
105
|
+
"""Extract the finish reason from an MLX generation response.
|
|
106
|
+
|
|
107
|
+
Args:
|
|
108
|
+
response: The MLX generation response to extract from.
|
|
109
|
+
|
|
110
|
+
Returns:
|
|
111
|
+
The normalized finish reason, or None if not applicable.
|
|
112
|
+
"""
|
|
113
|
+
if response is None:
|
|
114
|
+
return None
|
|
115
|
+
|
|
116
|
+
if response.finish_reason == "length":
|
|
117
|
+
return FinishReason.MAX_TOKENS
|
|
118
|
+
|
|
119
|
+
return None
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def extract_usage(response: GenerationResponse | None) -> Usage | None:
|
|
123
|
+
"""Extract usage information from an MLX generation response.
|
|
124
|
+
|
|
125
|
+
Args:
|
|
126
|
+
response: The MLX generation response to extract from.
|
|
127
|
+
|
|
128
|
+
Returns:
|
|
129
|
+
The Usage object with token counts, or None if not applicable.
|
|
130
|
+
"""
|
|
131
|
+
if response is None:
|
|
132
|
+
return None
|
|
133
|
+
|
|
134
|
+
return Usage(
|
|
135
|
+
input_tokens=response.prompt_tokens,
|
|
136
|
+
output_tokens=response.generation_tokens,
|
|
137
|
+
cache_read_tokens=0,
|
|
138
|
+
cache_write_tokens=0,
|
|
139
|
+
reasoning_tokens=0,
|
|
140
|
+
raw=response,
|
|
141
|
+
)
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import abc
|
|
4
|
+
from collections.abc import Iterable, Sequence
|
|
5
|
+
from typing import TypeAlias
|
|
6
|
+
|
|
7
|
+
from mlx_lm.generate import GenerationResponse
|
|
8
|
+
|
|
9
|
+
from ....formatting import Format, FormatSpec, FormattableT
|
|
10
|
+
from ....messages import AssistantContent, Message
|
|
11
|
+
from ....responses import ChunkIterator
|
|
12
|
+
from ....tools import AnyToolSchema, BaseToolkit
|
|
13
|
+
|
|
14
|
+
TokenIds: TypeAlias = list[int]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class BaseEncoder(abc.ABC):
|
|
18
|
+
"""Abstract base class for Mirascope <> MLX encoding and decoding."""
|
|
19
|
+
|
|
20
|
+
@abc.abstractmethod
|
|
21
|
+
def encode_request(
|
|
22
|
+
self,
|
|
23
|
+
messages: Sequence[Message],
|
|
24
|
+
tools: BaseToolkit[AnyToolSchema],
|
|
25
|
+
format: FormatSpec[FormattableT] | None,
|
|
26
|
+
) -> tuple[Sequence[Message], Format[FormattableT] | None, TokenIds]:
|
|
27
|
+
"""Encode the request messages into a format suitable for the model.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
messages: The sequence of messages to encode.
|
|
31
|
+
tools: Optional sequence of tool schemas or toolkit for the model.
|
|
32
|
+
format: Optional format specification for structured outputs.
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
A tuple containing:
|
|
36
|
+
- The processed messages
|
|
37
|
+
- The format specification (if provided)
|
|
38
|
+
- The encoded prompt as token IDs
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
...
|
|
42
|
+
|
|
43
|
+
@abc.abstractmethod
|
|
44
|
+
def decode_response(
|
|
45
|
+
self, stream: Iterable[GenerationResponse]
|
|
46
|
+
) -> tuple[AssistantContent, GenerationResponse | None]:
|
|
47
|
+
"""Decode a stream of MLX generation responses into assistant content.
|
|
48
|
+
|
|
49
|
+
Args:
|
|
50
|
+
stream: An iterable of MLX generation responses.
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
A tuple containing:
|
|
54
|
+
- The decoded assistant content
|
|
55
|
+
- The final generation response (if available)
|
|
56
|
+
"""
|
|
57
|
+
...
|
|
58
|
+
|
|
59
|
+
@abc.abstractmethod
|
|
60
|
+
def decode_stream(self, stream: Iterable[GenerationResponse]) -> ChunkIterator:
|
|
61
|
+
"""Decode a stream of MLX generation responses into an iterable of chunks.
|
|
62
|
+
|
|
63
|
+
Args:
|
|
64
|
+
stream: An iterable of MLX generation responses.
|
|
65
|
+
|
|
66
|
+
Returns:
|
|
67
|
+
A ChunkIterator yielding content chunks for streaming responses.
|
|
68
|
+
"""
|
|
69
|
+
...
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import io
|
|
2
|
+
from collections.abc import Iterable, Sequence
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import Literal, cast
|
|
5
|
+
from typing_extensions import TypedDict
|
|
6
|
+
|
|
7
|
+
from mlx_lm.generate import GenerationResponse
|
|
8
|
+
from transformers import PreTrainedTokenizer
|
|
9
|
+
|
|
10
|
+
from ....content import ContentPart, TextChunk, TextEndChunk, TextStartChunk
|
|
11
|
+
from ....formatting import Format, FormatSpec, FormattableT
|
|
12
|
+
from ....messages import AssistantContent, Message
|
|
13
|
+
from ....responses import (
|
|
14
|
+
ChunkIterator,
|
|
15
|
+
FinishReasonChunk,
|
|
16
|
+
RawStreamEventChunk,
|
|
17
|
+
UsageDeltaChunk,
|
|
18
|
+
)
|
|
19
|
+
from ....tools import AnyToolSchema, BaseToolkit
|
|
20
|
+
from .. import _utils
|
|
21
|
+
from .base import BaseEncoder, TokenIds
|
|
22
|
+
|
|
23
|
+
HFRole = Literal["system", "user", "assistant"] | str
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class TransformersMessage(TypedDict):
|
|
27
|
+
"""Message in Transformers format."""
|
|
28
|
+
|
|
29
|
+
role: HFRole
|
|
30
|
+
content: str
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _encode_content(content: Sequence[ContentPart]) -> str:
|
|
34
|
+
"""Encode content parts into a string.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
content: The sequence of content parts to encode.
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
The encoded content as a string.
|
|
41
|
+
|
|
42
|
+
Raises:
|
|
43
|
+
NotImplementedError: If content contains non-text parts.
|
|
44
|
+
"""
|
|
45
|
+
if len(content) == 1 and content[0].type == "text":
|
|
46
|
+
return content[0].text
|
|
47
|
+
|
|
48
|
+
raise NotImplementedError("Only text content is supported in this example.")
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _encode_message(message: Message) -> TransformersMessage:
|
|
52
|
+
"""Encode a Mirascope message into Transformers format.
|
|
53
|
+
|
|
54
|
+
Args:
|
|
55
|
+
message: The message to encode.
|
|
56
|
+
|
|
57
|
+
Returns:
|
|
58
|
+
The encoded message in Transformers format.
|
|
59
|
+
|
|
60
|
+
Raises:
|
|
61
|
+
ValueError: If the message role is not supported.
|
|
62
|
+
"""
|
|
63
|
+
if message.role == "system":
|
|
64
|
+
return TransformersMessage(role="system", content=message.content.text)
|
|
65
|
+
elif message.role == "assistant" or message.role == "user":
|
|
66
|
+
return TransformersMessage(
|
|
67
|
+
role=message.role, content=_encode_content(message.content)
|
|
68
|
+
)
|
|
69
|
+
else:
|
|
70
|
+
raise ValueError(f"Unsupported message type: {type(message)}")
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@dataclass(frozen=True)
|
|
74
|
+
class TransformersEncoder(BaseEncoder):
|
|
75
|
+
"""Encoder for Transformers models."""
|
|
76
|
+
|
|
77
|
+
tokenizer: PreTrainedTokenizer
|
|
78
|
+
"""The tokenizer to use for encoding."""
|
|
79
|
+
|
|
80
|
+
def encode_request(
|
|
81
|
+
self,
|
|
82
|
+
messages: Sequence[Message],
|
|
83
|
+
tools: BaseToolkit[AnyToolSchema],
|
|
84
|
+
format: FormatSpec[FormattableT] | None,
|
|
85
|
+
) -> tuple[Sequence[Message], Format[FormattableT] | None, TokenIds]:
|
|
86
|
+
"""Encode a request into a format suitable for the model."""
|
|
87
|
+
if tools.tools:
|
|
88
|
+
raise NotImplementedError("Tool usage is not supported.")
|
|
89
|
+
if format is not None:
|
|
90
|
+
raise NotImplementedError("Formatting is not supported.")
|
|
91
|
+
|
|
92
|
+
hf_messages: list[TransformersMessage] = [
|
|
93
|
+
_encode_message(msg) for msg in messages
|
|
94
|
+
]
|
|
95
|
+
prompt_text = cast(
|
|
96
|
+
str,
|
|
97
|
+
self.tokenizer.apply_chat_template( # pyright: ignore[reportUnknownMemberType]
|
|
98
|
+
cast(list[dict[str, str]], hf_messages),
|
|
99
|
+
tokenize=False,
|
|
100
|
+
add_generation_prompt=True,
|
|
101
|
+
),
|
|
102
|
+
)
|
|
103
|
+
return (
|
|
104
|
+
messages,
|
|
105
|
+
format,
|
|
106
|
+
self.tokenizer.encode(prompt_text, add_special_tokens=False), # pyright: ignore[reportUnknownMemberType]
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
def decode_response(
|
|
110
|
+
self, stream: Iterable[GenerationResponse]
|
|
111
|
+
) -> tuple[AssistantContent, GenerationResponse | None]:
|
|
112
|
+
"""Decode a response into a format suitable for the model."""
|
|
113
|
+
with io.StringIO() as buffer:
|
|
114
|
+
last_response: GenerationResponse | None = None
|
|
115
|
+
for response in stream:
|
|
116
|
+
buffer.write(response.text)
|
|
117
|
+
last_response = response
|
|
118
|
+
|
|
119
|
+
return buffer.getvalue(), last_response
|
|
120
|
+
|
|
121
|
+
def decode_stream(self, stream: Iterable[GenerationResponse]) -> ChunkIterator:
|
|
122
|
+
"""Decode a stream of responses into a format suitable for the model."""
|
|
123
|
+
yield TextStartChunk()
|
|
124
|
+
|
|
125
|
+
response: GenerationResponse | None = None
|
|
126
|
+
for response in stream:
|
|
127
|
+
yield RawStreamEventChunk(raw_stream_event=response)
|
|
128
|
+
yield TextChunk(delta=response.text)
|
|
129
|
+
|
|
130
|
+
assert response is not None
|
|
131
|
+
finish_reason = _utils.extract_finish_reason(response)
|
|
132
|
+
if finish_reason is not None:
|
|
133
|
+
yield FinishReasonChunk(finish_reason=finish_reason)
|
|
134
|
+
else:
|
|
135
|
+
yield TextEndChunk()
|
|
136
|
+
|
|
137
|
+
# Emit usage delta if available
|
|
138
|
+
usage = _utils.extract_usage(response)
|
|
139
|
+
if usage:
|
|
140
|
+
yield UsageDeltaChunk(
|
|
141
|
+
input_tokens=usage.input_tokens,
|
|
142
|
+
output_tokens=usage.output_tokens,
|
|
143
|
+
cache_read_tokens=usage.cache_read_tokens,
|
|
144
|
+
cache_write_tokens=usage.cache_write_tokens,
|
|
145
|
+
reasoning_tokens=usage.reasoning_tokens,
|
|
146
|
+
)
|