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,232 @@
|
|
|
1
|
+
"""Explicit span management utilities for `mirascope.ops`."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
from contextvars import Token
|
|
7
|
+
from typing import TYPE_CHECKING, Any
|
|
8
|
+
|
|
9
|
+
from opentelemetry import context as otel_context, trace as otel_trace
|
|
10
|
+
from opentelemetry.trace import (
|
|
11
|
+
SpanContext,
|
|
12
|
+
Status,
|
|
13
|
+
StatusCode,
|
|
14
|
+
format_span_id,
|
|
15
|
+
format_trace_id,
|
|
16
|
+
)
|
|
17
|
+
from opentelemetry.util.types import AttributeValue
|
|
18
|
+
|
|
19
|
+
from .session import current_session
|
|
20
|
+
from .utils import json_dumps
|
|
21
|
+
|
|
22
|
+
if TYPE_CHECKING:
|
|
23
|
+
from opentelemetry.context import Context
|
|
24
|
+
|
|
25
|
+
logger = logging.getLogger("mirascope.ops")
|
|
26
|
+
_warned_noop = False
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class Span:
|
|
30
|
+
"""Context-managed span for explicit tracing.
|
|
31
|
+
|
|
32
|
+
Creates a child span within the current trace context. Acts as a no-op
|
|
33
|
+
if tracing is not configured.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
def __init__(self, name: str, **attributes: AttributeValue) -> None:
|
|
37
|
+
"""Initialize a new span with the given name.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
name: Name for the span.
|
|
41
|
+
**attributes: Initial attributes to set on the span.
|
|
42
|
+
"""
|
|
43
|
+
self._name = name
|
|
44
|
+
self._initial_attributes = attributes
|
|
45
|
+
self._span: otel_trace.Span | None = None
|
|
46
|
+
self._token: Token[Context] | None = None
|
|
47
|
+
self._is_noop = True
|
|
48
|
+
self._finished = False
|
|
49
|
+
|
|
50
|
+
def __enter__(self) -> Span:
|
|
51
|
+
"""Enter the span context.
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
This span instance for use within the context.
|
|
55
|
+
"""
|
|
56
|
+
tracer = otel_trace.get_tracer("mirascope.ops")
|
|
57
|
+
self._span = tracer.start_span(self._name)
|
|
58
|
+
|
|
59
|
+
if self._span.__class__.__name__ == "NonRecordingSpan":
|
|
60
|
+
self._is_noop = True
|
|
61
|
+
self._span = None
|
|
62
|
+
global _warned_noop
|
|
63
|
+
if not _warned_noop:
|
|
64
|
+
logger.warning(
|
|
65
|
+
f"mirascope tracing is not configured; Span('{self._name}') is a no-op."
|
|
66
|
+
)
|
|
67
|
+
_warned_noop = True
|
|
68
|
+
else:
|
|
69
|
+
self._is_noop = False
|
|
70
|
+
self._span.set_attribute("mirascope.type", "trace")
|
|
71
|
+
|
|
72
|
+
session_ctx = current_session()
|
|
73
|
+
if session_ctx is not None:
|
|
74
|
+
self._span.set_attribute("mirascope.ops.session.id", session_ctx.id)
|
|
75
|
+
if session_ctx.attributes is not None:
|
|
76
|
+
self._span.set_attribute(
|
|
77
|
+
"mirascope.ops.session.attributes",
|
|
78
|
+
json_dumps(session_ctx.attributes),
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
self._token = otel_context.attach(
|
|
82
|
+
otel_trace.set_span_in_context(self._span)
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
if self._initial_attributes:
|
|
86
|
+
self.set(**self._initial_attributes)
|
|
87
|
+
|
|
88
|
+
return self
|
|
89
|
+
|
|
90
|
+
def __exit__(
|
|
91
|
+
self,
|
|
92
|
+
exc_type: type[BaseException] | None,
|
|
93
|
+
exc: BaseException | None,
|
|
94
|
+
tb: Any, # noqa: ANN401
|
|
95
|
+
) -> None:
|
|
96
|
+
"""Exit the span context.
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
exc_type: Exception type if an exception was raised.
|
|
100
|
+
exc: Exception instance if an exception was raised.
|
|
101
|
+
tb: Traceback if an exception was raised.
|
|
102
|
+
"""
|
|
103
|
+
if self._span and not self._finished:
|
|
104
|
+
if exc is not None:
|
|
105
|
+
self._span.record_exception(exc)
|
|
106
|
+
self._span.set_status(Status(StatusCode.ERROR))
|
|
107
|
+
self.finish()
|
|
108
|
+
|
|
109
|
+
def set(self, **attributes: AttributeValue) -> None:
|
|
110
|
+
"""Set attributes on the current span.
|
|
111
|
+
|
|
112
|
+
Args:
|
|
113
|
+
**attributes: Key-value pairs to set as span attributes.
|
|
114
|
+
"""
|
|
115
|
+
if self._span and not self._finished:
|
|
116
|
+
for key, value in attributes.items():
|
|
117
|
+
self._span.set_attribute(key, value)
|
|
118
|
+
|
|
119
|
+
def event(self, name: str, **attributes: AttributeValue) -> None:
|
|
120
|
+
"""Record an event within the span.
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
name: Name of the event.
|
|
124
|
+
**attributes: Event attributes as key-value pairs.
|
|
125
|
+
"""
|
|
126
|
+
if self._span and not self._finished:
|
|
127
|
+
self._span.add_event(name, attributes=attributes)
|
|
128
|
+
|
|
129
|
+
def debug(self, message: str, **additional_attributes: AttributeValue) -> None:
|
|
130
|
+
"""Log a debug message within the span.
|
|
131
|
+
|
|
132
|
+
Args:
|
|
133
|
+
message: Debug message text.
|
|
134
|
+
**additional_attributes: Additional structured attributes for the log entry.
|
|
135
|
+
"""
|
|
136
|
+
self.event("debug", level="debug", message=message, **additional_attributes)
|
|
137
|
+
|
|
138
|
+
def info(self, message: str, **additional_attributes: AttributeValue) -> None:
|
|
139
|
+
"""Log an info message within the span.
|
|
140
|
+
|
|
141
|
+
Args:
|
|
142
|
+
message: Info message text.
|
|
143
|
+
**additional_attributes: Additional structured attributes for the log entry.
|
|
144
|
+
"""
|
|
145
|
+
self.event("info", level="info", message=message, **additional_attributes)
|
|
146
|
+
|
|
147
|
+
def warning(self, message: str, **additional_attributes: AttributeValue) -> None:
|
|
148
|
+
"""Log a warning message within the span.
|
|
149
|
+
|
|
150
|
+
Args:
|
|
151
|
+
message: Warning message text.
|
|
152
|
+
**additional_attributes: Additional structured attributes for the log entry.
|
|
153
|
+
"""
|
|
154
|
+
self.event("warning", level="warning", message=message, **additional_attributes)
|
|
155
|
+
|
|
156
|
+
def error(self, message: str, **additional_attributes: AttributeValue) -> None:
|
|
157
|
+
"""Log an error message within the span.
|
|
158
|
+
|
|
159
|
+
Args:
|
|
160
|
+
message: Error message text.
|
|
161
|
+
**additional_attributes: Additional structured attributes for the log entry.
|
|
162
|
+
"""
|
|
163
|
+
self.event("error", level="error", message=message, **additional_attributes)
|
|
164
|
+
if self._span and not self._finished:
|
|
165
|
+
self._span.set_status(Status(StatusCode.ERROR))
|
|
166
|
+
|
|
167
|
+
def critical(self, message: str, **additional_attributes: AttributeValue) -> None:
|
|
168
|
+
"""Log a critical message within the span.
|
|
169
|
+
|
|
170
|
+
Args:
|
|
171
|
+
message: Critical message text.
|
|
172
|
+
**additional_attributes: Additional structured attributes for the log entry.
|
|
173
|
+
"""
|
|
174
|
+
self.event("critical", level="error", message=message, **additional_attributes)
|
|
175
|
+
if self._span and not self._finished:
|
|
176
|
+
self._span.set_status(Status(StatusCode.ERROR))
|
|
177
|
+
|
|
178
|
+
def finish(self) -> None:
|
|
179
|
+
"""Explicitly finish the span."""
|
|
180
|
+
if not self._finished:
|
|
181
|
+
self._finished = True
|
|
182
|
+
if self._span:
|
|
183
|
+
self._span.end()
|
|
184
|
+
if self._token:
|
|
185
|
+
otel_context.detach(self._token)
|
|
186
|
+
self._token = None
|
|
187
|
+
|
|
188
|
+
@property
|
|
189
|
+
def span_id(self) -> str | None:
|
|
190
|
+
"""Get the span ID if available.
|
|
191
|
+
|
|
192
|
+
Returns:
|
|
193
|
+
The span ID or None if not available.
|
|
194
|
+
"""
|
|
195
|
+
if span_context := self.span_context:
|
|
196
|
+
return format_span_id(span_context.span_id)
|
|
197
|
+
return None
|
|
198
|
+
|
|
199
|
+
@property
|
|
200
|
+
def trace_id(self) -> str | None:
|
|
201
|
+
if span_context := self.span_context:
|
|
202
|
+
return format_trace_id(span_context.trace_id)
|
|
203
|
+
return None
|
|
204
|
+
|
|
205
|
+
@property
|
|
206
|
+
def is_noop(self) -> bool:
|
|
207
|
+
"""Check if this is a no-op span.
|
|
208
|
+
|
|
209
|
+
Returns:
|
|
210
|
+
True if tracing is disabled, False otherwise.
|
|
211
|
+
"""
|
|
212
|
+
return self._is_noop
|
|
213
|
+
|
|
214
|
+
@property
|
|
215
|
+
def span_context(self) -> SpanContext | None:
|
|
216
|
+
"""Return the span context if available."""
|
|
217
|
+
if otel_span := self._span:
|
|
218
|
+
return otel_span.get_span_context()
|
|
219
|
+
return None
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
def span(name: str, **attributes: AttributeValue) -> Span:
|
|
223
|
+
"""Create a new span context manager.
|
|
224
|
+
|
|
225
|
+
Args:
|
|
226
|
+
name: Name for the new span.
|
|
227
|
+
**attributes: Initial attributes to set on the span.
|
|
228
|
+
|
|
229
|
+
Returns:
|
|
230
|
+
A Span context manager that creates a child span when entered.
|
|
231
|
+
"""
|
|
232
|
+
return Span(name, **attributes)
|
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
"""Traced call wrappers for @ops.trace decorated @llm.call functions."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass, field
|
|
6
|
+
from typing import Any, Generic, TypeVar
|
|
7
|
+
from typing_extensions import TypeIs
|
|
8
|
+
|
|
9
|
+
from ..._utils import copy_function_metadata
|
|
10
|
+
from ...llm.calls import AsyncCall, AsyncContextCall, Call, ContextCall
|
|
11
|
+
from ...llm.context import Context, DepsT
|
|
12
|
+
from ...llm.formatting import FormattableT
|
|
13
|
+
from ...llm.responses import (
|
|
14
|
+
AsyncContextResponse,
|
|
15
|
+
AsyncContextStreamResponse,
|
|
16
|
+
AsyncResponse,
|
|
17
|
+
AsyncStreamResponse,
|
|
18
|
+
ContextResponse,
|
|
19
|
+
ContextStreamResponse,
|
|
20
|
+
Response,
|
|
21
|
+
StreamResponse,
|
|
22
|
+
)
|
|
23
|
+
from ...llm.types import P
|
|
24
|
+
from .protocols import (
|
|
25
|
+
AsyncFunction,
|
|
26
|
+
AsyncSpanFunction,
|
|
27
|
+
R,
|
|
28
|
+
SyncFunction,
|
|
29
|
+
SyncSpanFunction,
|
|
30
|
+
)
|
|
31
|
+
from .traced_functions import (
|
|
32
|
+
AsyncTrace,
|
|
33
|
+
AsyncTracedContextFunction,
|
|
34
|
+
AsyncTracedFunction,
|
|
35
|
+
Trace,
|
|
36
|
+
TracedContextFunction,
|
|
37
|
+
TracedFunction,
|
|
38
|
+
)
|
|
39
|
+
from .utils import get_original_fn
|
|
40
|
+
|
|
41
|
+
CallT = TypeVar(
|
|
42
|
+
"CallT",
|
|
43
|
+
bound=Call[..., Any]
|
|
44
|
+
| AsyncCall[..., Any]
|
|
45
|
+
| ContextCall[..., Any, Any]
|
|
46
|
+
| AsyncContextCall[..., Any, Any],
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def is_call_type(
|
|
51
|
+
fn: (
|
|
52
|
+
SyncFunction[P, R]
|
|
53
|
+
| AsyncFunction[P, R]
|
|
54
|
+
| SyncSpanFunction[P, R]
|
|
55
|
+
| AsyncSpanFunction[P, R]
|
|
56
|
+
| ContextCall[P, DepsT, FormattableT]
|
|
57
|
+
| AsyncContextCall[P, DepsT, FormattableT]
|
|
58
|
+
| Call[P, FormattableT]
|
|
59
|
+
| AsyncCall[P, FormattableT]
|
|
60
|
+
),
|
|
61
|
+
) -> TypeIs[
|
|
62
|
+
ContextCall[P, DepsT, FormattableT]
|
|
63
|
+
| AsyncContextCall[P, DepsT, FormattableT]
|
|
64
|
+
| Call[P, FormattableT]
|
|
65
|
+
| AsyncCall[P, FormattableT]
|
|
66
|
+
]:
|
|
67
|
+
"""Check if fn is any of the Call types."""
|
|
68
|
+
return isinstance(fn, Call | AsyncCall | ContextCall | AsyncContextCall)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def wrap_call(
|
|
72
|
+
fn: (
|
|
73
|
+
ContextCall[P, DepsT, FormattableT]
|
|
74
|
+
| AsyncContextCall[P, DepsT, FormattableT]
|
|
75
|
+
| Call[P, FormattableT]
|
|
76
|
+
| AsyncCall[P, FormattableT]
|
|
77
|
+
),
|
|
78
|
+
tags: tuple[str, ...],
|
|
79
|
+
metadata: dict[str, str] | None = None,
|
|
80
|
+
) -> (
|
|
81
|
+
TracedContextCall[P, DepsT, FormattableT]
|
|
82
|
+
| TracedAsyncContextCall[P, DepsT, FormattableT]
|
|
83
|
+
| TracedCall[P, FormattableT]
|
|
84
|
+
| TracedAsyncCall[P, FormattableT]
|
|
85
|
+
):
|
|
86
|
+
"""Wrap a Call object with the appropriate TracedCall type."""
|
|
87
|
+
metadata = metadata or {}
|
|
88
|
+
if isinstance(fn, AsyncContextCall):
|
|
89
|
+
return TracedAsyncContextCall(_call=fn, tags=tags, metadata=metadata)
|
|
90
|
+
elif isinstance(fn, ContextCall):
|
|
91
|
+
return TracedContextCall(_call=fn, tags=tags, metadata=metadata)
|
|
92
|
+
elif isinstance(fn, AsyncCall):
|
|
93
|
+
return TracedAsyncCall(_call=fn, tags=tags, metadata=metadata)
|
|
94
|
+
else:
|
|
95
|
+
return TracedCall(_call=fn, tags=tags, metadata=metadata)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
@dataclass(kw_only=True)
|
|
99
|
+
class _BaseTracedCall(Generic[CallT]):
|
|
100
|
+
"""Wrapper for traced Call objects."""
|
|
101
|
+
|
|
102
|
+
_call: CallT
|
|
103
|
+
"""The original unwrapped Call object."""
|
|
104
|
+
|
|
105
|
+
tags: tuple[str, ...]
|
|
106
|
+
"""Tags to be associated with traced calls."""
|
|
107
|
+
|
|
108
|
+
metadata: dict[str, str] = field(default_factory=dict)
|
|
109
|
+
"""Arbitrary key-value pairs for additional metadata."""
|
|
110
|
+
|
|
111
|
+
__name__: str = field(init=False, repr=False, default="")
|
|
112
|
+
"""The name of the underlying function (preserved for decorator stacking)."""
|
|
113
|
+
|
|
114
|
+
def __post_init__(self) -> None:
|
|
115
|
+
"""Preserve standard function attributes for decorator stacking."""
|
|
116
|
+
original_fn = get_original_fn(self._call.prompt.fn)
|
|
117
|
+
copy_function_metadata(self, original_fn)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
@dataclass(kw_only=True)
|
|
121
|
+
class TracedCall(_BaseTracedCall[Call[P, FormattableT]]):
|
|
122
|
+
"""Traced wrapper for traced synchronous Call objects.
|
|
123
|
+
|
|
124
|
+
When @ops.trace decorates an @llm.call, it returns a TracedCall that wraps
|
|
125
|
+
the call and stream methods with tracing capabilities.
|
|
126
|
+
|
|
127
|
+
Example:
|
|
128
|
+
```python
|
|
129
|
+
@ops.trace
|
|
130
|
+
@llm.call("gpt-4o-mini")
|
|
131
|
+
def recommend_book(genre: str):
|
|
132
|
+
return f"Recommend a {genre} book"
|
|
133
|
+
|
|
134
|
+
# Returns Response directly (but execution is traced)
|
|
135
|
+
response = recommend_book("fantasy")
|
|
136
|
+
print(response.content)
|
|
137
|
+
|
|
138
|
+
# Same as __call__
|
|
139
|
+
response = recommend_book.call("fantasy")
|
|
140
|
+
|
|
141
|
+
# Streaming returns StreamResponse (traced)
|
|
142
|
+
stream = recommend_book.stream("fantasy")
|
|
143
|
+
for chunk in stream:
|
|
144
|
+
print(chunk)
|
|
145
|
+
|
|
146
|
+
# Use wrapped to get Trace[Response] with span info
|
|
147
|
+
trace = recommend_book.wrapped("fantasy")
|
|
148
|
+
print(trace.result.content)
|
|
149
|
+
print(trace.span_id)
|
|
150
|
+
|
|
151
|
+
# Use wrapped_stream to get Trace[StreamResponse]
|
|
152
|
+
trace = recommend_book.wrapped_stream("fantasy")
|
|
153
|
+
```
|
|
154
|
+
"""
|
|
155
|
+
|
|
156
|
+
call: TracedFunction[P, Response | Response[FormattableT]] = field(init=False)
|
|
157
|
+
"""TracedFunction wrapping the call method."""
|
|
158
|
+
|
|
159
|
+
stream: TracedFunction[P, StreamResponse | StreamResponse[FormattableT]] = field(
|
|
160
|
+
init=False
|
|
161
|
+
)
|
|
162
|
+
"""TracedFunction wrapping the stream method."""
|
|
163
|
+
|
|
164
|
+
def __post_init__(self) -> None:
|
|
165
|
+
"""Initialize TracedFunction wrappers for call and stream methods."""
|
|
166
|
+
super().__post_init__()
|
|
167
|
+
self.call = TracedFunction(
|
|
168
|
+
fn=self._call.call, tags=self.tags, metadata=self.metadata
|
|
169
|
+
)
|
|
170
|
+
self.stream = TracedFunction(
|
|
171
|
+
fn=self._call.stream, tags=self.tags, metadata=self.metadata
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
def __call__(
|
|
175
|
+
self, *args: P.args, **kwargs: P.kwargs
|
|
176
|
+
) -> Response | Response[FormattableT]:
|
|
177
|
+
"""Call the traced function and return Response directly."""
|
|
178
|
+
return self.call(*args, **kwargs)
|
|
179
|
+
|
|
180
|
+
def wrapped(
|
|
181
|
+
self, *args: P.args, **kwargs: P.kwargs
|
|
182
|
+
) -> Trace[Response | Response[FormattableT]]:
|
|
183
|
+
"""Call the traced function and return a wrapped Response."""
|
|
184
|
+
return self.call.wrapped(*args, **kwargs)
|
|
185
|
+
|
|
186
|
+
def wrapped_stream(
|
|
187
|
+
self, *args: P.args, **kwargs: P.kwargs
|
|
188
|
+
) -> Trace[StreamResponse | StreamResponse[FormattableT]]:
|
|
189
|
+
"""Stream the traced function and return a wrapped StreamResponse."""
|
|
190
|
+
return self.stream.wrapped(*args, **kwargs)
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
@dataclass(kw_only=True)
|
|
194
|
+
class TracedAsyncCall(_BaseTracedCall[AsyncCall[P, FormattableT]]):
|
|
195
|
+
"""Traced wrapper for traced asynchronous AsyncCall objects.
|
|
196
|
+
|
|
197
|
+
Example:
|
|
198
|
+
```python
|
|
199
|
+
@ops.trace
|
|
200
|
+
@llm.call("gpt-4o-mini")
|
|
201
|
+
async def recommend_book(genre: str):
|
|
202
|
+
return f"Recommend a {genre} book"
|
|
203
|
+
|
|
204
|
+
# Returns AsyncResponse directly (but execution is traced)
|
|
205
|
+
response = await recommend_book("fantasy")
|
|
206
|
+
print(response.content)
|
|
207
|
+
|
|
208
|
+
# Use wrapped to get AsyncTrace[AsyncResponse] with span info
|
|
209
|
+
trace = await recommend_book.wrapped("fantasy")
|
|
210
|
+
print(trace.result.content)
|
|
211
|
+
print(trace.span_id)
|
|
212
|
+
```
|
|
213
|
+
"""
|
|
214
|
+
|
|
215
|
+
call: AsyncTracedFunction[P, AsyncResponse | AsyncResponse[FormattableT]] = field(
|
|
216
|
+
init=False
|
|
217
|
+
)
|
|
218
|
+
"""AsyncTracedFunction wrapping the call method."""
|
|
219
|
+
|
|
220
|
+
stream: AsyncTracedFunction[
|
|
221
|
+
P, AsyncStreamResponse | AsyncStreamResponse[FormattableT]
|
|
222
|
+
] = field(init=False)
|
|
223
|
+
"""AsyncTracedFunction wrapping the stream method."""
|
|
224
|
+
|
|
225
|
+
def __post_init__(self) -> None:
|
|
226
|
+
"""Initialize AsyncTracedFunction wrappers for call and stream methods."""
|
|
227
|
+
super().__post_init__()
|
|
228
|
+
self.call = AsyncTracedFunction(
|
|
229
|
+
fn=self._call.call, tags=self.tags, metadata=self.metadata
|
|
230
|
+
)
|
|
231
|
+
self.stream = AsyncTracedFunction(
|
|
232
|
+
fn=self._call.stream, tags=self.tags, metadata=self.metadata
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
async def __call__(
|
|
236
|
+
self, *args: P.args, **kwargs: P.kwargs
|
|
237
|
+
) -> AsyncResponse | AsyncResponse[FormattableT]:
|
|
238
|
+
"""Call the traced function and return AsyncResponse directly."""
|
|
239
|
+
return await self.call(*args, **kwargs)
|
|
240
|
+
|
|
241
|
+
async def wrapped(
|
|
242
|
+
self, *args: P.args, **kwargs: P.kwargs
|
|
243
|
+
) -> AsyncTrace[AsyncResponse | AsyncResponse[FormattableT]]:
|
|
244
|
+
"""Call the traced function and return a wrapped Response."""
|
|
245
|
+
return await self.call.wrapped(*args, **kwargs)
|
|
246
|
+
|
|
247
|
+
async def wrapped_stream(
|
|
248
|
+
self, *args: P.args, **kwargs: P.kwargs
|
|
249
|
+
) -> AsyncTrace[AsyncStreamResponse | AsyncStreamResponse[FormattableT]]:
|
|
250
|
+
"""Stream the traced function and return a wrapped StreamResponse."""
|
|
251
|
+
return await self.stream.wrapped(*args, **kwargs)
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
@dataclass(kw_only=True)
|
|
255
|
+
class TracedContextCall(_BaseTracedCall[ContextCall[P, DepsT, FormattableT]]):
|
|
256
|
+
"""Traced wrapper for traced synchronous ContextCall objects.
|
|
257
|
+
|
|
258
|
+
Example:
|
|
259
|
+
```python
|
|
260
|
+
@ops.trace
|
|
261
|
+
@llm.call("gpt-4o-mini")
|
|
262
|
+
def recommend_book(ctx: llm.Context[str], genre: str):
|
|
263
|
+
return f"{ctx.deps} Recommend a {genre} book"
|
|
264
|
+
|
|
265
|
+
ctx = llm.Context(deps="As a librarian,")
|
|
266
|
+
|
|
267
|
+
# Returns ContextResponse directly (but execution is traced)
|
|
268
|
+
response = recommend_book(ctx, "fantasy")
|
|
269
|
+
print(response.content)
|
|
270
|
+
|
|
271
|
+
# Use wrapped to get Trace[ContextResponse] with span info
|
|
272
|
+
trace = recommend_book.wrapped(ctx, "fantasy")
|
|
273
|
+
print(trace.result.content)
|
|
274
|
+
```
|
|
275
|
+
"""
|
|
276
|
+
|
|
277
|
+
call: TracedContextFunction[
|
|
278
|
+
P, DepsT, ContextResponse[DepsT, None] | ContextResponse[DepsT, FormattableT]
|
|
279
|
+
] = field(init=False)
|
|
280
|
+
"""TracedContextFunction wrapping the call method."""
|
|
281
|
+
|
|
282
|
+
stream: TracedContextFunction[
|
|
283
|
+
P,
|
|
284
|
+
DepsT,
|
|
285
|
+
ContextStreamResponse[DepsT, None] | ContextStreamResponse[DepsT, FormattableT],
|
|
286
|
+
] = field(init=False)
|
|
287
|
+
"""TracedContextFunction wrapping the stream method."""
|
|
288
|
+
|
|
289
|
+
def __post_init__(self) -> None:
|
|
290
|
+
"""Initialize TracedContextFunction wrappers for call and stream methods."""
|
|
291
|
+
super().__post_init__()
|
|
292
|
+
self.call = TracedContextFunction(
|
|
293
|
+
fn=self._call.call, tags=self.tags, metadata=self.metadata
|
|
294
|
+
)
|
|
295
|
+
self.stream = TracedContextFunction(
|
|
296
|
+
fn=self._call.stream, tags=self.tags, metadata=self.metadata
|
|
297
|
+
)
|
|
298
|
+
|
|
299
|
+
def __call__(
|
|
300
|
+
self, ctx: Context[DepsT], *args: P.args, **kwargs: P.kwargs
|
|
301
|
+
) -> ContextResponse[DepsT, None] | ContextResponse[DepsT, FormattableT]:
|
|
302
|
+
"""Call the traced function and return ContextResponse directly."""
|
|
303
|
+
return self.call(ctx, *args, **kwargs)
|
|
304
|
+
|
|
305
|
+
def wrapped(
|
|
306
|
+
self, ctx: Context[DepsT], *args: P.args, **kwargs: P.kwargs
|
|
307
|
+
) -> Trace[ContextResponse[DepsT, None] | ContextResponse[DepsT, FormattableT]]:
|
|
308
|
+
"""Call the traced function and return a wrapped Response."""
|
|
309
|
+
return self.call.wrapped(ctx, *args, **kwargs)
|
|
310
|
+
|
|
311
|
+
def wrapped_stream(
|
|
312
|
+
self, ctx: Context[DepsT], *args: P.args, **kwargs: P.kwargs
|
|
313
|
+
) -> Trace[
|
|
314
|
+
ContextStreamResponse[DepsT, None] | ContextStreamResponse[DepsT, FormattableT]
|
|
315
|
+
]:
|
|
316
|
+
"""Stream the traced function and return a wrapped StreamResponse."""
|
|
317
|
+
return self.stream.wrapped(ctx, *args, **kwargs)
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
@dataclass(kw_only=True)
|
|
321
|
+
class TracedAsyncContextCall(_BaseTracedCall[AsyncContextCall[P, DepsT, FormattableT]]):
|
|
322
|
+
"""Traced wrapper for traced asynchronous AsyncContextCall objects.
|
|
323
|
+
|
|
324
|
+
Example:
|
|
325
|
+
```python
|
|
326
|
+
@ops.trace
|
|
327
|
+
@llm.call("gpt-4o-mini")
|
|
328
|
+
async def recommend_book(ctx: llm.Context[str], genre: str):
|
|
329
|
+
return f"{ctx.deps} Recommend a {genre} book"
|
|
330
|
+
|
|
331
|
+
ctx = llm.Context(deps="As a librarian,")
|
|
332
|
+
|
|
333
|
+
# Returns AsyncContextResponse directly (but execution is traced)
|
|
334
|
+
response = await recommend_book(ctx, "fantasy")
|
|
335
|
+
print(response.content)
|
|
336
|
+
|
|
337
|
+
# Use wrapped to get AsyncTrace[AsyncContextResponse] with span info
|
|
338
|
+
trace = await recommend_book.wrapped(ctx, "fantasy")
|
|
339
|
+
print(trace.result.content)
|
|
340
|
+
```
|
|
341
|
+
"""
|
|
342
|
+
|
|
343
|
+
call: AsyncTracedContextFunction[
|
|
344
|
+
P,
|
|
345
|
+
DepsT,
|
|
346
|
+
AsyncContextResponse[DepsT, None] | AsyncContextResponse[DepsT, FormattableT],
|
|
347
|
+
] = field(init=False)
|
|
348
|
+
"""AsyncTracedContextFunction wrapping the call method."""
|
|
349
|
+
|
|
350
|
+
stream: AsyncTracedContextFunction[
|
|
351
|
+
P,
|
|
352
|
+
DepsT,
|
|
353
|
+
AsyncContextStreamResponse[DepsT, None]
|
|
354
|
+
| AsyncContextStreamResponse[DepsT, FormattableT],
|
|
355
|
+
] = field(init=False)
|
|
356
|
+
"""AsyncTracedContextFunction wrapping the stream method."""
|
|
357
|
+
|
|
358
|
+
def __post_init__(self) -> None:
|
|
359
|
+
"""Initialize AsyncTracedContextFunction wrappers for call and stream methods."""
|
|
360
|
+
super().__post_init__()
|
|
361
|
+
self.call = AsyncTracedContextFunction(
|
|
362
|
+
fn=self._call.call, tags=self.tags, metadata=self.metadata
|
|
363
|
+
)
|
|
364
|
+
self.stream = AsyncTracedContextFunction(
|
|
365
|
+
fn=self._call.stream, tags=self.tags, metadata=self.metadata
|
|
366
|
+
)
|
|
367
|
+
|
|
368
|
+
async def __call__(
|
|
369
|
+
self, ctx: Context[DepsT], *args: P.args, **kwargs: P.kwargs
|
|
370
|
+
) -> AsyncContextResponse[DepsT, None] | AsyncContextResponse[DepsT, FormattableT]:
|
|
371
|
+
"""Call the traced function and return AsyncContextResponse directly."""
|
|
372
|
+
return await self.call(ctx, *args, **kwargs)
|
|
373
|
+
|
|
374
|
+
async def wrapped(
|
|
375
|
+
self, ctx: Context[DepsT], *args: P.args, **kwargs: P.kwargs
|
|
376
|
+
) -> AsyncTrace[
|
|
377
|
+
AsyncContextResponse[DepsT, None] | AsyncContextResponse[DepsT, FormattableT]
|
|
378
|
+
]:
|
|
379
|
+
"""Call the traced function and return a wrapped Response."""
|
|
380
|
+
return await self.call.wrapped(ctx, *args, **kwargs)
|
|
381
|
+
|
|
382
|
+
async def wrapped_stream(
|
|
383
|
+
self, ctx: Context[DepsT], *args: P.args, **kwargs: P.kwargs
|
|
384
|
+
) -> AsyncTrace[
|
|
385
|
+
AsyncContextStreamResponse[DepsT, None]
|
|
386
|
+
| AsyncContextStreamResponse[DepsT, FormattableT]
|
|
387
|
+
]:
|
|
388
|
+
"""Stream the traced function and return a wrapped StreamResponse."""
|
|
389
|
+
return await self.stream.wrapped(ctx, *args, **kwargs)
|