mirascope 2.0.0__py3-none-any.whl → 2.0.0a1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mirascope/__init__.py +2 -11
- mirascope/graphs/__init__.py +22 -0
- mirascope/graphs/finite_state_machine.py +625 -0
- mirascope/llm/__init__.py +15 -96
- mirascope/llm/agents/__init__.py +15 -0
- mirascope/llm/agents/agent.py +97 -0
- mirascope/llm/agents/agent_template.py +45 -0
- mirascope/llm/agents/decorator.py +176 -0
- mirascope/llm/calls/__init__.py +1 -2
- mirascope/llm/calls/base_call.py +33 -0
- mirascope/llm/calls/calls.py +58 -84
- mirascope/llm/calls/decorator.py +120 -140
- mirascope/llm/clients/__init__.py +34 -0
- mirascope/llm/clients/_missing_import_stubs.py +47 -0
- mirascope/llm/clients/anthropic/__init__.py +25 -0
- mirascope/llm/{providers/openai/completions → clients/anthropic}/_utils/__init__.py +0 -2
- mirascope/llm/{providers → clients}/anthropic/_utils/decode.py +22 -66
- mirascope/llm/clients/anthropic/_utils/encode.py +243 -0
- mirascope/llm/clients/anthropic/clients.py +819 -0
- mirascope/llm/clients/anthropic/model_ids.py +8 -0
- mirascope/llm/{providers → clients}/base/__init__.py +5 -4
- mirascope/llm/{providers → clients}/base/_utils.py +17 -78
- mirascope/llm/{providers/base/base_provider.py → clients/base/client.py} +145 -468
- mirascope/llm/{models → clients/base}/params.py +37 -16
- mirascope/llm/clients/google/__init__.py +20 -0
- mirascope/llm/{providers/openai/responses → clients/google}/_utils/__init__.py +0 -2
- mirascope/llm/{providers → clients}/google/_utils/decode.py +22 -98
- mirascope/llm/{providers → clients}/google/_utils/encode.py +46 -168
- mirascope/llm/clients/google/clients.py +853 -0
- mirascope/llm/clients/google/model_ids.py +15 -0
- mirascope/llm/clients/openai/__init__.py +25 -0
- mirascope/llm/clients/openai/completions/__init__.py +28 -0
- mirascope/llm/{providers/google → clients/openai/completions}/_utils/__init__.py +0 -4
- mirascope/llm/{providers → clients}/openai/completions/_utils/decode.py +9 -74
- mirascope/llm/{providers → clients}/openai/completions/_utils/encode.py +52 -70
- mirascope/llm/clients/openai/completions/_utils/model_features.py +81 -0
- mirascope/llm/clients/openai/completions/clients.py +833 -0
- mirascope/llm/clients/openai/completions/model_ids.py +8 -0
- mirascope/llm/clients/openai/responses/__init__.py +26 -0
- mirascope/llm/clients/openai/responses/_utils/__init__.py +13 -0
- mirascope/llm/{providers → clients}/openai/responses/_utils/decode.py +14 -80
- mirascope/llm/{providers → clients}/openai/responses/_utils/encode.py +41 -92
- mirascope/llm/clients/openai/responses/_utils/model_features.py +87 -0
- mirascope/llm/clients/openai/responses/clients.py +832 -0
- mirascope/llm/clients/openai/responses/model_ids.py +8 -0
- mirascope/llm/clients/openai/shared/__init__.py +7 -0
- mirascope/llm/clients/openai/shared/_utils.py +55 -0
- mirascope/llm/clients/providers.py +175 -0
- mirascope/llm/content/__init__.py +2 -3
- mirascope/llm/content/tool_call.py +0 -6
- mirascope/llm/content/tool_output.py +5 -22
- mirascope/llm/context/_utils.py +6 -19
- mirascope/llm/exceptions.py +43 -298
- mirascope/llm/formatting/__init__.py +2 -19
- mirascope/llm/formatting/_utils.py +74 -0
- mirascope/llm/formatting/format.py +30 -219
- mirascope/llm/formatting/from_call_args.py +2 -2
- mirascope/llm/formatting/partial.py +7 -80
- mirascope/llm/formatting/types.py +64 -21
- mirascope/llm/mcp/__init__.py +2 -2
- mirascope/llm/mcp/client.py +118 -0
- mirascope/llm/messages/__init__.py +0 -3
- mirascope/llm/messages/message.py +5 -13
- mirascope/llm/models/__init__.py +2 -7
- mirascope/llm/models/models.py +139 -315
- mirascope/llm/prompts/__init__.py +12 -13
- mirascope/llm/prompts/_utils.py +43 -14
- mirascope/llm/prompts/decorator.py +204 -144
- mirascope/llm/prompts/protocols.py +59 -25
- mirascope/llm/responses/__init__.py +1 -9
- mirascope/llm/responses/_utils.py +12 -102
- mirascope/llm/responses/base_response.py +6 -18
- mirascope/llm/responses/base_stream_response.py +50 -173
- mirascope/llm/responses/finish_reason.py +0 -1
- mirascope/llm/responses/response.py +13 -34
- mirascope/llm/responses/root_response.py +29 -100
- mirascope/llm/responses/stream_response.py +31 -40
- mirascope/llm/tools/__init__.py +2 -9
- mirascope/llm/tools/_utils.py +3 -12
- mirascope/llm/tools/decorator.py +16 -25
- mirascope/llm/tools/protocols.py +4 -4
- mirascope/llm/tools/tool_schema.py +19 -87
- mirascope/llm/tools/toolkit.py +27 -35
- mirascope/llm/tools/tools.py +41 -135
- {mirascope-2.0.0.dist-info → mirascope-2.0.0a1.dist-info}/METADATA +13 -90
- mirascope-2.0.0a1.dist-info/RECORD +102 -0
- {mirascope-2.0.0.dist-info → mirascope-2.0.0a1.dist-info}/WHEEL +1 -1
- {mirascope-2.0.0.dist-info → mirascope-2.0.0a1.dist-info}/licenses/LICENSE +1 -1
- mirascope/_stubs.py +0 -363
- mirascope/api/__init__.py +0 -14
- mirascope/api/_generated/README.md +0 -207
- mirascope/api/_generated/__init__.py +0 -440
- mirascope/api/_generated/annotations/__init__.py +0 -33
- mirascope/api/_generated/annotations/client.py +0 -506
- mirascope/api/_generated/annotations/raw_client.py +0 -1414
- mirascope/api/_generated/annotations/types/__init__.py +0 -31
- mirascope/api/_generated/annotations/types/annotations_create_request_label.py +0 -5
- mirascope/api/_generated/annotations/types/annotations_create_response.py +0 -48
- mirascope/api/_generated/annotations/types/annotations_create_response_label.py +0 -5
- mirascope/api/_generated/annotations/types/annotations_get_response.py +0 -48
- mirascope/api/_generated/annotations/types/annotations_get_response_label.py +0 -5
- mirascope/api/_generated/annotations/types/annotations_list_request_label.py +0 -5
- mirascope/api/_generated/annotations/types/annotations_list_response.py +0 -21
- mirascope/api/_generated/annotations/types/annotations_list_response_annotations_item.py +0 -50
- mirascope/api/_generated/annotations/types/annotations_list_response_annotations_item_label.py +0 -5
- mirascope/api/_generated/annotations/types/annotations_update_request_label.py +0 -5
- mirascope/api/_generated/annotations/types/annotations_update_response.py +0 -48
- mirascope/api/_generated/annotations/types/annotations_update_response_label.py +0 -5
- mirascope/api/_generated/api_keys/__init__.py +0 -17
- mirascope/api/_generated/api_keys/client.py +0 -530
- mirascope/api/_generated/api_keys/raw_client.py +0 -1236
- mirascope/api/_generated/api_keys/types/__init__.py +0 -15
- mirascope/api/_generated/api_keys/types/api_keys_create_response.py +0 -28
- mirascope/api/_generated/api_keys/types/api_keys_get_response.py +0 -27
- mirascope/api/_generated/api_keys/types/api_keys_list_all_for_org_response_item.py +0 -40
- mirascope/api/_generated/api_keys/types/api_keys_list_response_item.py +0 -27
- mirascope/api/_generated/client.py +0 -211
- mirascope/api/_generated/core/__init__.py +0 -52
- mirascope/api/_generated/core/api_error.py +0 -23
- mirascope/api/_generated/core/client_wrapper.py +0 -46
- mirascope/api/_generated/core/datetime_utils.py +0 -28
- mirascope/api/_generated/core/file.py +0 -67
- mirascope/api/_generated/core/force_multipart.py +0 -16
- mirascope/api/_generated/core/http_client.py +0 -543
- mirascope/api/_generated/core/http_response.py +0 -55
- mirascope/api/_generated/core/jsonable_encoder.py +0 -100
- mirascope/api/_generated/core/pydantic_utilities.py +0 -255
- mirascope/api/_generated/core/query_encoder.py +0 -58
- mirascope/api/_generated/core/remove_none_from_dict.py +0 -11
- mirascope/api/_generated/core/request_options.py +0 -35
- mirascope/api/_generated/core/serialization.py +0 -276
- mirascope/api/_generated/docs/__init__.py +0 -4
- mirascope/api/_generated/docs/client.py +0 -91
- mirascope/api/_generated/docs/raw_client.py +0 -178
- mirascope/api/_generated/environment.py +0 -9
- mirascope/api/_generated/environments/__init__.py +0 -23
- mirascope/api/_generated/environments/client.py +0 -649
- mirascope/api/_generated/environments/raw_client.py +0 -1567
- mirascope/api/_generated/environments/types/__init__.py +0 -25
- mirascope/api/_generated/environments/types/environments_create_response.py +0 -24
- mirascope/api/_generated/environments/types/environments_get_analytics_response.py +0 -60
- mirascope/api/_generated/environments/types/environments_get_analytics_response_top_functions_item.py +0 -24
- mirascope/api/_generated/environments/types/environments_get_analytics_response_top_models_item.py +0 -22
- mirascope/api/_generated/environments/types/environments_get_response.py +0 -24
- mirascope/api/_generated/environments/types/environments_list_response_item.py +0 -24
- mirascope/api/_generated/environments/types/environments_update_response.py +0 -24
- mirascope/api/_generated/errors/__init__.py +0 -25
- mirascope/api/_generated/errors/bad_request_error.py +0 -14
- mirascope/api/_generated/errors/conflict_error.py +0 -14
- mirascope/api/_generated/errors/forbidden_error.py +0 -11
- mirascope/api/_generated/errors/internal_server_error.py +0 -10
- mirascope/api/_generated/errors/not_found_error.py +0 -11
- mirascope/api/_generated/errors/payment_required_error.py +0 -15
- mirascope/api/_generated/errors/service_unavailable_error.py +0 -14
- mirascope/api/_generated/errors/too_many_requests_error.py +0 -15
- mirascope/api/_generated/errors/unauthorized_error.py +0 -11
- mirascope/api/_generated/functions/__init__.py +0 -39
- mirascope/api/_generated/functions/client.py +0 -647
- mirascope/api/_generated/functions/raw_client.py +0 -1890
- mirascope/api/_generated/functions/types/__init__.py +0 -53
- mirascope/api/_generated/functions/types/functions_create_request_dependencies_value.py +0 -20
- mirascope/api/_generated/functions/types/functions_create_response.py +0 -37
- mirascope/api/_generated/functions/types/functions_create_response_dependencies_value.py +0 -20
- mirascope/api/_generated/functions/types/functions_find_by_hash_response.py +0 -39
- mirascope/api/_generated/functions/types/functions_find_by_hash_response_dependencies_value.py +0 -20
- mirascope/api/_generated/functions/types/functions_get_by_env_response.py +0 -53
- mirascope/api/_generated/functions/types/functions_get_by_env_response_dependencies_value.py +0 -22
- mirascope/api/_generated/functions/types/functions_get_response.py +0 -37
- mirascope/api/_generated/functions/types/functions_get_response_dependencies_value.py +0 -20
- mirascope/api/_generated/functions/types/functions_list_by_env_response.py +0 -25
- mirascope/api/_generated/functions/types/functions_list_by_env_response_functions_item.py +0 -56
- mirascope/api/_generated/functions/types/functions_list_by_env_response_functions_item_dependencies_value.py +0 -22
- mirascope/api/_generated/functions/types/functions_list_response.py +0 -21
- mirascope/api/_generated/functions/types/functions_list_response_functions_item.py +0 -41
- mirascope/api/_generated/functions/types/functions_list_response_functions_item_dependencies_value.py +0 -20
- mirascope/api/_generated/health/__init__.py +0 -7
- mirascope/api/_generated/health/client.py +0 -92
- mirascope/api/_generated/health/raw_client.py +0 -175
- mirascope/api/_generated/health/types/__init__.py +0 -8
- mirascope/api/_generated/health/types/health_check_response.py +0 -22
- mirascope/api/_generated/health/types/health_check_response_status.py +0 -5
- mirascope/api/_generated/organization_invitations/__init__.py +0 -33
- mirascope/api/_generated/organization_invitations/client.py +0 -546
- mirascope/api/_generated/organization_invitations/raw_client.py +0 -1519
- mirascope/api/_generated/organization_invitations/types/__init__.py +0 -53
- mirascope/api/_generated/organization_invitations/types/organization_invitations_accept_response.py +0 -34
- mirascope/api/_generated/organization_invitations/types/organization_invitations_accept_response_role.py +0 -7
- mirascope/api/_generated/organization_invitations/types/organization_invitations_create_request_role.py +0 -7
- mirascope/api/_generated/organization_invitations/types/organization_invitations_create_response.py +0 -48
- mirascope/api/_generated/organization_invitations/types/organization_invitations_create_response_role.py +0 -7
- mirascope/api/_generated/organization_invitations/types/organization_invitations_create_response_status.py +0 -7
- mirascope/api/_generated/organization_invitations/types/organization_invitations_get_response.py +0 -48
- mirascope/api/_generated/organization_invitations/types/organization_invitations_get_response_role.py +0 -7
- mirascope/api/_generated/organization_invitations/types/organization_invitations_get_response_status.py +0 -7
- mirascope/api/_generated/organization_invitations/types/organization_invitations_list_response_item.py +0 -48
- mirascope/api/_generated/organization_invitations/types/organization_invitations_list_response_item_role.py +0 -7
- mirascope/api/_generated/organization_invitations/types/organization_invitations_list_response_item_status.py +0 -7
- mirascope/api/_generated/organization_memberships/__init__.py +0 -19
- mirascope/api/_generated/organization_memberships/client.py +0 -302
- mirascope/api/_generated/organization_memberships/raw_client.py +0 -736
- mirascope/api/_generated/organization_memberships/types/__init__.py +0 -27
- mirascope/api/_generated/organization_memberships/types/organization_memberships_list_response_item.py +0 -33
- mirascope/api/_generated/organization_memberships/types/organization_memberships_list_response_item_role.py +0 -7
- mirascope/api/_generated/organization_memberships/types/organization_memberships_update_request_role.py +0 -7
- mirascope/api/_generated/organization_memberships/types/organization_memberships_update_response.py +0 -31
- mirascope/api/_generated/organization_memberships/types/organization_memberships_update_response_role.py +0 -7
- mirascope/api/_generated/organizations/__init__.py +0 -51
- mirascope/api/_generated/organizations/client.py +0 -869
- mirascope/api/_generated/organizations/raw_client.py +0 -2593
- mirascope/api/_generated/organizations/types/__init__.py +0 -71
- mirascope/api/_generated/organizations/types/organizations_create_payment_intent_response.py +0 -24
- mirascope/api/_generated/organizations/types/organizations_create_response.py +0 -26
- mirascope/api/_generated/organizations/types/organizations_create_response_role.py +0 -5
- mirascope/api/_generated/organizations/types/organizations_get_response.py +0 -26
- mirascope/api/_generated/organizations/types/organizations_get_response_role.py +0 -5
- mirascope/api/_generated/organizations/types/organizations_list_response_item.py +0 -26
- mirascope/api/_generated/organizations/types/organizations_list_response_item_role.py +0 -5
- mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_request_target_plan.py +0 -7
- mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_response.py +0 -47
- mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_response_validation_errors_item.py +0 -33
- mirascope/api/_generated/organizations/types/organizations_preview_subscription_change_response_validation_errors_item_resource.py +0 -7
- mirascope/api/_generated/organizations/types/organizations_router_balance_response.py +0 -24
- mirascope/api/_generated/organizations/types/organizations_subscription_response.py +0 -53
- mirascope/api/_generated/organizations/types/organizations_subscription_response_current_plan.py +0 -7
- mirascope/api/_generated/organizations/types/organizations_subscription_response_payment_method.py +0 -26
- mirascope/api/_generated/organizations/types/organizations_subscription_response_scheduled_change.py +0 -34
- mirascope/api/_generated/organizations/types/organizations_subscription_response_scheduled_change_target_plan.py +0 -7
- mirascope/api/_generated/organizations/types/organizations_update_response.py +0 -26
- mirascope/api/_generated/organizations/types/organizations_update_response_role.py +0 -5
- mirascope/api/_generated/organizations/types/organizations_update_subscription_request_target_plan.py +0 -7
- mirascope/api/_generated/organizations/types/organizations_update_subscription_response.py +0 -35
- mirascope/api/_generated/project_memberships/__init__.py +0 -25
- mirascope/api/_generated/project_memberships/client.py +0 -437
- mirascope/api/_generated/project_memberships/raw_client.py +0 -1039
- mirascope/api/_generated/project_memberships/types/__init__.py +0 -29
- mirascope/api/_generated/project_memberships/types/project_memberships_create_request_role.py +0 -7
- mirascope/api/_generated/project_memberships/types/project_memberships_create_response.py +0 -35
- mirascope/api/_generated/project_memberships/types/project_memberships_create_response_role.py +0 -7
- mirascope/api/_generated/project_memberships/types/project_memberships_list_response_item.py +0 -33
- mirascope/api/_generated/project_memberships/types/project_memberships_list_response_item_role.py +0 -7
- mirascope/api/_generated/project_memberships/types/project_memberships_update_request_role.py +0 -7
- mirascope/api/_generated/project_memberships/types/project_memberships_update_response.py +0 -35
- mirascope/api/_generated/project_memberships/types/project_memberships_update_response_role.py +0 -7
- mirascope/api/_generated/projects/__init__.py +0 -7
- mirascope/api/_generated/projects/client.py +0 -428
- mirascope/api/_generated/projects/raw_client.py +0 -1302
- mirascope/api/_generated/projects/types/__init__.py +0 -10
- mirascope/api/_generated/projects/types/projects_create_response.py +0 -25
- mirascope/api/_generated/projects/types/projects_get_response.py +0 -25
- mirascope/api/_generated/projects/types/projects_list_response_item.py +0 -25
- mirascope/api/_generated/projects/types/projects_update_response.py +0 -25
- mirascope/api/_generated/reference.md +0 -4915
- mirascope/api/_generated/tags/__init__.py +0 -19
- mirascope/api/_generated/tags/client.py +0 -504
- mirascope/api/_generated/tags/raw_client.py +0 -1288
- mirascope/api/_generated/tags/types/__init__.py +0 -17
- mirascope/api/_generated/tags/types/tags_create_response.py +0 -41
- mirascope/api/_generated/tags/types/tags_get_response.py +0 -41
- mirascope/api/_generated/tags/types/tags_list_response.py +0 -23
- mirascope/api/_generated/tags/types/tags_list_response_tags_item.py +0 -41
- mirascope/api/_generated/tags/types/tags_update_response.py +0 -41
- mirascope/api/_generated/token_cost/__init__.py +0 -7
- mirascope/api/_generated/token_cost/client.py +0 -160
- mirascope/api/_generated/token_cost/raw_client.py +0 -264
- mirascope/api/_generated/token_cost/types/__init__.py +0 -8
- mirascope/api/_generated/token_cost/types/token_cost_calculate_request_usage.py +0 -54
- mirascope/api/_generated/token_cost/types/token_cost_calculate_response.py +0 -52
- mirascope/api/_generated/traces/__init__.py +0 -97
- mirascope/api/_generated/traces/client.py +0 -1103
- mirascope/api/_generated/traces/raw_client.py +0 -2322
- mirascope/api/_generated/traces/types/__init__.py +0 -155
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item.py +0 -29
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource.py +0 -27
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item.py +0 -23
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value.py +0 -38
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_array_value.py +0 -19
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_kvlist_value.py +0 -22
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_resource_attributes_item_value_kvlist_value_values_item.py +0 -20
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item.py +0 -29
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope.py +0 -31
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item.py +0 -23
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value.py +0 -38
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_array_value.py +0 -19
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_kvlist_value.py +0 -22
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_scope_attributes_item_value_kvlist_value_values_item.py +0 -22
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item.py +0 -48
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item.py +0 -23
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value.py +0 -38
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_array_value.py +0 -19
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_kvlist_value.py +0 -24
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_attributes_item_value_kvlist_value_values_item.py +0 -22
- mirascope/api/_generated/traces/types/traces_create_request_resource_spans_item_scope_spans_item_spans_item_status.py +0 -20
- mirascope/api/_generated/traces/types/traces_create_response.py +0 -24
- mirascope/api/_generated/traces/types/traces_create_response_partial_success.py +0 -22
- mirascope/api/_generated/traces/types/traces_get_analytics_summary_response.py +0 -60
- mirascope/api/_generated/traces/types/traces_get_analytics_summary_response_top_functions_item.py +0 -24
- mirascope/api/_generated/traces/types/traces_get_analytics_summary_response_top_models_item.py +0 -22
- mirascope/api/_generated/traces/types/traces_get_trace_detail_by_env_response.py +0 -33
- mirascope/api/_generated/traces/types/traces_get_trace_detail_by_env_response_spans_item.py +0 -88
- mirascope/api/_generated/traces/types/traces_get_trace_detail_response.py +0 -33
- mirascope/api/_generated/traces/types/traces_get_trace_detail_response_spans_item.py +0 -88
- mirascope/api/_generated/traces/types/traces_list_by_function_hash_response.py +0 -25
- mirascope/api/_generated/traces/types/traces_list_by_function_hash_response_traces_item.py +0 -44
- mirascope/api/_generated/traces/types/traces_search_by_env_request_attribute_filters_item.py +0 -26
- mirascope/api/_generated/traces/types/traces_search_by_env_request_attribute_filters_item_operator.py +0 -7
- mirascope/api/_generated/traces/types/traces_search_by_env_request_sort_by.py +0 -7
- mirascope/api/_generated/traces/types/traces_search_by_env_request_sort_order.py +0 -7
- mirascope/api/_generated/traces/types/traces_search_by_env_response.py +0 -26
- mirascope/api/_generated/traces/types/traces_search_by_env_response_spans_item.py +0 -50
- mirascope/api/_generated/traces/types/traces_search_request_attribute_filters_item.py +0 -26
- mirascope/api/_generated/traces/types/traces_search_request_attribute_filters_item_operator.py +0 -7
- mirascope/api/_generated/traces/types/traces_search_request_sort_by.py +0 -7
- mirascope/api/_generated/traces/types/traces_search_request_sort_order.py +0 -5
- mirascope/api/_generated/traces/types/traces_search_response.py +0 -26
- mirascope/api/_generated/traces/types/traces_search_response_spans_item.py +0 -50
- mirascope/api/_generated/types/__init__.py +0 -85
- mirascope/api/_generated/types/already_exists_error.py +0 -22
- mirascope/api/_generated/types/already_exists_error_tag.py +0 -5
- mirascope/api/_generated/types/bad_request_error_body.py +0 -50
- mirascope/api/_generated/types/click_house_error.py +0 -22
- mirascope/api/_generated/types/database_error.py +0 -22
- mirascope/api/_generated/types/database_error_tag.py +0 -5
- mirascope/api/_generated/types/date.py +0 -3
- mirascope/api/_generated/types/http_api_decode_error.py +0 -27
- mirascope/api/_generated/types/http_api_decode_error_tag.py +0 -5
- mirascope/api/_generated/types/immutable_resource_error.py +0 -22
- mirascope/api/_generated/types/internal_server_error_body.py +0 -49
- mirascope/api/_generated/types/issue.py +0 -38
- mirascope/api/_generated/types/issue_tag.py +0 -10
- mirascope/api/_generated/types/not_found_error_body.py +0 -22
- mirascope/api/_generated/types/not_found_error_tag.py +0 -5
- mirascope/api/_generated/types/number_from_string.py +0 -3
- mirascope/api/_generated/types/permission_denied_error.py +0 -22
- mirascope/api/_generated/types/permission_denied_error_tag.py +0 -5
- mirascope/api/_generated/types/plan_limit_exceeded_error.py +0 -32
- mirascope/api/_generated/types/plan_limit_exceeded_error_tag.py +0 -7
- mirascope/api/_generated/types/pricing_unavailable_error.py +0 -23
- mirascope/api/_generated/types/property_key.py +0 -7
- mirascope/api/_generated/types/property_key_key.py +0 -25
- mirascope/api/_generated/types/property_key_key_tag.py +0 -5
- mirascope/api/_generated/types/rate_limit_error.py +0 -31
- mirascope/api/_generated/types/rate_limit_error_tag.py +0 -5
- mirascope/api/_generated/types/service_unavailable_error_body.py +0 -24
- mirascope/api/_generated/types/service_unavailable_error_tag.py +0 -7
- mirascope/api/_generated/types/stripe_error.py +0 -20
- mirascope/api/_generated/types/subscription_past_due_error.py +0 -31
- mirascope/api/_generated/types/subscription_past_due_error_tag.py +0 -7
- mirascope/api/_generated/types/unauthorized_error_body.py +0 -21
- mirascope/api/_generated/types/unauthorized_error_tag.py +0 -5
- mirascope/api/client.py +0 -255
- mirascope/api/settings.py +0 -99
- mirascope/llm/formatting/output_parser.py +0 -178
- mirascope/llm/formatting/primitives.py +0 -192
- mirascope/llm/mcp/mcp_client.py +0 -130
- mirascope/llm/messages/_utils.py +0 -34
- mirascope/llm/models/thinking_config.py +0 -61
- mirascope/llm/prompts/prompts.py +0 -487
- mirascope/llm/providers/__init__.py +0 -62
- mirascope/llm/providers/anthropic/__init__.py +0 -11
- mirascope/llm/providers/anthropic/_utils/__init__.py +0 -27
- mirascope/llm/providers/anthropic/_utils/beta_decode.py +0 -282
- mirascope/llm/providers/anthropic/_utils/beta_encode.py +0 -266
- mirascope/llm/providers/anthropic/_utils/encode.py +0 -418
- mirascope/llm/providers/anthropic/_utils/errors.py +0 -46
- mirascope/llm/providers/anthropic/beta_provider.py +0 -374
- mirascope/llm/providers/anthropic/model_id.py +0 -23
- mirascope/llm/providers/anthropic/model_info.py +0 -87
- mirascope/llm/providers/anthropic/provider.py +0 -479
- mirascope/llm/providers/google/__init__.py +0 -6
- mirascope/llm/providers/google/_utils/errors.py +0 -50
- mirascope/llm/providers/google/model_id.py +0 -22
- mirascope/llm/providers/google/model_info.py +0 -63
- mirascope/llm/providers/google/provider.py +0 -492
- mirascope/llm/providers/mirascope/__init__.py +0 -5
- mirascope/llm/providers/mirascope/_utils.py +0 -73
- mirascope/llm/providers/mirascope/provider.py +0 -349
- mirascope/llm/providers/mlx/__init__.py +0 -9
- mirascope/llm/providers/mlx/_utils.py +0 -141
- mirascope/llm/providers/mlx/encoding/__init__.py +0 -8
- mirascope/llm/providers/mlx/encoding/base.py +0 -72
- mirascope/llm/providers/mlx/encoding/transformers.py +0 -150
- mirascope/llm/providers/mlx/mlx.py +0 -254
- mirascope/llm/providers/mlx/model_id.py +0 -17
- mirascope/llm/providers/mlx/provider.py +0 -452
- mirascope/llm/providers/model_id.py +0 -16
- mirascope/llm/providers/ollama/__init__.py +0 -7
- mirascope/llm/providers/ollama/provider.py +0 -71
- mirascope/llm/providers/openai/__init__.py +0 -15
- mirascope/llm/providers/openai/_utils/__init__.py +0 -5
- mirascope/llm/providers/openai/_utils/errors.py +0 -46
- mirascope/llm/providers/openai/completions/__init__.py +0 -7
- mirascope/llm/providers/openai/completions/base_provider.py +0 -542
- mirascope/llm/providers/openai/completions/provider.py +0 -22
- mirascope/llm/providers/openai/model_id.py +0 -31
- mirascope/llm/providers/openai/model_info.py +0 -303
- mirascope/llm/providers/openai/provider.py +0 -441
- mirascope/llm/providers/openai/responses/__init__.py +0 -5
- mirascope/llm/providers/openai/responses/provider.py +0 -513
- mirascope/llm/providers/provider_id.py +0 -24
- mirascope/llm/providers/provider_registry.py +0 -299
- mirascope/llm/providers/together/__init__.py +0 -7
- mirascope/llm/providers/together/provider.py +0 -40
- mirascope/llm/responses/usage.py +0 -95
- mirascope/ops/__init__.py +0 -111
- mirascope/ops/_internal/__init__.py +0 -5
- mirascope/ops/_internal/closure.py +0 -1169
- mirascope/ops/_internal/configuration.py +0 -177
- mirascope/ops/_internal/context.py +0 -76
- mirascope/ops/_internal/exporters/__init__.py +0 -26
- mirascope/ops/_internal/exporters/exporters.py +0 -395
- mirascope/ops/_internal/exporters/processors.py +0 -104
- mirascope/ops/_internal/exporters/types.py +0 -165
- mirascope/ops/_internal/exporters/utils.py +0 -29
- mirascope/ops/_internal/instrumentation/__init__.py +0 -8
- mirascope/ops/_internal/instrumentation/llm/__init__.py +0 -8
- mirascope/ops/_internal/instrumentation/llm/common.py +0 -530
- mirascope/ops/_internal/instrumentation/llm/cost.py +0 -190
- mirascope/ops/_internal/instrumentation/llm/encode.py +0 -238
- mirascope/ops/_internal/instrumentation/llm/gen_ai_types/__init__.py +0 -38
- mirascope/ops/_internal/instrumentation/llm/gen_ai_types/gen_ai_input_messages.py +0 -31
- mirascope/ops/_internal/instrumentation/llm/gen_ai_types/gen_ai_output_messages.py +0 -38
- mirascope/ops/_internal/instrumentation/llm/gen_ai_types/gen_ai_system_instructions.py +0 -18
- mirascope/ops/_internal/instrumentation/llm/gen_ai_types/shared.py +0 -100
- mirascope/ops/_internal/instrumentation/llm/llm.py +0 -161
- mirascope/ops/_internal/instrumentation/llm/model.py +0 -1798
- mirascope/ops/_internal/instrumentation/llm/response.py +0 -521
- mirascope/ops/_internal/instrumentation/llm/serialize.py +0 -300
- mirascope/ops/_internal/propagation.py +0 -198
- mirascope/ops/_internal/protocols.py +0 -133
- mirascope/ops/_internal/session.py +0 -139
- mirascope/ops/_internal/spans.py +0 -232
- mirascope/ops/_internal/traced_calls.py +0 -375
- mirascope/ops/_internal/traced_functions.py +0 -523
- mirascope/ops/_internal/tracing.py +0 -353
- mirascope/ops/_internal/types.py +0 -13
- mirascope/ops/_internal/utils.py +0 -123
- mirascope/ops/_internal/versioned_calls.py +0 -512
- mirascope/ops/_internal/versioned_functions.py +0 -357
- mirascope/ops/_internal/versioning.py +0 -303
- mirascope/ops/exceptions.py +0 -21
- mirascope-2.0.0.dist-info/RECORD +0 -423
- /mirascope/llm/{providers → clients}/base/kwargs.py +0 -0
- /mirascope/llm/{providers → clients}/google/message.py +0 -0
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
"""Cost calculation utilities for LLM instrumentation."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
import logging
|
|
6
|
-
import re
|
|
7
|
-
from typing import Any
|
|
8
|
-
|
|
9
|
-
from .....api._generated.token_cost import (
|
|
10
|
-
TokenCostCalculateRequestUsage,
|
|
11
|
-
TokenCostCalculateResponse,
|
|
12
|
-
)
|
|
13
|
-
from .....api.client import get_async_client, get_sync_client
|
|
14
|
-
from .....llm.providers import get_provider_for_model
|
|
15
|
-
from .....llm.providers.mirascope import MirascopeProvider
|
|
16
|
-
from .....llm.responses.usage import Usage
|
|
17
|
-
|
|
18
|
-
logger = logging.getLogger(__name__)
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
def _is_via_router(model_id: str) -> bool:
|
|
22
|
-
"""Check if the model_id routes through MirascopeProvider (Mirascope Router).
|
|
23
|
-
|
|
24
|
-
Args:
|
|
25
|
-
model_id: The full model ID (e.g., "openai/gpt-4o").
|
|
26
|
-
|
|
27
|
-
Returns:
|
|
28
|
-
True if the registered provider for this model is MirascopeProvider.
|
|
29
|
-
"""
|
|
30
|
-
try:
|
|
31
|
-
provider = get_provider_for_model(model_id)
|
|
32
|
-
return isinstance(provider, MirascopeProvider)
|
|
33
|
-
except Exception:
|
|
34
|
-
return False
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def _normalize_model_id(model_id: str) -> str:
|
|
38
|
-
"""Normalize model_id by stripping provider prefix and any :suffix.
|
|
39
|
-
|
|
40
|
-
Args:
|
|
41
|
-
model_id: The full model ID (e.g., "openai/gpt-4o:responses").
|
|
42
|
-
|
|
43
|
-
Returns:
|
|
44
|
-
The base model name (e.g., "gpt-4o").
|
|
45
|
-
"""
|
|
46
|
-
# Strip provider prefix (e.g., "openai/gpt-4o" -> "gpt-4o")
|
|
47
|
-
if "/" in model_id:
|
|
48
|
-
model_id = model_id.split("/", 1)[1]
|
|
49
|
-
# Strip any :suffix (e.g., ":responses", ":completions")
|
|
50
|
-
return re.sub(r":.*$", "", model_id)
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
def extract_cache_write_breakdown(usage: Usage) -> dict[str, float] | None:
|
|
54
|
-
"""Extract cache write breakdown from Anthropic's raw usage data.
|
|
55
|
-
|
|
56
|
-
Returns a dict like {"ephemeral5m": 100, "ephemeral1h": 50} if available,
|
|
57
|
-
or None if the breakdown isn't available.
|
|
58
|
-
"""
|
|
59
|
-
raw = usage.raw
|
|
60
|
-
if raw is None:
|
|
61
|
-
return None
|
|
62
|
-
|
|
63
|
-
# Check for Anthropic's cache_creation breakdown
|
|
64
|
-
cache_creation = getattr(raw, "cache_creation", None)
|
|
65
|
-
if cache_creation is None:
|
|
66
|
-
return None
|
|
67
|
-
|
|
68
|
-
ephemeral_5m = getattr(cache_creation, "ephemeral_5m_input_tokens", None)
|
|
69
|
-
ephemeral_1h = getattr(cache_creation, "ephemeral_1h_input_tokens", None)
|
|
70
|
-
|
|
71
|
-
if ephemeral_5m is None and ephemeral_1h is None:
|
|
72
|
-
return None
|
|
73
|
-
|
|
74
|
-
breakdown: dict[str, float] = {}
|
|
75
|
-
if ephemeral_5m is not None and ephemeral_5m > 0:
|
|
76
|
-
breakdown["ephemeral5m"] = float(ephemeral_5m)
|
|
77
|
-
if ephemeral_1h is not None and ephemeral_1h > 0:
|
|
78
|
-
breakdown["ephemeral1h"] = float(ephemeral_1h)
|
|
79
|
-
|
|
80
|
-
return breakdown if breakdown else None
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
def calculate_cost_sync(
|
|
84
|
-
provider_id: str,
|
|
85
|
-
model_id: str,
|
|
86
|
-
usage: Usage,
|
|
87
|
-
) -> TokenCostCalculateResponse | None:
|
|
88
|
-
"""Calculate cost synchronously. Returns None on any failure."""
|
|
89
|
-
normalized_model = _normalize_model_id(model_id)
|
|
90
|
-
via_router = _is_via_router(model_id)
|
|
91
|
-
logger.debug(
|
|
92
|
-
"Calculating cost for provider=%s, model=%s (normalized=%s), "
|
|
93
|
-
"via_router=%s, usage=(input=%s, output=%s, cache_read=%s, cache_write=%s)",
|
|
94
|
-
provider_id,
|
|
95
|
-
model_id,
|
|
96
|
-
normalized_model,
|
|
97
|
-
via_router,
|
|
98
|
-
usage.input_tokens,
|
|
99
|
-
usage.output_tokens,
|
|
100
|
-
usage.cache_read_tokens,
|
|
101
|
-
usage.cache_write_tokens,
|
|
102
|
-
)
|
|
103
|
-
try:
|
|
104
|
-
client = get_sync_client()
|
|
105
|
-
logger.debug("Got sync client, making API request")
|
|
106
|
-
cache_breakdown = extract_cache_write_breakdown(usage)
|
|
107
|
-
if cache_breakdown:
|
|
108
|
-
logger.debug("Cache write breakdown: %s", cache_breakdown)
|
|
109
|
-
# Build usage kwargs, only including optional fields if they have values
|
|
110
|
-
usage_kwargs: dict[str, Any] = {
|
|
111
|
-
"input_tokens": usage.input_tokens,
|
|
112
|
-
"output_tokens": usage.output_tokens,
|
|
113
|
-
}
|
|
114
|
-
if usage.cache_read_tokens:
|
|
115
|
-
usage_kwargs["cache_read_tokens"] = usage.cache_read_tokens
|
|
116
|
-
if usage.cache_write_tokens:
|
|
117
|
-
usage_kwargs["cache_write_tokens"] = usage.cache_write_tokens
|
|
118
|
-
if cache_breakdown:
|
|
119
|
-
usage_kwargs["cache_write_breakdown"] = cache_breakdown
|
|
120
|
-
result = client.token_cost.calculate(
|
|
121
|
-
provider=provider_id,
|
|
122
|
-
model=normalized_model,
|
|
123
|
-
usage=TokenCostCalculateRequestUsage(**usage_kwargs),
|
|
124
|
-
via_router=via_router,
|
|
125
|
-
)
|
|
126
|
-
logger.debug(
|
|
127
|
-
"Cost calculation result: input=%s, output=%s, total=%s centicents",
|
|
128
|
-
result.input_cost_centicents,
|
|
129
|
-
result.output_cost_centicents,
|
|
130
|
-
result.total_cost_centicents,
|
|
131
|
-
)
|
|
132
|
-
return result
|
|
133
|
-
except Exception:
|
|
134
|
-
logger.debug("Failed to calculate cost", exc_info=True)
|
|
135
|
-
return None
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
async def calculate_cost_async(
|
|
139
|
-
provider_id: str,
|
|
140
|
-
model_id: str,
|
|
141
|
-
usage: Usage,
|
|
142
|
-
) -> TokenCostCalculateResponse | None:
|
|
143
|
-
"""Calculate cost asynchronously. Returns None on any failure."""
|
|
144
|
-
normalized_model = _normalize_model_id(model_id)
|
|
145
|
-
via_router = _is_via_router(model_id)
|
|
146
|
-
logger.debug(
|
|
147
|
-
"Calculating cost (async) for provider=%s, model=%s (normalized=%s), "
|
|
148
|
-
"via_router=%s, usage=(input=%s, output=%s, cache_read=%s, cache_write=%s)",
|
|
149
|
-
provider_id,
|
|
150
|
-
model_id,
|
|
151
|
-
normalized_model,
|
|
152
|
-
via_router,
|
|
153
|
-
usage.input_tokens,
|
|
154
|
-
usage.output_tokens,
|
|
155
|
-
usage.cache_read_tokens,
|
|
156
|
-
usage.cache_write_tokens,
|
|
157
|
-
)
|
|
158
|
-
try:
|
|
159
|
-
client = get_async_client()
|
|
160
|
-
logger.debug("Got async client, making API request")
|
|
161
|
-
cache_breakdown = extract_cache_write_breakdown(usage)
|
|
162
|
-
if cache_breakdown:
|
|
163
|
-
logger.debug("Cache write breakdown: %s", cache_breakdown)
|
|
164
|
-
# Build usage kwargs, only including optional fields if they have values
|
|
165
|
-
usage_kwargs: dict[str, Any] = {
|
|
166
|
-
"input_tokens": usage.input_tokens,
|
|
167
|
-
"output_tokens": usage.output_tokens,
|
|
168
|
-
}
|
|
169
|
-
if usage.cache_read_tokens:
|
|
170
|
-
usage_kwargs["cache_read_tokens"] = usage.cache_read_tokens
|
|
171
|
-
if usage.cache_write_tokens:
|
|
172
|
-
usage_kwargs["cache_write_tokens"] = usage.cache_write_tokens
|
|
173
|
-
if cache_breakdown:
|
|
174
|
-
usage_kwargs["cache_write_breakdown"] = cache_breakdown
|
|
175
|
-
result = await client.token_cost.calculate(
|
|
176
|
-
provider=provider_id,
|
|
177
|
-
model=normalized_model,
|
|
178
|
-
usage=TokenCostCalculateRequestUsage(**usage_kwargs),
|
|
179
|
-
via_router=via_router,
|
|
180
|
-
)
|
|
181
|
-
logger.debug(
|
|
182
|
-
"Cost calculation result (async): input=%s, output=%s, total=%s centicents",
|
|
183
|
-
result.input_cost_centicents,
|
|
184
|
-
result.output_cost_centicents,
|
|
185
|
-
result.total_cost_centicents,
|
|
186
|
-
)
|
|
187
|
-
return result
|
|
188
|
-
except Exception:
|
|
189
|
-
logger.debug("Failed to calculate cost (async)", exc_info=True)
|
|
190
|
-
return None
|
|
@@ -1,238 +0,0 @@
|
|
|
1
|
-
"""Utilities for encoding Mirascope messages into GenAI semconv payloads."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
import json
|
|
6
|
-
from collections.abc import Sequence
|
|
7
|
-
from dataclasses import dataclass
|
|
8
|
-
from typing import TYPE_CHECKING
|
|
9
|
-
|
|
10
|
-
from . import gen_ai_types
|
|
11
|
-
|
|
12
|
-
if TYPE_CHECKING:
|
|
13
|
-
from typing import TypeAlias
|
|
14
|
-
|
|
15
|
-
MessagePart: TypeAlias = (
|
|
16
|
-
gen_ai_types.TextPart
|
|
17
|
-
| gen_ai_types.ToolCallRequestPart
|
|
18
|
-
| gen_ai_types.ToolCallResponsePart
|
|
19
|
-
| gen_ai_types.BlobPart
|
|
20
|
-
| gen_ai_types.FilePart
|
|
21
|
-
| gen_ai_types.UriPart
|
|
22
|
-
| gen_ai_types.ReasoningPart
|
|
23
|
-
| gen_ai_types.GenericPart
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
from .....llm.content import (
|
|
28
|
-
Audio,
|
|
29
|
-
Base64ImageSource,
|
|
30
|
-
Document,
|
|
31
|
-
Image,
|
|
32
|
-
Text,
|
|
33
|
-
Thought,
|
|
34
|
-
ToolCall,
|
|
35
|
-
ToolOutput,
|
|
36
|
-
)
|
|
37
|
-
from .....llm.formatting import FormattableT
|
|
38
|
-
from .....llm.messages import AssistantMessage, Message, SystemMessage
|
|
39
|
-
from .....llm.responses.finish_reason import FinishReason
|
|
40
|
-
from .....llm.responses.root_response import RootResponse
|
|
41
|
-
from .....llm.tools import ToolkitT
|
|
42
|
-
from .....llm.types import Jsonable
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
@dataclass(frozen=True, slots=True)
|
|
46
|
-
class OTelMessageSnapshot:
|
|
47
|
-
"""Structured view of system, input, and output messages."""
|
|
48
|
-
|
|
49
|
-
system_instructions: gen_ai_types.SystemInstructions
|
|
50
|
-
"""Instructions to be executed prior to the conversation."""
|
|
51
|
-
|
|
52
|
-
inputs: gen_ai_types.InputMessages
|
|
53
|
-
"""Messages to be sent to the model."""
|
|
54
|
-
|
|
55
|
-
outputs: gen_ai_types.OutputMessages
|
|
56
|
-
"""Messages received from the model."""
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
def _serialize_message_parts(
|
|
60
|
-
parts: Sequence[
|
|
61
|
-
Text | ToolCall | ToolOutput[Jsonable] | Thought | Image | Audio | Document
|
|
62
|
-
],
|
|
63
|
-
) -> list[MessagePart]:
|
|
64
|
-
"""Serialize message content parts into GenAI-compliant dictionaries.
|
|
65
|
-
|
|
66
|
-
Handles Text, ToolCall, ToolOutput, Thought, Image, Audio, Document,
|
|
67
|
-
and str types.
|
|
68
|
-
"""
|
|
69
|
-
serialized: list[MessagePart] = []
|
|
70
|
-
for part in parts:
|
|
71
|
-
match part:
|
|
72
|
-
case Text():
|
|
73
|
-
text_part: gen_ai_types.TextPart = {
|
|
74
|
-
"type": "text",
|
|
75
|
-
"content": part.text,
|
|
76
|
-
}
|
|
77
|
-
serialized.append(text_part)
|
|
78
|
-
case ToolCall():
|
|
79
|
-
try:
|
|
80
|
-
arguments = json.loads(part.args)
|
|
81
|
-
except json.JSONDecodeError: # pragma: no cover
|
|
82
|
-
arguments = ""
|
|
83
|
-
tool_call_part: gen_ai_types.ToolCallRequestPart = {
|
|
84
|
-
"type": "tool_call",
|
|
85
|
-
"id": part.id,
|
|
86
|
-
"name": part.name,
|
|
87
|
-
"arguments": arguments,
|
|
88
|
-
}
|
|
89
|
-
serialized.append(tool_call_part)
|
|
90
|
-
case ToolOutput():
|
|
91
|
-
tool_output_part: gen_ai_types.ToolCallResponsePart = {
|
|
92
|
-
"type": "tool_call_response",
|
|
93
|
-
"id": part.id,
|
|
94
|
-
"response": part.result,
|
|
95
|
-
}
|
|
96
|
-
serialized.append(tool_output_part)
|
|
97
|
-
case Thought():
|
|
98
|
-
serialized.append(
|
|
99
|
-
gen_ai_types.ReasoningPart(type="reasoning", content=part.thought)
|
|
100
|
-
)
|
|
101
|
-
case Image():
|
|
102
|
-
if isinstance(part.source, Base64ImageSource):
|
|
103
|
-
image = gen_ai_types.BlobPart(
|
|
104
|
-
type="blob",
|
|
105
|
-
modality="image",
|
|
106
|
-
mime_type=part.source.mime_type,
|
|
107
|
-
content=part.source.data,
|
|
108
|
-
)
|
|
109
|
-
else:
|
|
110
|
-
image = gen_ai_types.UriPart(
|
|
111
|
-
type="uri", modality="image", uri=part.source.url
|
|
112
|
-
)
|
|
113
|
-
serialized.append(image)
|
|
114
|
-
case Audio():
|
|
115
|
-
serialized.append(
|
|
116
|
-
gen_ai_types.BlobPart(
|
|
117
|
-
type="blob",
|
|
118
|
-
modality="audio",
|
|
119
|
-
mime_type=part.source.mime_type,
|
|
120
|
-
content=part.source.data,
|
|
121
|
-
)
|
|
122
|
-
)
|
|
123
|
-
case Document(): # pragma: no cover
|
|
124
|
-
raise NotImplementedError(
|
|
125
|
-
"Document serialization is not yet supported by any provider. "
|
|
126
|
-
"This will be implemented when provider support is added."
|
|
127
|
-
)
|
|
128
|
-
return serialized
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
def _serialize_message(message: Message) -> gen_ai_types.ChatMessage:
|
|
132
|
-
"""Serialize a Mirascope message into a GenAI ChatMessage."""
|
|
133
|
-
content_parts = _serialize_message_parts(
|
|
134
|
-
message.content if not isinstance(message, SystemMessage) else [message.content]
|
|
135
|
-
)
|
|
136
|
-
serialized: gen_ai_types.ChatMessage = {
|
|
137
|
-
"role": message.role,
|
|
138
|
-
"parts": content_parts,
|
|
139
|
-
}
|
|
140
|
-
name = getattr(message, "name", None)
|
|
141
|
-
if name:
|
|
142
|
-
serialized["name"] = name
|
|
143
|
-
return serialized
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
def map_finish_reason(
|
|
147
|
-
reason: FinishReason | None,
|
|
148
|
-
) -> gen_ai_types.FinishReason:
|
|
149
|
-
"""Map a finish reason to a GenAI finish reason."""
|
|
150
|
-
if reason is None:
|
|
151
|
-
return "stop"
|
|
152
|
-
elif reason == FinishReason.MAX_TOKENS:
|
|
153
|
-
return "length"
|
|
154
|
-
elif reason == FinishReason.REFUSAL: # pragma: no cover
|
|
155
|
-
return "content_filter"
|
|
156
|
-
raise ValueError(f"Unknown finish reason: {reason}") # pragma: no cover
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
def _serialize_output_message(
|
|
160
|
-
message: AssistantMessage, finish_reason: FinishReason | None
|
|
161
|
-
) -> gen_ai_types.OutputMessage:
|
|
162
|
-
"""Serialize an assistant message into a GenAI OutputMessage with finish_reason."""
|
|
163
|
-
chat_message = _serialize_message(message)
|
|
164
|
-
output_message: gen_ai_types.OutputMessage = {
|
|
165
|
-
"role": chat_message["role"],
|
|
166
|
-
"parts": chat_message["parts"],
|
|
167
|
-
"finish_reason": map_finish_reason(finish_reason),
|
|
168
|
-
}
|
|
169
|
-
if "name" in chat_message:
|
|
170
|
-
output_message["name"] = chat_message["name"]
|
|
171
|
-
return output_message
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
def split_request_messages(
|
|
175
|
-
messages: Sequence[Message],
|
|
176
|
-
) -> tuple[gen_ai_types.SystemInstructions, gen_ai_types.InputMessages]:
|
|
177
|
-
"""Return serialized system instructions and non-system input messages.
|
|
178
|
-
|
|
179
|
-
System messages are flattened into a list of parts (not wrapped in message objects),
|
|
180
|
-
while other messages are serialized as complete ChatMessage objects.
|
|
181
|
-
"""
|
|
182
|
-
system_instructions: gen_ai_types.SystemInstructions = []
|
|
183
|
-
inputs: gen_ai_types.InputMessages = []
|
|
184
|
-
for message in messages:
|
|
185
|
-
if message.role == "system":
|
|
186
|
-
# System messages contribute only their parts (flattened)
|
|
187
|
-
parts = _serialize_message_parts(
|
|
188
|
-
[message.content]
|
|
189
|
-
if isinstance(message, SystemMessage)
|
|
190
|
-
else message.content
|
|
191
|
-
)
|
|
192
|
-
system_instructions.extend(parts)
|
|
193
|
-
else:
|
|
194
|
-
# Non-system messages are serialized as full ChatMessage objects
|
|
195
|
-
serialized = _serialize_message(message)
|
|
196
|
-
inputs.append(serialized)
|
|
197
|
-
return system_instructions, inputs
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
def snapshot_from_response_messages(
|
|
201
|
-
*,
|
|
202
|
-
request_messages: Sequence[Message],
|
|
203
|
-
assistant_message: AssistantMessage,
|
|
204
|
-
finish_reason: FinishReason | None,
|
|
205
|
-
) -> OTelMessageSnapshot:
|
|
206
|
-
"""Build a snapshot using the request/response boundary for a call."""
|
|
207
|
-
|
|
208
|
-
system_instructions, inputs = split_request_messages(request_messages)
|
|
209
|
-
outputs = [_serialize_output_message(assistant_message, finish_reason)]
|
|
210
|
-
return OTelMessageSnapshot(
|
|
211
|
-
system_instructions=system_instructions,
|
|
212
|
-
inputs=inputs,
|
|
213
|
-
outputs=outputs,
|
|
214
|
-
)
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
def snapshot_from_root_response(
|
|
218
|
-
response: RootResponse[ToolkitT, FormattableT | None],
|
|
219
|
-
*,
|
|
220
|
-
request_messages: Sequence[Message] | None = None,
|
|
221
|
-
) -> OTelMessageSnapshot:
|
|
222
|
-
"""Build a snapshot directly from a `RootResponse`.
|
|
223
|
-
|
|
224
|
-
Args:
|
|
225
|
-
response: The response that includes the entire conversation history.
|
|
226
|
-
request_messages: Optional explicit request message sequence. Defaults to all
|
|
227
|
-
but the final assistant message inside `response.messages`.
|
|
228
|
-
"""
|
|
229
|
-
|
|
230
|
-
assistant_message = response.messages[-1]
|
|
231
|
-
if not isinstance(assistant_message, AssistantMessage): # pragma: no cover
|
|
232
|
-
raise TypeError("Final response message must be an AssistantMessage")
|
|
233
|
-
|
|
234
|
-
return snapshot_from_response_messages(
|
|
235
|
-
request_messages=request_messages or response.messages[:-1],
|
|
236
|
-
assistant_message=assistant_message,
|
|
237
|
-
finish_reason=response.finish_reason,
|
|
238
|
-
)
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
"""OpenTelemetry Gen AI Semantic Conventions types."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
from .gen_ai_input_messages import ChatMessage, InputMessages
|
|
6
|
-
from .gen_ai_output_messages import FinishReason, OutputMessage, OutputMessages
|
|
7
|
-
from .gen_ai_system_instructions import SystemInstructions
|
|
8
|
-
from .shared import (
|
|
9
|
-
BlobPart,
|
|
10
|
-
FilePart,
|
|
11
|
-
GenericPart,
|
|
12
|
-
Modality,
|
|
13
|
-
ReasoningPart,
|
|
14
|
-
Role,
|
|
15
|
-
TextPart,
|
|
16
|
-
ToolCallRequestPart,
|
|
17
|
-
ToolCallResponsePart,
|
|
18
|
-
UriPart,
|
|
19
|
-
)
|
|
20
|
-
|
|
21
|
-
__all__ = [
|
|
22
|
-
"BlobPart",
|
|
23
|
-
"ChatMessage",
|
|
24
|
-
"FilePart",
|
|
25
|
-
"FinishReason",
|
|
26
|
-
"GenericPart",
|
|
27
|
-
"InputMessages",
|
|
28
|
-
"Modality",
|
|
29
|
-
"OutputMessage",
|
|
30
|
-
"OutputMessages",
|
|
31
|
-
"ReasoningPart",
|
|
32
|
-
"Role",
|
|
33
|
-
"SystemInstructions",
|
|
34
|
-
"TextPart",
|
|
35
|
-
"ToolCallRequestPart",
|
|
36
|
-
"ToolCallResponsePart",
|
|
37
|
-
"UriPart",
|
|
38
|
-
]
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
"""OpenTelemetry Gen AI Semantic Conventions types."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
from typing import TypeAlias, TypedDict
|
|
6
|
-
from typing_extensions import NotRequired
|
|
7
|
-
|
|
8
|
-
from . import shared
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class ChatMessage(TypedDict):
|
|
12
|
-
role: shared.Role | str
|
|
13
|
-
"""Role of the entity that created the message."""
|
|
14
|
-
|
|
15
|
-
parts: list[
|
|
16
|
-
shared.TextPart
|
|
17
|
-
| shared.ToolCallRequestPart
|
|
18
|
-
| shared.ToolCallResponsePart
|
|
19
|
-
| shared.BlobPart
|
|
20
|
-
| shared.FilePart
|
|
21
|
-
| shared.UriPart
|
|
22
|
-
| shared.ReasoningPart
|
|
23
|
-
| shared.GenericPart
|
|
24
|
-
]
|
|
25
|
-
"""List of message parts that make up the message content."""
|
|
26
|
-
|
|
27
|
-
name: NotRequired[str | None]
|
|
28
|
-
"""The name of the participant."""
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
InputMessages: TypeAlias = list[ChatMessage]
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
"""OpenTelemetry Gen AI Semantic Conventions types."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
from typing import Literal, TypeAlias, TypedDict
|
|
6
|
-
from typing_extensions import NotRequired
|
|
7
|
-
|
|
8
|
-
from . import shared
|
|
9
|
-
|
|
10
|
-
FinishReason: TypeAlias = Literal[
|
|
11
|
-
"stop", "length", "content_filter", "tool_call", "error"
|
|
12
|
-
]
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class OutputMessage(TypedDict):
|
|
16
|
-
role: shared.Role | str
|
|
17
|
-
"""Role of the entity that created the message."""
|
|
18
|
-
|
|
19
|
-
parts: list[
|
|
20
|
-
shared.TextPart
|
|
21
|
-
| shared.ToolCallRequestPart
|
|
22
|
-
| shared.ToolCallResponsePart
|
|
23
|
-
| shared.BlobPart
|
|
24
|
-
| shared.FilePart
|
|
25
|
-
| shared.UriPart
|
|
26
|
-
| shared.ReasoningPart
|
|
27
|
-
| shared.GenericPart
|
|
28
|
-
]
|
|
29
|
-
"""List of message parts that make up the message content."""
|
|
30
|
-
|
|
31
|
-
name: NotRequired[str | None]
|
|
32
|
-
"""The name of the participant."""
|
|
33
|
-
|
|
34
|
-
finish_reason: FinishReason | str
|
|
35
|
-
"""Reason for finishing the generation."""
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
OutputMessages: TypeAlias = list[OutputMessage]
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
"""OpenTelemetry Gen AI Semantic Conventions types."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
from typing import TypeAlias
|
|
6
|
-
|
|
7
|
-
from . import shared
|
|
8
|
-
|
|
9
|
-
SystemInstructions: TypeAlias = list[
|
|
10
|
-
shared.TextPart
|
|
11
|
-
| shared.ToolCallRequestPart
|
|
12
|
-
| shared.ToolCallResponsePart
|
|
13
|
-
| shared.BlobPart
|
|
14
|
-
| shared.FilePart
|
|
15
|
-
| shared.UriPart
|
|
16
|
-
| shared.ReasoningPart
|
|
17
|
-
| shared.GenericPart
|
|
18
|
-
]
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
"""OpenTelemetry Gen AI Semantic Conventions types."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
from typing import Any, Literal, TypeAlias, TypedDict
|
|
6
|
-
from typing_extensions import NotRequired
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class BlobPart(TypedDict):
|
|
10
|
-
type: Literal["blob"]
|
|
11
|
-
"""The type of the content captured in this part."""
|
|
12
|
-
|
|
13
|
-
mime_type: NotRequired[str | None]
|
|
14
|
-
"""The IANA MIME type of the attached data."""
|
|
15
|
-
|
|
16
|
-
modality: Modality | str
|
|
17
|
-
"""The general modality of the data if it is known. Instrumentations SHOULD also set the mimeType field if the specific type is known."""
|
|
18
|
-
|
|
19
|
-
content: str
|
|
20
|
-
"""Raw bytes of the attached data. This field SHOULD be encoded as a base64 string when transmitted as JSON."""
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
class FilePart(TypedDict):
|
|
24
|
-
type: Literal["file"]
|
|
25
|
-
"""The type of the content captured in this part."""
|
|
26
|
-
|
|
27
|
-
mime_type: NotRequired[str | None]
|
|
28
|
-
"""The IANA MIME type of the attached data."""
|
|
29
|
-
|
|
30
|
-
modality: Modality | str
|
|
31
|
-
"""The general modality of the data if it is known. Instrumentations SHOULD also set the mimeType field if the specific type is known."""
|
|
32
|
-
|
|
33
|
-
file_id: str
|
|
34
|
-
"""An identifier referencing a file that was pre-uploaded to the provider."""
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
class GenericPart(TypedDict):
|
|
38
|
-
type: str
|
|
39
|
-
"""The type of the content captured in this part."""
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
Modality: TypeAlias = Literal["image", "video", "audio"]
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
class ReasoningPart(TypedDict):
|
|
46
|
-
type: Literal["reasoning"]
|
|
47
|
-
"""The type of the content captured in this part."""
|
|
48
|
-
|
|
49
|
-
content: str
|
|
50
|
-
"""Reasoning/thinking content received from the model."""
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
Role: TypeAlias = Literal["system", "user", "assistant", "tool"]
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
class TextPart(TypedDict):
|
|
57
|
-
type: Literal["text"]
|
|
58
|
-
"""The type of the content captured in this part."""
|
|
59
|
-
|
|
60
|
-
content: str
|
|
61
|
-
"""Text content sent to or received from the model."""
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
class ToolCallRequestPart(TypedDict):
|
|
65
|
-
type: Literal["tool_call"]
|
|
66
|
-
"""The type of the content captured in this part."""
|
|
67
|
-
|
|
68
|
-
id: NotRequired[str | None]
|
|
69
|
-
"""Unique identifier for the tool call."""
|
|
70
|
-
|
|
71
|
-
name: str
|
|
72
|
-
"""Name of the tool."""
|
|
73
|
-
|
|
74
|
-
arguments: NotRequired[Any]
|
|
75
|
-
"""Arguments for the tool call."""
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
class ToolCallResponsePart(TypedDict):
|
|
79
|
-
type: Literal["tool_call_response"]
|
|
80
|
-
"""The type of the content captured in this part."""
|
|
81
|
-
|
|
82
|
-
id: NotRequired[str | None]
|
|
83
|
-
"""Unique tool call identifier."""
|
|
84
|
-
|
|
85
|
-
response: Any
|
|
86
|
-
"""Tool call response."""
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
class UriPart(TypedDict):
|
|
90
|
-
type: Literal["uri"]
|
|
91
|
-
"""The type of the content captured in this part."""
|
|
92
|
-
|
|
93
|
-
mime_type: NotRequired[str | None]
|
|
94
|
-
"""The IANA MIME type of the attached data."""
|
|
95
|
-
|
|
96
|
-
modality: Modality | str
|
|
97
|
-
"""The general modality of the data if it is known. Instrumentations SHOULD also set the mimeType field if the specific type is known."""
|
|
98
|
-
|
|
99
|
-
uri: str
|
|
100
|
-
"""A URI referencing attached data. It should not be a base64 data URL, which should use the `blob` part instead. The URI may use a scheme known to the provider api (e.g. `gs://bucket/object.png`), or be a publicly accessible location."""
|