mirascope 2.0.0__py3-none-any.whl → 2.0.0a0__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 +16 -101
- 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/anthropic/__init__.py +11 -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 +6 -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 +9 -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 +9 -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.0a0.dist-info}/METADATA +9 -95
- mirascope-2.0.0a0.dist-info/RECORD +101 -0
- {mirascope-2.0.0.dist-info → mirascope-2.0.0a0.dist-info}/WHEEL +1 -1
- {mirascope-2.0.0.dist-info → mirascope-2.0.0a0.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,18 +1,16 @@
|
|
|
1
1
|
"""The Responses module for LLM responses."""
|
|
2
2
|
|
|
3
3
|
from . import _utils
|
|
4
|
-
from .base_response import ResponseT
|
|
5
4
|
from .base_stream_response import (
|
|
6
5
|
AsyncChunkIterator,
|
|
7
6
|
ChunkIterator,
|
|
8
7
|
RawMessageChunk,
|
|
9
8
|
RawStreamEventChunk,
|
|
10
9
|
StreamResponseChunk,
|
|
11
|
-
StreamResponseT,
|
|
12
10
|
)
|
|
13
11
|
from .finish_reason import FinishReason, FinishReasonChunk
|
|
14
12
|
from .response import AsyncContextResponse, AsyncResponse, ContextResponse, Response
|
|
15
|
-
from .root_response import
|
|
13
|
+
from .root_response import RootResponse
|
|
16
14
|
from .stream_response import (
|
|
17
15
|
AsyncContextStreamResponse,
|
|
18
16
|
AsyncStreamResponse,
|
|
@@ -29,10 +27,8 @@ from .streams import (
|
|
|
29
27
|
ThoughtStream,
|
|
30
28
|
ToolCallStream,
|
|
31
29
|
)
|
|
32
|
-
from .usage import Usage, UsageDeltaChunk
|
|
33
30
|
|
|
34
31
|
__all__ = [
|
|
35
|
-
"AnyResponse",
|
|
36
32
|
"AsyncChunkIterator",
|
|
37
33
|
"AsyncContextResponse",
|
|
38
34
|
"AsyncContextStreamResponse",
|
|
@@ -50,16 +46,12 @@ __all__ = [
|
|
|
50
46
|
"RawMessageChunk",
|
|
51
47
|
"RawStreamEventChunk",
|
|
52
48
|
"Response",
|
|
53
|
-
"ResponseT",
|
|
54
49
|
"RootResponse",
|
|
55
50
|
"Stream",
|
|
56
51
|
"StreamResponse",
|
|
57
52
|
"StreamResponseChunk",
|
|
58
|
-
"StreamResponseT",
|
|
59
53
|
"TextStream",
|
|
60
54
|
"ThoughtStream",
|
|
61
55
|
"ToolCallStream",
|
|
62
|
-
"Usage",
|
|
63
|
-
"UsageDeltaChunk",
|
|
64
56
|
"_utils",
|
|
65
57
|
]
|
|
@@ -1,34 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import json
|
|
4
|
-
from typing import cast
|
|
5
|
-
|
|
6
|
-
import jiter
|
|
7
|
-
from pydantic import BaseModel
|
|
8
|
-
|
|
9
|
-
from ..formatting import (
|
|
10
|
-
FormattableT,
|
|
11
|
-
Partial,
|
|
12
|
-
PrimitiveWrapperModel,
|
|
13
|
-
create_wrapper_model,
|
|
14
|
-
is_primitive_type,
|
|
15
|
-
)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
def _strip_json_preamble(text: str) -> str | None:
|
|
19
|
-
"""Strip preamble text before JSON content.
|
|
1
|
+
def extract_serialized_json(text: str) -> str:
|
|
2
|
+
"""Extract the serialized JSON string from text that may contain extra content.
|
|
20
3
|
|
|
21
4
|
Handles cases where models output text before JSON like:
|
|
22
|
-
"Sure thing! Here's the JSON:\n{..."
|
|
5
|
+
"Sure thing! Here's the JSON:\n{...}"
|
|
23
6
|
|
|
24
7
|
Or cases where the model wraps the JSON in code blocks like:
|
|
25
|
-
"```json\n{..."
|
|
8
|
+
"```json\n{...}\n```"
|
|
26
9
|
|
|
27
10
|
Args:
|
|
28
11
|
text: The raw text that may contain a JSON object
|
|
29
12
|
|
|
13
|
+
Raises:
|
|
14
|
+
ValueError: If no serialized json object string was found.
|
|
15
|
+
|
|
30
16
|
Returns:
|
|
31
|
-
|
|
17
|
+
The extracted serialized JSON string
|
|
32
18
|
"""
|
|
33
19
|
code_block_start_marker = "```json"
|
|
34
20
|
code_block_start = text.find(code_block_start_marker)
|
|
@@ -39,39 +25,14 @@ def _strip_json_preamble(text: str) -> str | None:
|
|
|
39
25
|
|
|
40
26
|
json_start = text.find("{")
|
|
41
27
|
if json_start == -1:
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
return text[json_start:]
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
def extract_serialized_json(text: str) -> str:
|
|
48
|
-
"""Extract the serialized JSON string from text that may contain extra content.
|
|
49
|
-
|
|
50
|
-
Handles cases where models output text before JSON like:
|
|
51
|
-
"Sure thing! Here's the JSON:\n{...}"
|
|
52
|
-
|
|
53
|
-
Or cases where the model wraps the JSON in code blocks like:
|
|
54
|
-
"```json\n{...}\n```"
|
|
55
|
-
|
|
56
|
-
Args:
|
|
57
|
-
text: The raw text that may contain a JSON object
|
|
58
|
-
|
|
59
|
-
Raises:
|
|
60
|
-
json.JSONDecodeError: If no valid JSON object could be extracted.
|
|
61
|
-
|
|
62
|
-
Returns:
|
|
63
|
-
The extracted serialized JSON string
|
|
64
|
-
"""
|
|
65
|
-
stripped = _strip_json_preamble(text)
|
|
66
|
-
if stripped is None:
|
|
67
|
-
raise json.JSONDecodeError("No JSON object found: missing '{'", text, 0)
|
|
28
|
+
raise ValueError("Could not extract json: no opening `{`")
|
|
68
29
|
|
|
69
30
|
# Find the matching closing brace
|
|
70
31
|
brace_count = 0
|
|
71
32
|
in_string = False
|
|
72
33
|
escaped = False
|
|
73
34
|
|
|
74
|
-
for i, char in enumerate(
|
|
35
|
+
for i, char in enumerate(text[json_start:], json_start):
|
|
75
36
|
if escaped:
|
|
76
37
|
escaped = False
|
|
77
38
|
continue
|
|
@@ -90,57 +51,6 @@ def extract_serialized_json(text: str) -> str:
|
|
|
90
51
|
elif char == "}":
|
|
91
52
|
brace_count -= 1
|
|
92
53
|
if brace_count == 0:
|
|
93
|
-
return
|
|
94
|
-
|
|
95
|
-
raise json.JSONDecodeError("No JSON object found: missing '}'", text, len(text))
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
def parse_partial_json(
|
|
99
|
-
json_text: str, formattable: type[FormattableT]
|
|
100
|
-
) -> FormattableT | Partial[FormattableT] | None:
|
|
101
|
-
"""Parse incomplete JSON into a Partial model for structured streaming.
|
|
102
|
-
|
|
103
|
-
Uses jiter's partial mode to handle incomplete JSON gracefully.
|
|
104
|
-
Returns None if JSON cannot be parsed yet.
|
|
105
|
-
|
|
106
|
-
Handles cases where models output text before JSON like:
|
|
107
|
-
"Sure thing! Here's the JSON:\n{..."
|
|
108
|
-
|
|
109
|
-
Args:
|
|
110
|
-
json_text: The incomplete JSON string to parse
|
|
111
|
-
formattable: The target format type (BaseModel or PrimitiveType)
|
|
112
|
-
|
|
113
|
-
Returns:
|
|
114
|
-
Parsed partial object, or None if unparsable
|
|
115
|
-
|
|
116
|
-
Example:
|
|
117
|
-
>>> from pydantic import BaseModel
|
|
118
|
-
>>> class Book(BaseModel):
|
|
119
|
-
... title: str
|
|
120
|
-
... author: str
|
|
121
|
-
>>> parse_partial_json('{"title": "The Name"', Book)
|
|
122
|
-
PartialBook(title='The Name', author=None)
|
|
123
|
-
"""
|
|
124
|
-
# Strip preamble text before JSON
|
|
125
|
-
stripped = _strip_json_preamble(json_text)
|
|
126
|
-
if stripped is None:
|
|
127
|
-
return None
|
|
128
|
-
|
|
129
|
-
try:
|
|
130
|
-
parsed = jiter.from_json(stripped.encode(), partial_mode="trailing-strings")
|
|
131
|
-
except Exception:
|
|
132
|
-
return None
|
|
133
|
-
|
|
134
|
-
target_model = formattable
|
|
135
|
-
if is_primitive_type(target_model):
|
|
136
|
-
target_model = cast(BaseModel, create_wrapper_model(target_model))
|
|
137
|
-
|
|
138
|
-
try:
|
|
139
|
-
instance = cast(BaseModel, Partial[target_model]).model_validate(parsed)
|
|
140
|
-
except Exception:
|
|
141
|
-
return None
|
|
142
|
-
|
|
143
|
-
if is_primitive_type(formattable):
|
|
144
|
-
return cast(PrimitiveWrapperModel, instance).output
|
|
54
|
+
return text[json_start : i + 1]
|
|
145
55
|
|
|
146
|
-
|
|
56
|
+
raise ValueError("Could not extract json: no closing `}`")
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Shared base of Response and AsyncResponse."""
|
|
2
2
|
|
|
3
3
|
from collections.abc import Sequence
|
|
4
|
-
from typing import TYPE_CHECKING, Any
|
|
4
|
+
from typing import TYPE_CHECKING, Any
|
|
5
5
|
|
|
6
6
|
from ..content import Text, Thought, ToolCall
|
|
7
7
|
from ..formatting import Format, FormattableT
|
|
@@ -9,13 +9,9 @@ from ..messages import AssistantMessage, Message
|
|
|
9
9
|
from ..tools import FORMAT_TOOL_NAME, ToolkitT
|
|
10
10
|
from .finish_reason import FinishReason
|
|
11
11
|
from .root_response import RootResponse
|
|
12
|
-
from .usage import Usage
|
|
13
12
|
|
|
14
13
|
if TYPE_CHECKING:
|
|
15
|
-
from ..
|
|
16
|
-
from ..providers import ModelId, ProviderId
|
|
17
|
-
|
|
18
|
-
ResponseT = TypeVar("ResponseT", bound="BaseResponse[Any, Any]")
|
|
14
|
+
from ..clients import ModelId, Params, Provider
|
|
19
15
|
|
|
20
16
|
|
|
21
17
|
class BaseResponse(RootResponse[ToolkitT, FormattableT]):
|
|
@@ -25,41 +21,34 @@ class BaseResponse(RootResponse[ToolkitT, FormattableT]):
|
|
|
25
21
|
self,
|
|
26
22
|
*,
|
|
27
23
|
raw: Any, # noqa: ANN401
|
|
28
|
-
|
|
24
|
+
provider: "Provider",
|
|
29
25
|
model_id: "ModelId",
|
|
30
|
-
provider_model_name: str,
|
|
31
26
|
params: "Params",
|
|
32
27
|
toolkit: ToolkitT,
|
|
33
28
|
format: Format[FormattableT] | None = None,
|
|
34
29
|
input_messages: Sequence[Message],
|
|
35
30
|
assistant_message: AssistantMessage,
|
|
36
31
|
finish_reason: FinishReason | None,
|
|
37
|
-
usage: Usage | None,
|
|
38
32
|
) -> None:
|
|
39
33
|
"""Initialize a Response.
|
|
40
34
|
|
|
41
35
|
Args:
|
|
42
36
|
raw: The raw response from the LLM.
|
|
43
|
-
provider: The provider name (e.g. "anthropic", "openai").
|
|
37
|
+
provider: The provider name (e.g. "anthropic", "openai:completions").
|
|
44
38
|
model_id: The model identifier that generated the response.
|
|
45
|
-
provider_model_name: Optional provider-specific model name. May include
|
|
46
|
-
provider-specific additional info (like api mode in "gpt-5:responses").
|
|
47
39
|
params: The params used to generate the response (or None).
|
|
48
40
|
toolkit: Toolkit containing all the tools used to generate the response.
|
|
49
41
|
format: The `Format` for the expected structured output format (or None).
|
|
50
42
|
input_messages: The message history before the final assistant message.
|
|
51
43
|
assistant_message: The final assistant message containing the response content.
|
|
52
44
|
finish_reason: The reason why the LLM finished generating a response.
|
|
53
|
-
usage: Token usage statistics for the response.
|
|
54
45
|
"""
|
|
55
46
|
self.raw = raw
|
|
56
|
-
self.
|
|
47
|
+
self.provider = provider
|
|
57
48
|
self.model_id = model_id
|
|
58
|
-
self.provider_model_name = provider_model_name
|
|
59
49
|
self.params = params
|
|
60
50
|
self.toolkit = toolkit
|
|
61
51
|
self.finish_reason = finish_reason
|
|
62
|
-
self.usage = usage
|
|
63
52
|
self.format = format
|
|
64
53
|
|
|
65
54
|
# Process content in the assistant message, organizing it by type and
|
|
@@ -95,9 +84,8 @@ class BaseResponse(RootResponse[ToolkitT, FormattableT]):
|
|
|
95
84
|
assistant_message = AssistantMessage(
|
|
96
85
|
content=self.content,
|
|
97
86
|
name=assistant_message.name,
|
|
98
|
-
|
|
87
|
+
provider=assistant_message.provider,
|
|
99
88
|
model_id=assistant_message.model_id,
|
|
100
|
-
provider_model_name=assistant_message.provider_model_name,
|
|
101
89
|
raw_message=assistant_message.raw_message,
|
|
102
90
|
)
|
|
103
91
|
self.messages = list(input_messages) + [assistant_message]
|
|
@@ -20,12 +20,7 @@ from ..content import (
|
|
|
20
20
|
ToolCallEndChunk,
|
|
21
21
|
ToolCallStartChunk,
|
|
22
22
|
)
|
|
23
|
-
from ..formatting import
|
|
24
|
-
Format,
|
|
25
|
-
FormattableT,
|
|
26
|
-
Partial,
|
|
27
|
-
is_output_parser,
|
|
28
|
-
)
|
|
23
|
+
from ..formatting import Format, FormattableT, Partial
|
|
29
24
|
from ..messages import AssistantMessage, Message
|
|
30
25
|
from ..tools import FORMAT_TOOL_NAME, ToolkitT
|
|
31
26
|
from ..types import Jsonable
|
|
@@ -41,14 +36,9 @@ from .streams import (
|
|
|
41
36
|
ThoughtStream,
|
|
42
37
|
ToolCallStream,
|
|
43
38
|
)
|
|
44
|
-
from .usage import Usage, UsageDeltaChunk
|
|
45
39
|
|
|
46
40
|
if TYPE_CHECKING:
|
|
47
|
-
from ..
|
|
48
|
-
from ..providers import ModelId, ProviderId
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
StreamResponseT = TypeVar("StreamResponseT", bound="BaseStreamResponse[Any, Any, Any]")
|
|
41
|
+
from ..clients import ModelId, Params, Provider
|
|
52
42
|
|
|
53
43
|
|
|
54
44
|
@dataclass(kw_only=True)
|
|
@@ -86,11 +76,7 @@ class RawMessageChunk:
|
|
|
86
76
|
|
|
87
77
|
|
|
88
78
|
StreamResponseChunk: TypeAlias = (
|
|
89
|
-
AssistantContentChunk
|
|
90
|
-
| FinishReasonChunk
|
|
91
|
-
| RawStreamEventChunk
|
|
92
|
-
| RawMessageChunk
|
|
93
|
-
| UsageDeltaChunk
|
|
79
|
+
AssistantContentChunk | FinishReasonChunk | RawStreamEventChunk | RawMessageChunk
|
|
94
80
|
)
|
|
95
81
|
|
|
96
82
|
ChunkIterator: TypeAlias = Iterator[StreamResponseChunk]
|
|
@@ -171,39 +157,32 @@ class BaseStreamResponse(
|
|
|
171
157
|
def __init__(
|
|
172
158
|
self,
|
|
173
159
|
*,
|
|
174
|
-
|
|
160
|
+
provider: "Provider",
|
|
175
161
|
model_id: "ModelId",
|
|
176
|
-
provider_model_name: str,
|
|
177
162
|
params: "Params",
|
|
178
163
|
toolkit: ToolkitT,
|
|
179
164
|
format: Format[FormattableT] | None = None,
|
|
180
165
|
input_messages: Sequence[Message],
|
|
181
166
|
chunk_iterator: ChunkIteratorT,
|
|
182
|
-
usage: Usage | None = None,
|
|
183
167
|
) -> None:
|
|
184
168
|
"""Initialize the BaseStreamResponse.
|
|
185
169
|
|
|
186
170
|
Args:
|
|
187
|
-
provider: The provider name (e.g. "anthropic", "openai").
|
|
171
|
+
provider: The provider name (e.g. "anthropic", "openai:completions").
|
|
188
172
|
model_id: The model identifier that generated the response.
|
|
189
|
-
provider_model_name: Optional provider-specific model name. May include
|
|
190
|
-
provider-specific additional info (like api mode in "gpt-5:responses").
|
|
191
173
|
params: The params used to generate the response (or None).
|
|
192
174
|
toolkit: Toolkit containing all the tools used to generate the response.
|
|
193
175
|
format: The `Format` for the expected structured output format (or None).
|
|
194
176
|
input_messages: The input messages that were sent to the LLM
|
|
195
|
-
usage: Token usage statistics for the response.
|
|
196
177
|
|
|
197
178
|
The BaseStreamResponse will process the tuples to build the chunks and raw lists
|
|
198
179
|
as the stream is consumed.
|
|
199
180
|
"""
|
|
200
181
|
|
|
201
|
-
self.
|
|
182
|
+
self.provider = provider
|
|
202
183
|
self.model_id = model_id
|
|
203
|
-
self.provider_model_name = provider_model_name
|
|
204
184
|
self.params = params
|
|
205
185
|
self.toolkit = toolkit
|
|
206
|
-
self.usage = usage
|
|
207
186
|
self.format = format
|
|
208
187
|
|
|
209
188
|
# Internal-only lists which we mutate (append) during chunk processing
|
|
@@ -227,17 +206,15 @@ class BaseStreamResponse(
|
|
|
227
206
|
|
|
228
207
|
self._assistant_message = AssistantMessage(
|
|
229
208
|
content=self._content,
|
|
230
|
-
|
|
209
|
+
provider=provider,
|
|
231
210
|
model_id=model_id,
|
|
232
|
-
provider_model_name=provider_model_name,
|
|
233
211
|
raw_message=None,
|
|
234
212
|
)
|
|
235
213
|
|
|
236
214
|
self.messages = list(input_messages) + [self._assistant_message]
|
|
237
215
|
|
|
238
216
|
self._chunk_iterator = chunk_iterator
|
|
239
|
-
self._current_content: Text | Thought | None = None
|
|
240
|
-
self._current_tool_calls: dict[str, ToolCall] = {}
|
|
217
|
+
self._current_content: Text | Thought | ToolCall | None = None
|
|
241
218
|
|
|
242
219
|
self._processing_format_tool: bool = False
|
|
243
220
|
|
|
@@ -279,7 +256,7 @@ class BaseStreamResponse(
|
|
|
279
256
|
self, chunk: TextStartChunk | TextChunk | TextEndChunk
|
|
280
257
|
) -> None:
|
|
281
258
|
if chunk.type == "text_start_chunk":
|
|
282
|
-
if self._current_content
|
|
259
|
+
if self._current_content:
|
|
283
260
|
raise RuntimeError(
|
|
284
261
|
"Received text_start_chunk while processing another chunk"
|
|
285
262
|
)
|
|
@@ -302,7 +279,7 @@ class BaseStreamResponse(
|
|
|
302
279
|
self, chunk: ThoughtStartChunk | ThoughtChunk | ThoughtEndChunk
|
|
303
280
|
) -> None:
|
|
304
281
|
if chunk.type == "thought_start_chunk":
|
|
305
|
-
if self._current_content
|
|
282
|
+
if self._current_content:
|
|
306
283
|
raise RuntimeError(
|
|
307
284
|
"Received thought_start_chunk while processing another chunk"
|
|
308
285
|
)
|
|
@@ -333,38 +310,35 @@ class BaseStreamResponse(
|
|
|
333
310
|
raise RuntimeError(
|
|
334
311
|
"Received tool_call_start_chunk while processing another chunk"
|
|
335
312
|
)
|
|
336
|
-
|
|
337
|
-
raise RuntimeError("Got tool_call_start_chunk with conflicting id")
|
|
338
|
-
# Create a new tool call and track it by ID
|
|
339
|
-
# Multiple tool calls can be in progress simultaneously (interleaved)
|
|
340
|
-
tool_call = ToolCall(
|
|
313
|
+
self._current_content = ToolCall(
|
|
341
314
|
id=chunk.id,
|
|
342
315
|
name=chunk.name,
|
|
343
316
|
args="",
|
|
344
317
|
)
|
|
345
|
-
self._current_tool_calls[chunk.id] = tool_call
|
|
346
318
|
|
|
347
319
|
elif chunk.type == "tool_call_chunk":
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
320
|
+
if (
|
|
321
|
+
self._current_content is None
|
|
322
|
+
or self._current_content.type != "tool_call"
|
|
323
|
+
):
|
|
351
324
|
raise RuntimeError(
|
|
352
|
-
|
|
325
|
+
"Received tool_call_chunk while not processing tool call."
|
|
353
326
|
)
|
|
354
|
-
|
|
327
|
+
self._current_content.args += chunk.delta
|
|
355
328
|
|
|
356
329
|
elif chunk.type == "tool_call_end_chunk":
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
330
|
+
if (
|
|
331
|
+
self._current_content is None
|
|
332
|
+
or self._current_content.type != "tool_call"
|
|
333
|
+
):
|
|
360
334
|
raise RuntimeError(
|
|
361
|
-
|
|
335
|
+
"Received tool_call_end_chunk while not processing tool call."
|
|
362
336
|
)
|
|
363
|
-
if not
|
|
364
|
-
|
|
365
|
-
self._content.append(
|
|
366
|
-
self._tool_calls.append(
|
|
367
|
-
|
|
337
|
+
if not self._current_content.args:
|
|
338
|
+
self._current_content.args = "{}"
|
|
339
|
+
self._content.append(self._current_content)
|
|
340
|
+
self._tool_calls.append(self._current_content)
|
|
341
|
+
self._current_content = None
|
|
368
342
|
|
|
369
343
|
def _pretty_chunk(self, chunk: AssistantContentChunk, spacer: str) -> str:
|
|
370
344
|
match chunk.type:
|
|
@@ -496,14 +470,6 @@ class BaseSyncStreamResponse(BaseStreamResponse[ChunkIterator, ToolkitT, Formatt
|
|
|
496
470
|
self._assistant_message.raw_message = chunk.raw_message
|
|
497
471
|
elif chunk.type == "finish_reason_chunk":
|
|
498
472
|
self.finish_reason = chunk.finish_reason
|
|
499
|
-
elif chunk.type == "usage_delta_chunk":
|
|
500
|
-
if self.usage is None:
|
|
501
|
-
self.usage = Usage()
|
|
502
|
-
self.usage.input_tokens += chunk.input_tokens
|
|
503
|
-
self.usage.output_tokens += chunk.output_tokens
|
|
504
|
-
self.usage.cache_read_tokens += chunk.cache_read_tokens
|
|
505
|
-
self.usage.cache_write_tokens += chunk.cache_write_tokens
|
|
506
|
-
self.usage.reasoning_tokens += chunk.reasoning_tokens
|
|
507
473
|
else:
|
|
508
474
|
yield self._handle_chunk(chunk)
|
|
509
475
|
|
|
@@ -514,26 +480,6 @@ class BaseSyncStreamResponse(BaseStreamResponse[ChunkIterator, ToolkitT, Formatt
|
|
|
514
480
|
for _ in self.chunk_stream():
|
|
515
481
|
pass
|
|
516
482
|
|
|
517
|
-
def text_stream(self, sep: str = "\n") -> Iterator[str]:
|
|
518
|
-
"""Stream only the text content from the response.
|
|
519
|
-
|
|
520
|
-
Args:
|
|
521
|
-
sep: Separator to yield between text parts. Defaults to newline.
|
|
522
|
-
|
|
523
|
-
Returns:
|
|
524
|
-
Iterator[str]: Iterator yielding text delta strings
|
|
525
|
-
|
|
526
|
-
Yields text deltas as they arrive, ignoring thoughts, tool calls, and other
|
|
527
|
-
content types. Ideal for displaying text to users in real-time.
|
|
528
|
-
|
|
529
|
-
If you concatenate the strings from `.text_stream()`, it will be equivalent to
|
|
530
|
-
calling `.text(sep=sep)` on the fully consumed response.
|
|
531
|
-
"""
|
|
532
|
-
for stream in self.streams():
|
|
533
|
-
if stream.content_type == "text":
|
|
534
|
-
yield from stream
|
|
535
|
-
yield sep
|
|
536
|
-
|
|
537
483
|
def pretty_stream(self) -> Iterator[str]:
|
|
538
484
|
"""Stream a readable representation of the stream_response as text.
|
|
539
485
|
|
|
@@ -556,46 +502,26 @@ class BaseSyncStreamResponse(BaseStreamResponse[ChunkIterator, ToolkitT, Formatt
|
|
|
556
502
|
printed = True
|
|
557
503
|
yield pretty
|
|
558
504
|
|
|
505
|
+
if not printed:
|
|
506
|
+
yield "**[No Content]**"
|
|
507
|
+
|
|
559
508
|
def structured_stream(
|
|
560
509
|
self,
|
|
561
510
|
) -> Iterator[Partial[FormattableT]]:
|
|
562
|
-
"""
|
|
511
|
+
"""Returns an iterator that yields partial structured objects as content streams.
|
|
563
512
|
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
Partial[FormattableT] with optional fields that may be None until fully received.
|
|
513
|
+
Returns:
|
|
514
|
+
Iterator[Partial[FormatT]]: Synchronous iterator yielding partial structured objects
|
|
567
515
|
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
>>> book = response.parse() # Get final complete result
|
|
516
|
+
This method yields Partial[FormatT] objects as the response content is streamed,
|
|
517
|
+
allowing you to access partial structured data before the response is fully complete.
|
|
518
|
+
Each yielded object represents the current state of the parsed structure with all
|
|
519
|
+
fields optional.
|
|
573
520
|
|
|
574
521
|
Fully iterating through this iterator will fully consume the underlying stream,
|
|
575
522
|
updating the Response with all collected content.
|
|
576
|
-
|
|
577
|
-
Yields:
|
|
578
|
-
Partial[FormattableT]: Partial objects with fields populated as they arrive.
|
|
579
|
-
Fields not yet received will be None.
|
|
580
|
-
|
|
581
|
-
Raises:
|
|
582
|
-
ValueError: If format parameter not set.
|
|
583
|
-
NotImplementedError: If format uses OutputParser (not supported).
|
|
584
523
|
"""
|
|
585
|
-
|
|
586
|
-
raise ValueError("structured_stream() requires format parameter")
|
|
587
|
-
|
|
588
|
-
if is_output_parser(self.format.formattable):
|
|
589
|
-
raise NotImplementedError(
|
|
590
|
-
"structured_stream() not supported for OutputParser. "
|
|
591
|
-
"Use BaseModel or primitive types."
|
|
592
|
-
)
|
|
593
|
-
|
|
594
|
-
for chunk in self.chunk_stream():
|
|
595
|
-
if chunk.type == "text_chunk":
|
|
596
|
-
partial = self.parse(partial=True)
|
|
597
|
-
if partial:
|
|
598
|
-
yield partial
|
|
524
|
+
raise NotImplementedError()
|
|
599
525
|
|
|
600
526
|
|
|
601
527
|
class BaseAsyncStreamResponse(
|
|
@@ -717,14 +643,6 @@ class BaseAsyncStreamResponse(
|
|
|
717
643
|
self._assistant_message.raw_message = chunk.raw_message
|
|
718
644
|
elif chunk.type == "finish_reason_chunk":
|
|
719
645
|
self.finish_reason = chunk.finish_reason
|
|
720
|
-
elif chunk.type == "usage_delta_chunk":
|
|
721
|
-
if self.usage is None:
|
|
722
|
-
self.usage = Usage()
|
|
723
|
-
self.usage.input_tokens += chunk.input_tokens
|
|
724
|
-
self.usage.output_tokens += chunk.output_tokens
|
|
725
|
-
self.usage.cache_read_tokens += chunk.cache_read_tokens
|
|
726
|
-
self.usage.cache_write_tokens += chunk.cache_write_tokens
|
|
727
|
-
self.usage.reasoning_tokens += chunk.reasoning_tokens
|
|
728
646
|
else:
|
|
729
647
|
yield self._handle_chunk(chunk)
|
|
730
648
|
|
|
@@ -735,27 +653,6 @@ class BaseAsyncStreamResponse(
|
|
|
735
653
|
async for _ in self.chunk_stream():
|
|
736
654
|
pass
|
|
737
655
|
|
|
738
|
-
async def text_stream(self, sep: str = "\n") -> AsyncIterator[str]:
|
|
739
|
-
"""Stream only the text content from the response.
|
|
740
|
-
|
|
741
|
-
Args:
|
|
742
|
-
sep: Separator to yield between text parts. Defaults to newline.
|
|
743
|
-
|
|
744
|
-
Returns:
|
|
745
|
-
AsyncIterator[str]: Async iterator yielding text delta strings
|
|
746
|
-
|
|
747
|
-
Yields text deltas as they arrive, ignoring thoughts, tool calls, and other
|
|
748
|
-
content types. Ideal for displaying text to users in real-time.
|
|
749
|
-
|
|
750
|
-
If you concatenate the strings from `.text_stream()`, it will be equivalent to
|
|
751
|
-
calling `.text(sep=sep)` on the fully consumed response.
|
|
752
|
-
"""
|
|
753
|
-
async for stream in self.streams():
|
|
754
|
-
if stream.content_type == "text":
|
|
755
|
-
async for delta in stream:
|
|
756
|
-
yield delta
|
|
757
|
-
yield sep
|
|
758
|
-
|
|
759
656
|
async def pretty_stream(self) -> AsyncIterator[str]:
|
|
760
657
|
"""Stream a readable representation of the stream_response as text.
|
|
761
658
|
|
|
@@ -778,43 +675,23 @@ class BaseAsyncStreamResponse(
|
|
|
778
675
|
printed = True
|
|
779
676
|
yield pretty
|
|
780
677
|
|
|
781
|
-
|
|
678
|
+
if not printed:
|
|
679
|
+
yield "**[No Content]**"
|
|
680
|
+
|
|
681
|
+
def structured_stream(
|
|
782
682
|
self,
|
|
783
683
|
) -> AsyncIterator[Partial[FormattableT]]:
|
|
784
|
-
"""
|
|
684
|
+
"""Returns an async iterator that yields partial structured objects as content streams.
|
|
785
685
|
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
Partial[FormattableT] with optional fields that may be None until fully received.
|
|
686
|
+
Returns:
|
|
687
|
+
AsyncIterator[Partial[FormatT]]: Async iterator yielding partial structured objects
|
|
789
688
|
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
>>> book = response.parse() # Get final complete result
|
|
689
|
+
This method yields Partial[FormatT] objects as the response content is streamed,
|
|
690
|
+
allowing you to access partial structured data before the response is fully complete.
|
|
691
|
+
Each yielded object represents the current state of the parsed structure with all
|
|
692
|
+
fields optional.
|
|
795
693
|
|
|
796
694
|
Fully iterating through this iterator will fully consume the underlying stream,
|
|
797
695
|
updating the Response with all collected content.
|
|
798
|
-
|
|
799
|
-
Yields:
|
|
800
|
-
Partial[FormattableT]: Partial objects with fields populated as they arrive.
|
|
801
|
-
Fields not yet received will be None.
|
|
802
|
-
|
|
803
|
-
Raises:
|
|
804
|
-
ValueError: If format parameter not set.
|
|
805
|
-
NotImplementedError: If format uses OutputParser (not supported).
|
|
806
696
|
"""
|
|
807
|
-
|
|
808
|
-
raise ValueError("structured_stream() requires format parameter")
|
|
809
|
-
|
|
810
|
-
if is_output_parser(self.format.formattable):
|
|
811
|
-
raise NotImplementedError(
|
|
812
|
-
"structured_stream() not supported for OutputParser. "
|
|
813
|
-
"Use BaseModel or primitive types."
|
|
814
|
-
)
|
|
815
|
-
|
|
816
|
-
async for chunk in self.chunk_stream():
|
|
817
|
-
if chunk.type == "text_chunk":
|
|
818
|
-
partial = self.parse(partial=True)
|
|
819
|
-
if partial:
|
|
820
|
-
yield partial
|
|
697
|
+
raise NotImplementedError()
|