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,178 +0,0 @@
|
|
|
1
|
-
"""The `llm.output_parser` decorator for creating custom output parsers."""
|
|
2
|
-
|
|
3
|
-
from collections.abc import Callable
|
|
4
|
-
from typing import TYPE_CHECKING, Any, Generic, TypeVar
|
|
5
|
-
from typing_extensions import TypeIs
|
|
6
|
-
|
|
7
|
-
if TYPE_CHECKING:
|
|
8
|
-
from ..responses import AnyResponse
|
|
9
|
-
|
|
10
|
-
OutputT = TypeVar("OutputT")
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class OutputParser(Generic[OutputT]):
|
|
14
|
-
"""Represents a custom output parser created with @llm.output_parser.
|
|
15
|
-
|
|
16
|
-
This class wraps a parsing function and stores formatting instructions.
|
|
17
|
-
It is created by the @llm.output_parser decorator and used as a format
|
|
18
|
-
argument in LLM calls.
|
|
19
|
-
|
|
20
|
-
Unlike BaseModel and primitive type formats that use structured outputs
|
|
21
|
-
(JSON schema, tools, strict mode), OutputParser works with raw text responses
|
|
22
|
-
and custom parsing logic.
|
|
23
|
-
|
|
24
|
-
Example:
|
|
25
|
-
```python
|
|
26
|
-
@llm.output_parser(
|
|
27
|
-
formatting_instructions="Return XML: <book><title>...</title></book>"
|
|
28
|
-
)
|
|
29
|
-
def parse_book_xml(response: llm.AnyResponse) -> Book:
|
|
30
|
-
text = "".join(part.text for part in response.texts)
|
|
31
|
-
root = ET.fromstring(text)
|
|
32
|
-
return Book(title=root.find("title").text, ...)
|
|
33
|
-
|
|
34
|
-
@llm.call("openai/gpt-4o", format=parse_book_xml)
|
|
35
|
-
def recommend_book(genre: str):
|
|
36
|
-
return f"Recommend a {genre} book."
|
|
37
|
-
|
|
38
|
-
response = recommend_book("fantasy")
|
|
39
|
-
book = response.parse() # Returns Book instance
|
|
40
|
-
```
|
|
41
|
-
"""
|
|
42
|
-
|
|
43
|
-
def __init__(
|
|
44
|
-
self,
|
|
45
|
-
func: Callable[["AnyResponse"], OutputT],
|
|
46
|
-
formatting_instructions: str,
|
|
47
|
-
) -> None:
|
|
48
|
-
"""Initialize the OutputParser.
|
|
49
|
-
|
|
50
|
-
Args:
|
|
51
|
-
func: The parsing function that takes a Response and returns parsed output.
|
|
52
|
-
formatting_instructions: Instructions for the LLM on how to format output.
|
|
53
|
-
"""
|
|
54
|
-
self.func = func
|
|
55
|
-
self._formatting_instructions = formatting_instructions
|
|
56
|
-
self.__name__ = func.__name__
|
|
57
|
-
self.__doc__ = func.__doc__
|
|
58
|
-
|
|
59
|
-
def formatting_instructions(self) -> str:
|
|
60
|
-
"""Return the formatting instructions for the LLM.
|
|
61
|
-
|
|
62
|
-
These instructions are added to the system prompt to guide the LLM
|
|
63
|
-
on how to format its output for parsing.
|
|
64
|
-
|
|
65
|
-
Returns:
|
|
66
|
-
The formatting instructions string.
|
|
67
|
-
"""
|
|
68
|
-
return self._formatting_instructions
|
|
69
|
-
|
|
70
|
-
def __call__(self, response: "AnyResponse") -> OutputT:
|
|
71
|
-
"""Parse the response using the wrapped function.
|
|
72
|
-
|
|
73
|
-
Args:
|
|
74
|
-
response: The response object from the LLM call.
|
|
75
|
-
|
|
76
|
-
Returns:
|
|
77
|
-
The parsed output of type OutputT.
|
|
78
|
-
|
|
79
|
-
Raises:
|
|
80
|
-
Any exception raised by the wrapped parsing function.
|
|
81
|
-
"""
|
|
82
|
-
return self.func(response)
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
def output_parser(
|
|
86
|
-
*,
|
|
87
|
-
formatting_instructions: str,
|
|
88
|
-
) -> Callable[[Callable[["AnyResponse"], OutputT]], OutputParser[OutputT]]:
|
|
89
|
-
"""Decorator to create an output parser for custom format parsing.
|
|
90
|
-
|
|
91
|
-
Use this decorator to create custom parsers for non-JSON formats like
|
|
92
|
-
XML, YAML, CSV, or any custom text structure. The decorated function
|
|
93
|
-
receives the full Response object and returns the parsed output.
|
|
94
|
-
|
|
95
|
-
This is the recommended way to handle custom output formats that don't
|
|
96
|
-
fit the JSON/BaseModel paradigm. The formatting instructions guide the
|
|
97
|
-
LLM on how to structure its output, and the parsing function extracts
|
|
98
|
-
the data you need.
|
|
99
|
-
|
|
100
|
-
Args:
|
|
101
|
-
formatting_instructions: Instructions for the LLM on how to format
|
|
102
|
-
the output. These will be added to the system prompt.
|
|
103
|
-
|
|
104
|
-
Returns:
|
|
105
|
-
Decorator that converts a function into an OutputParser.
|
|
106
|
-
|
|
107
|
-
Example:
|
|
108
|
-
|
|
109
|
-
XML parsing:
|
|
110
|
-
```python
|
|
111
|
-
@llm.output_parser(
|
|
112
|
-
formatting_instructions='''
|
|
113
|
-
Return the book information in this XML structure:
|
|
114
|
-
<book>
|
|
115
|
-
<title>Book Title</title>
|
|
116
|
-
<author>Author Name</author>
|
|
117
|
-
<rating>5</rating>
|
|
118
|
-
</book>
|
|
119
|
-
'''
|
|
120
|
-
)
|
|
121
|
-
def parse_book_xml(response: llm.AnyResponse) -> Book:
|
|
122
|
-
import xml.etree.ElementTree as ET
|
|
123
|
-
text = "".join(part.text for part in response.texts)
|
|
124
|
-
root = ET.fromstring(text)
|
|
125
|
-
return Book(
|
|
126
|
-
title=root.find("title").text,
|
|
127
|
-
author=root.find("author").text,
|
|
128
|
-
rating=int(root.find("rating").text),
|
|
129
|
-
)
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
Example:
|
|
133
|
-
|
|
134
|
-
CSV parsing:
|
|
135
|
-
```python
|
|
136
|
-
@llm.output_parser(
|
|
137
|
-
formatting_instructions='''
|
|
138
|
-
Return book information as CSV format with header:
|
|
139
|
-
title,author,rating
|
|
140
|
-
Book 1,Author 1,5
|
|
141
|
-
Book 2,Author 2,4
|
|
142
|
-
'''
|
|
143
|
-
)
|
|
144
|
-
def parse_books_csv(response: llm.AnyResponse) -> list[Book]:
|
|
145
|
-
text = "".join(part.text for part in response.texts)
|
|
146
|
-
lines = text.strip().split('\\n')[1:] # Skip header
|
|
147
|
-
return [
|
|
148
|
-
Book(
|
|
149
|
-
title=line.split(',')[0].strip(),
|
|
150
|
-
author=line.split(',')[1].strip(),
|
|
151
|
-
rating=int(line.split(',')[2]),
|
|
152
|
-
)
|
|
153
|
-
for line in lines
|
|
154
|
-
]
|
|
155
|
-
```
|
|
156
|
-
"""
|
|
157
|
-
|
|
158
|
-
def decorator(
|
|
159
|
-
func: Callable[["AnyResponse"], OutputT],
|
|
160
|
-
) -> OutputParser[OutputT]:
|
|
161
|
-
return OutputParser(func, formatting_instructions)
|
|
162
|
-
|
|
163
|
-
return decorator
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
def is_output_parser(obj: Any) -> TypeIs[OutputParser[Any]]: # noqa: ANN401
|
|
167
|
-
"""Check if an object is an OutputParser.
|
|
168
|
-
|
|
169
|
-
This is a type guard function that narrows the type of `obj` to
|
|
170
|
-
`OutputParser[Any, Any]` when it returns True.
|
|
171
|
-
|
|
172
|
-
Args:
|
|
173
|
-
obj: The object to check.
|
|
174
|
-
|
|
175
|
-
Returns:
|
|
176
|
-
True if the object is an OutputParser instance, False otherwise.
|
|
177
|
-
"""
|
|
178
|
-
return isinstance(obj, OutputParser)
|
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
"""Utilities for handling primitive types in formatting."""
|
|
2
|
-
|
|
3
|
-
import inspect
|
|
4
|
-
from enum import Enum
|
|
5
|
-
from types import UnionType
|
|
6
|
-
from typing import (
|
|
7
|
-
Annotated,
|
|
8
|
-
Any,
|
|
9
|
-
Literal,
|
|
10
|
-
Protocol,
|
|
11
|
-
TypeAlias,
|
|
12
|
-
Union,
|
|
13
|
-
cast,
|
|
14
|
-
get_args,
|
|
15
|
-
get_origin,
|
|
16
|
-
)
|
|
17
|
-
from typing_extensions import TypeIs
|
|
18
|
-
|
|
19
|
-
from pydantic import create_model
|
|
20
|
-
|
|
21
|
-
PrimitiveType: TypeAlias = (
|
|
22
|
-
str
|
|
23
|
-
| int
|
|
24
|
-
| float
|
|
25
|
-
| bool
|
|
26
|
-
| bytes
|
|
27
|
-
| list[Any]
|
|
28
|
-
| set[Any]
|
|
29
|
-
| tuple[Any, ...]
|
|
30
|
-
| dict[Any, Any]
|
|
31
|
-
)
|
|
32
|
-
"""Primitive types that can be used with format parameter.
|
|
33
|
-
|
|
34
|
-
These types are automatically wrapped in a BaseModel for schema generation,
|
|
35
|
-
then unwrapped after validation to return the primitive value.
|
|
36
|
-
"""
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
class PrimitiveWrapperModel(Protocol):
|
|
40
|
-
"""Protocol for wrapper models with an output field."""
|
|
41
|
-
|
|
42
|
-
output: Any
|
|
43
|
-
model_fields: Any
|
|
44
|
-
|
|
45
|
-
def __init__(self, *, output: Any) -> None: ... # noqa: ANN401
|
|
46
|
-
|
|
47
|
-
@classmethod
|
|
48
|
-
def model_json_schema(cls) -> dict[str, Any]: ...
|
|
49
|
-
|
|
50
|
-
@classmethod
|
|
51
|
-
def model_validate_json(cls, json_data: str) -> "PrimitiveWrapperModel": ...
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
def is_primitive_type(
|
|
55
|
-
type_: Any, # noqa: ANN401
|
|
56
|
-
) -> TypeIs[type[PrimitiveType]]:
|
|
57
|
-
"""Check if a type is a primitive type that needs wrapping.
|
|
58
|
-
|
|
59
|
-
Returns True for:
|
|
60
|
-
- Basic primitives: str, int, float, bool, bytes, list, set, tuple, dict
|
|
61
|
-
- Enum types
|
|
62
|
-
- Generic types with primitive origins: list[Book], dict[str, int]
|
|
63
|
-
- Literal types
|
|
64
|
-
- Union types (including Optional)
|
|
65
|
-
- Annotated types
|
|
66
|
-
|
|
67
|
-
Returns False for:
|
|
68
|
-
- BaseModel subclasses (already have model_json_schema)
|
|
69
|
-
- None/NoneType
|
|
70
|
-
|
|
71
|
-
Args:
|
|
72
|
-
type_: The type to check
|
|
73
|
-
|
|
74
|
-
Returns:
|
|
75
|
-
True if the type is a primitive that needs wrapping
|
|
76
|
-
|
|
77
|
-
Example:
|
|
78
|
-
>>> is_primitive_type(str)
|
|
79
|
-
True
|
|
80
|
-
>>> is_primitive_type(list[int])
|
|
81
|
-
True
|
|
82
|
-
>>> from pydantic import BaseModel
|
|
83
|
-
>>> class Book(BaseModel):
|
|
84
|
-
... title: str
|
|
85
|
-
>>> is_primitive_type(Book)
|
|
86
|
-
False
|
|
87
|
-
"""
|
|
88
|
-
primitive_types: set[type[PrimitiveType]] = {
|
|
89
|
-
str,
|
|
90
|
-
int,
|
|
91
|
-
float,
|
|
92
|
-
bool,
|
|
93
|
-
bytes,
|
|
94
|
-
list,
|
|
95
|
-
set,
|
|
96
|
-
tuple,
|
|
97
|
-
dict,
|
|
98
|
-
}
|
|
99
|
-
special_types: set[Any] = {Annotated, Literal, Union, UnionType}
|
|
100
|
-
|
|
101
|
-
return (
|
|
102
|
-
(inspect.isclass(type_) and issubclass(type_, Enum))
|
|
103
|
-
or type_ in primitive_types
|
|
104
|
-
or get_origin(type_) in primitive_types.union(special_types)
|
|
105
|
-
)
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
def _get_type_name(type_: Any) -> str: # noqa: ANN401
|
|
109
|
-
"""Extract a clean name from a type for use in model naming.
|
|
110
|
-
|
|
111
|
-
Handles Annotated types by extracting the underlying type,
|
|
112
|
-
and generates clean names for generic types.
|
|
113
|
-
|
|
114
|
-
Args:
|
|
115
|
-
type_: The type to extract a name from
|
|
116
|
-
|
|
117
|
-
Returns:
|
|
118
|
-
A clean string suitable for use in a Python class name
|
|
119
|
-
|
|
120
|
-
Example:
|
|
121
|
-
>>> _get_type_name(str)
|
|
122
|
-
'str'
|
|
123
|
-
>>> _get_type_name(list[int])
|
|
124
|
-
'list_int_'
|
|
125
|
-
"""
|
|
126
|
-
# Import Annotated locally
|
|
127
|
-
# Check if this is an Annotated type
|
|
128
|
-
if get_origin(type_) in {Annotated}:
|
|
129
|
-
# For Annotated types, use the first arg (the actual type)
|
|
130
|
-
return _get_type_name(get_args(type_)[0])
|
|
131
|
-
|
|
132
|
-
# If the type has a __name__ attribute, use it
|
|
133
|
-
if hasattr(type_, "__name__"):
|
|
134
|
-
return type_.__name__
|
|
135
|
-
|
|
136
|
-
# For complex generics like list[Book], use string representation
|
|
137
|
-
type_str = str(type_)
|
|
138
|
-
|
|
139
|
-
# Clean up the string to make it a valid Python identifier
|
|
140
|
-
# Replace brackets and commas with underscores
|
|
141
|
-
clean = (
|
|
142
|
-
type_str.replace("[", "_")
|
|
143
|
-
.replace("]", "_")
|
|
144
|
-
.replace(", ", "_")
|
|
145
|
-
.replace(" ", "")
|
|
146
|
-
.replace("'", "")
|
|
147
|
-
.replace('"', "")
|
|
148
|
-
)
|
|
149
|
-
|
|
150
|
-
return clean
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
def create_wrapper_model(
|
|
154
|
-
primitive_type: Any, # noqa: ANN401
|
|
155
|
-
) -> type[PrimitiveWrapperModel]:
|
|
156
|
-
"""Create a wrapper BaseModel for a primitive type.
|
|
157
|
-
|
|
158
|
-
The wrapper has a single field called "output" containing the primitive value.
|
|
159
|
-
Uses Pydantic's create_model() to generate the wrapper dynamically.
|
|
160
|
-
|
|
161
|
-
Args:
|
|
162
|
-
primitive_type: The primitive type to wrap
|
|
163
|
-
|
|
164
|
-
Returns:
|
|
165
|
-
A dynamically created BaseModel with an "output" field
|
|
166
|
-
|
|
167
|
-
Example:
|
|
168
|
-
>>> wrapper = create_wrapper_model(str)
|
|
169
|
-
>>> instance = wrapper(output="hello")
|
|
170
|
-
>>> instance.output
|
|
171
|
-
'hello'
|
|
172
|
-
|
|
173
|
-
>>> from pydantic import BaseModel
|
|
174
|
-
>>> class Book(BaseModel):
|
|
175
|
-
... title: str
|
|
176
|
-
>>> wrapper = create_wrapper_model(list[Book])
|
|
177
|
-
>>> books = [Book(title="Test")]
|
|
178
|
-
>>> instance = wrapper(output=books)
|
|
179
|
-
>>> len(instance.output)
|
|
180
|
-
1
|
|
181
|
-
"""
|
|
182
|
-
# Get a clean name for the wrapper class
|
|
183
|
-
type_name = _get_type_name(primitive_type)
|
|
184
|
-
|
|
185
|
-
# Create wrapper model with "output" field (required)
|
|
186
|
-
wrapper = create_model(
|
|
187
|
-
f"{type_name}Output",
|
|
188
|
-
__doc__=f"Wrapper for primitive type {type_name}",
|
|
189
|
-
output=(primitive_type, ...), # ... means required
|
|
190
|
-
)
|
|
191
|
-
|
|
192
|
-
return cast(type[PrimitiveWrapperModel], wrapper)
|
mirascope/llm/mcp/mcp_client.py
DELETED
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
import contextlib
|
|
2
|
-
from collections.abc import AsyncIterator
|
|
3
|
-
from datetime import timedelta
|
|
4
|
-
from typing import cast
|
|
5
|
-
|
|
6
|
-
from mcp import ClientSession
|
|
7
|
-
from mcp.client.sse import sse_client as mcp_sse_client
|
|
8
|
-
from mcp.client.stdio import StdioServerParameters, stdio_client as mcp_stdio_client
|
|
9
|
-
from mcp.client.streamable_http import (
|
|
10
|
-
streamable_http_client as mcp_streamable_http_client,
|
|
11
|
-
)
|
|
12
|
-
from mcp.types import CallToolResult, Tool as MCPTool
|
|
13
|
-
|
|
14
|
-
from ..tools import AsyncTool
|
|
15
|
-
from ..tools.tool_schema import ToolParameterSchema
|
|
16
|
-
from ..types import Jsonable
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class MCPClient:
|
|
20
|
-
"""Mirascope wrapper around a MCP ClientSession.
|
|
21
|
-
|
|
22
|
-
It provides a way to get MCP results that are pre-converted into Mirascope-friendly
|
|
23
|
-
types.
|
|
24
|
-
|
|
25
|
-
The underlying MCP ClientSession may be accessed by .session if needed.
|
|
26
|
-
"""
|
|
27
|
-
|
|
28
|
-
def __init__(self, session: ClientSession) -> None:
|
|
29
|
-
self._session = session
|
|
30
|
-
|
|
31
|
-
@property
|
|
32
|
-
def session(self) -> ClientSession:
|
|
33
|
-
"""Access the underlying MCP ClientSession if needed."""
|
|
34
|
-
return self._session
|
|
35
|
-
|
|
36
|
-
def _convert_mcp_tool_to_async_tool(self, mcp_tool: MCPTool) -> AsyncTool:
|
|
37
|
-
"""Convert an MCP Tool to a Mirascope AsyncTool.
|
|
38
|
-
|
|
39
|
-
Args:
|
|
40
|
-
mcp_tool: The MCP tool to convert.
|
|
41
|
-
|
|
42
|
-
Returns:
|
|
43
|
-
An `AsyncTool` that wraps the MCP tool.
|
|
44
|
-
"""
|
|
45
|
-
|
|
46
|
-
# Create an async function that calls the MCP tool
|
|
47
|
-
async def tool_fn(**kwargs: object) -> Jsonable:
|
|
48
|
-
tool_result: CallToolResult = await self._session.call_tool(
|
|
49
|
-
mcp_tool.name, kwargs
|
|
50
|
-
)
|
|
51
|
-
# Convert ContentBlock objects to JSON-serializable dicts
|
|
52
|
-
# Cast to Jsonable since model_dump() returns dict[str, Any]
|
|
53
|
-
return cast(
|
|
54
|
-
Jsonable, [content.model_dump() for content in tool_result.content]
|
|
55
|
-
)
|
|
56
|
-
|
|
57
|
-
# Convert MCP tool's inputSchema to Mirascope's ToolParameterSchema
|
|
58
|
-
input_schema = mcp_tool.inputSchema
|
|
59
|
-
parameters = ToolParameterSchema(
|
|
60
|
-
properties=input_schema.get("properties", {}),
|
|
61
|
-
required=input_schema.get("required", []),
|
|
62
|
-
additionalProperties=input_schema.get("additionalProperties", False),
|
|
63
|
-
)
|
|
64
|
-
if "$defs" in input_schema:
|
|
65
|
-
parameters.defs = input_schema["$defs"]
|
|
66
|
-
|
|
67
|
-
# Create the AsyncTool instance
|
|
68
|
-
return AsyncTool(
|
|
69
|
-
fn=tool_fn,
|
|
70
|
-
name=mcp_tool.name,
|
|
71
|
-
description=mcp_tool.description or mcp_tool.name,
|
|
72
|
-
parameters=parameters,
|
|
73
|
-
strict=False,
|
|
74
|
-
)
|
|
75
|
-
|
|
76
|
-
async def list_tools(self) -> list[AsyncTool]:
|
|
77
|
-
"""List all tools available on the MCP server.
|
|
78
|
-
|
|
79
|
-
Returns:
|
|
80
|
-
A list of dynamically created `AsyncTool`s.
|
|
81
|
-
"""
|
|
82
|
-
result = await self._session.list_tools()
|
|
83
|
-
return [self._convert_mcp_tool_to_async_tool(tool) for tool in result.tools]
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
@contextlib.asynccontextmanager
|
|
87
|
-
async def streamable_http_client(
|
|
88
|
-
url: str,
|
|
89
|
-
) -> AsyncIterator[MCPClient]: # pragma: no cover
|
|
90
|
-
"""Create a Mirascope MCPClient using StreamableHTTP."""
|
|
91
|
-
# NOTE: If updating this function, unskip and manually run the TestTransportModes
|
|
92
|
-
# tests in test_mcp_client.py. (Skipped because they are flaky)
|
|
93
|
-
async with (
|
|
94
|
-
mcp_streamable_http_client(url) as (read, write, _),
|
|
95
|
-
ClientSession(read, write) as session,
|
|
96
|
-
):
|
|
97
|
-
await session.initialize()
|
|
98
|
-
yield MCPClient(session)
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
@contextlib.asynccontextmanager
|
|
102
|
-
async def stdio_client(
|
|
103
|
-
server_parameters: StdioServerParameters,
|
|
104
|
-
name: str | None = None,
|
|
105
|
-
) -> AsyncIterator[MCPClient]:
|
|
106
|
-
"""Create a Mirascope MCPClient using stdio."""
|
|
107
|
-
async with (
|
|
108
|
-
mcp_stdio_client(server_parameters) as (read, write),
|
|
109
|
-
ClientSession(read, write) as session,
|
|
110
|
-
):
|
|
111
|
-
await session.initialize()
|
|
112
|
-
yield MCPClient(session)
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
@contextlib.asynccontextmanager
|
|
116
|
-
async def sse_client(
|
|
117
|
-
url: str,
|
|
118
|
-
read_timeout_seconds: timedelta | None = None,
|
|
119
|
-
) -> AsyncIterator[MCPClient]: # pragma: no cover
|
|
120
|
-
"""Create a Mirascope MCPClient using sse."""
|
|
121
|
-
# NOTE: If updating this function, unskip and manually run the TestTransportModes
|
|
122
|
-
# tests in test_mcp_client.py. (Skipped because they are flaky)
|
|
123
|
-
async with (
|
|
124
|
-
mcp_sse_client(url) as (read, write),
|
|
125
|
-
ClientSession(
|
|
126
|
-
read, write, read_timeout_seconds=read_timeout_seconds
|
|
127
|
-
) as session,
|
|
128
|
-
):
|
|
129
|
-
await session.initialize()
|
|
130
|
-
yield MCPClient(session)
|
mirascope/llm/messages/_utils.py
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
"""Utility functions for message handling."""
|
|
2
|
-
|
|
3
|
-
from collections.abc import Sequence
|
|
4
|
-
from typing_extensions import TypeIs
|
|
5
|
-
|
|
6
|
-
from .message import (
|
|
7
|
-
AssistantMessage,
|
|
8
|
-
Message,
|
|
9
|
-
SystemMessage,
|
|
10
|
-
UserContent,
|
|
11
|
-
UserMessage,
|
|
12
|
-
user,
|
|
13
|
-
)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
def is_messages(
|
|
17
|
-
content: UserContent | Sequence[Message],
|
|
18
|
-
) -> TypeIs[Sequence[Message]]:
|
|
19
|
-
if isinstance(content, list):
|
|
20
|
-
if not content:
|
|
21
|
-
raise ValueError("Empty array may not be used as message content")
|
|
22
|
-
return isinstance(content[0], SystemMessage | UserMessage | AssistantMessage)
|
|
23
|
-
return False
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
def promote_to_messages(content: UserContent | Sequence[Message]) -> Sequence[Message]:
|
|
27
|
-
"""Promote a prompt result to a list of messages.
|
|
28
|
-
|
|
29
|
-
If the result is already a list of Messages, returns it as-is.
|
|
30
|
-
If the result is str/UserContentPart/Sequence of content parts, wraps it in a user message.
|
|
31
|
-
"""
|
|
32
|
-
if is_messages(content):
|
|
33
|
-
return content
|
|
34
|
-
return [user(content)]
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
"""Configuration for extended reasoning/thinking in LLM responses."""
|
|
2
|
-
|
|
3
|
-
from typing import Literal
|
|
4
|
-
from typing_extensions import Required, TypedDict
|
|
5
|
-
|
|
6
|
-
ThinkingLevel = Literal["none", "default", "minimal", "low", "medium", "high", "max"]
|
|
7
|
-
"""Level of effort/reasoning to apply to thinking."""
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class ThinkingConfig(TypedDict, total=False):
|
|
11
|
-
"""Configuration for extended reasoning/thinking in LLM responses.
|
|
12
|
-
|
|
13
|
-
Thinking is a process where the model spends additional tokens reasoning about
|
|
14
|
-
the prompt before generating a response. Providing any `ThinkingConfig` will enable
|
|
15
|
-
thinking (unless it is specifically disabled via level="minimal"). Depending on
|
|
16
|
-
the provider and model, thinking may always be active regardless of user settings.
|
|
17
|
-
"""
|
|
18
|
-
|
|
19
|
-
level: Required[ThinkingLevel]
|
|
20
|
-
"""Level of effort/reasoning to apply to thinking.
|
|
21
|
-
|
|
22
|
-
- none: Disable thinking entirely. Minimizes cost and latency.
|
|
23
|
-
- default: Use the provider's default
|
|
24
|
-
- minimal: Use the provider's lowest setting for reasoning
|
|
25
|
-
- medium: Use a moderate amount of reasoning tokens
|
|
26
|
-
- high: Allow extensive resources for thinking
|
|
27
|
-
- max: Uses as much thinking as allowed by the provider.
|
|
28
|
-
|
|
29
|
-
Mirascope makes a best effort to apply the chosen thinking level, but exact behavior
|
|
30
|
-
varies by provider and model. For example, some models may not support thinking,
|
|
31
|
-
while other models may not allow disabling it.
|
|
32
|
-
"""
|
|
33
|
-
|
|
34
|
-
include_thoughts: bool
|
|
35
|
-
"""Whether to include Thought content in the model output.
|
|
36
|
-
|
|
37
|
-
Depending on the model and provider, enabling include_thoughts to true may
|
|
38
|
-
request reasoning summaries (which are not the underlying reasoning tokens,
|
|
39
|
-
but a readable summary produced by another model), or it may be the original
|
|
40
|
-
reasoning tokens.
|
|
41
|
-
|
|
42
|
-
When include_thoughts is false, no summaries will be requested, and thoughts
|
|
43
|
-
will not be included in the output even if they were provided by the provider.
|
|
44
|
-
|
|
45
|
-
Defaults to false.
|
|
46
|
-
"""
|
|
47
|
-
|
|
48
|
-
encode_thoughts_as_text: bool
|
|
49
|
-
"""Re-encode Thought content as text for model consumption.
|
|
50
|
-
|
|
51
|
-
If `True`, when an `AssistantMessage` contains `Thoughts` and is passed back
|
|
52
|
-
to an LLM, those `Thoughts` will be encoded as `Text`, ensuring the assistant
|
|
53
|
-
can read its prior reasoning. This contrasts with provider defaults which may
|
|
54
|
-
ignore prior thoughts, particularly if tool calls are not involved.
|
|
55
|
-
|
|
56
|
-
When `True`, Mirascope will re-encode messages rather than reusing raw provider
|
|
57
|
-
response content, which may disable provider-specific optimizations like cached
|
|
58
|
-
reasoning tokens.
|
|
59
|
-
|
|
60
|
-
Defaults to `False` if unset.
|
|
61
|
-
"""
|