payi 0.1.0a83__tar.gz → 0.1.0a85__tar.gz
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.
Potentially problematic release.
This version of payi might be problematic. Click here for more details.
- payi-0.1.0a85/.release-please-manifest.json +3 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/CHANGELOG.md +17 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/PKG-INFO +1 -1
- {payi-0.1.0a83 → payi-0.1.0a85}/api.md +6 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/pyproject.toml +1 -1
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_version.py +1 -1
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/lib/AnthropicInstrumentor.py +111 -70
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/lib/BedrockInstrumentor.py +83 -100
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/lib/GoogleGenAiInstrumentor.py +26 -111
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/lib/VertexInstrumentor.py +132 -98
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/lib/instrument.py +52 -15
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/categories/__init__.py +14 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/categories/categories.py +32 -0
- payi-0.1.0a85/src/payi/resources/categories/fixed_cost_resources.py +196 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/ingest.py +14 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/limits/limits.py +4 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/categories/__init__.py +1 -0
- payi-0.1.0a85/src/payi/types/categories/fixed_cost_resource_create_params.py +21 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/ingest_event_param.py +13 -1
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/ingest_units_params.py +11 -1
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/limit_create_params.py +2 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/limit_history_response.py +3 -3
- payi-0.1.0a85/tests/api_resources/categories/test_fixed_cost_resources.py +151 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/test_ingest.py +32 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/test_limits.py +2 -0
- payi-0.1.0a83/.release-please-manifest.json +0 -3
- {payi-0.1.0a83 → payi-0.1.0a85}/.gitignore +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/CONTRIBUTING.md +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/LICENSE +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/README.md +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/SECURITY.md +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/bin/check-release-environment +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/bin/publish-pypi +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/examples/.keep +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/mypy.ini +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/noxfile.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/release-please-config.json +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/requirements-dev.lock +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/requirements.lock +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/__init__.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_base_client.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_client.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_compat.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_constants.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_exceptions.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_files.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_models.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_qs.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_resource.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_response.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_streaming.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_types.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_utils/__init__.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_utils/_logs.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_utils/_proxy.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_utils/_reflection.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_utils/_resources_proxy.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_utils/_streams.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_utils/_sync.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_utils/_transform.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_utils/_typing.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/_utils/_utils.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/lib/.keep +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/lib/OpenAIInstrumentor.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/lib/Stopwatch.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/lib/helpers.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/pagination.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/py.typed +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/__init__.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/categories/resources.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/experiences/__init__.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/experiences/experiences.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/experiences/properties.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/experiences/types/__init__.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/experiences/types/limit_config.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/experiences/types/types.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/limits/__init__.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/limits/tags.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/requests/__init__.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/requests/properties.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/requests/requests.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/requests/result.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/use_cases/__init__.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/use_cases/definitions/__init__.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/use_cases/definitions/definitions.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/use_cases/definitions/kpis.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/use_cases/definitions/limit_config.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/use_cases/definitions/version.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/use_cases/kpis.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/use_cases/properties.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/resources/use_cases/use_cases.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/__init__.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/bulk_ingest_response.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/categories/resource_create_params.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/categories/resource_list_params.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/category_delete_resource_response.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/category_delete_response.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/category_list_params.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/category_list_resources_params.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/category_resource_response.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/category_response.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/cost_data.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/cost_details.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/default_response.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/experience_instance_response.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/experiences/__init__.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/experiences/experience_type.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/experiences/property_create_params.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/experiences/type_create_params.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/experiences/type_list_params.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/experiences/type_update_params.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/experiences/types/__init__.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/experiences/types/limit_config_create_params.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/ingest_bulk_params.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/ingest_response.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/limit_list_params.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/limit_list_response.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/limit_reset_params.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/limit_response.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/limit_update_params.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/limits/__init__.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/limits/limit_tags.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/limits/tag_create_params.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/limits/tag_create_response.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/limits/tag_delete_response.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/limits/tag_list_response.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/limits/tag_remove_params.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/limits/tag_remove_response.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/limits/tag_update_params.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/limits/tag_update_response.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/pay_i_common_models_api_router_header_info_param.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/requests/__init__.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/requests/property_create_params.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/requests/request_result.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/requests_data.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/shared/__init__.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/shared/evaluation_response.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/shared/ingest_units.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/shared/pay_i_common_models_budget_management_cost_details_base.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/shared/pay_i_common_models_budget_management_create_limit_base.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/shared/properties_response.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/shared/xproxy_error.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/shared/xproxy_result.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/shared_params/__init__.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/shared_params/ingest_units.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/shared_params/pay_i_common_models_budget_management_create_limit_base.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/total_cost_data.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_case_instance_response.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/__init__.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/definition_create_params.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/definition_list_params.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/definition_update_params.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/definitions/__init__.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/definitions/kpi_create_params.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/definitions/kpi_create_response.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/definitions/kpi_delete_response.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/definitions/kpi_list_params.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/definitions/kpi_list_response.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/definitions/kpi_retrieve_response.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/definitions/kpi_update_params.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/definitions/kpi_update_response.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/definitions/limit_config_create_params.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/kpi_create_params.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/kpi_list_params.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/kpi_list_response.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/kpi_update_params.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/property_create_params.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/src/payi/types/use_cases/use_case_definition.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/__init__.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/__init__.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/categories/__init__.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/categories/test_resources.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/experiences/__init__.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/experiences/test_properties.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/experiences/test_types.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/experiences/types/__init__.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/experiences/types/test_limit_config.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/limits/__init__.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/limits/test_tags.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/requests/__init__.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/requests/test_properties.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/requests/test_result.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/test_categories.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/test_experiences.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/test_use_cases.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/use_cases/__init__.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/use_cases/definitions/__init__.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/use_cases/definitions/test_kpis.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/use_cases/definitions/test_limit_config.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/use_cases/definitions/test_version.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/use_cases/test_definitions.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/use_cases/test_kpis.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/api_resources/use_cases/test_properties.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/conftest.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/sample_file.txt +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/test_client.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/test_deepcopy.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/test_extract_files.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/test_files.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/test_models.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/test_qs.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/test_required_args.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/test_response.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/test_streaming.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/test_transform.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/test_utils/test_proxy.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/test_utils/test_typing.py +0 -0
- {payi-0.1.0a83 → payi-0.1.0a85}/tests/utils.py +0 -0
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.0-alpha.85 (2025-06-12)
|
|
4
|
+
|
|
5
|
+
Full Changelog: [v0.1.0-alpha.84...v0.1.0-alpha.85](https://github.com/Pay-i/pay-i-python/compare/v0.1.0-alpha.84...v0.1.0-alpha.85)
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
* AnthropicBedrock ([#320](https://github.com/Pay-i/pay-i-python/issues/320)) ([33b42e3](https://github.com/Pay-i/pay-i-python/commit/33b42e38d7ba3245e0633254b4401cf991937933))
|
|
10
|
+
|
|
11
|
+
## 0.1.0-alpha.84 (2025-06-09)
|
|
12
|
+
|
|
13
|
+
Full Changelog: [v0.1.0-alpha.83...v0.1.0-alpha.84](https://github.com/Pay-i/pay-i-python/compare/v0.1.0-alpha.83...v0.1.0-alpha.84)
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
* **api:** manual updates ([b5edce3](https://github.com/Pay-i/pay-i-python/commit/b5edce3207c9cd01ded791e67b8cc0bbf5ef4ef4))
|
|
18
|
+
* consolidate anthropic vision, google.genai and vertex compute usage ([#318](https://github.com/Pay-i/pay-i-python/issues/318)) ([28700fd](https://github.com/Pay-i/pay-i-python/commit/28700fd25e76b03e06f9cb7c963890dbb1675f2b))
|
|
19
|
+
|
|
3
20
|
## 0.1.0-alpha.83 (2025-06-06)
|
|
4
21
|
|
|
5
22
|
Full Changelog: [v0.1.0-alpha.82...v0.1.0-alpha.83](https://github.com/Pay-i/pay-i-python/compare/v0.1.0-alpha.82...v0.1.0-alpha.83)
|
|
@@ -108,6 +108,12 @@ Methods:
|
|
|
108
108
|
- <code title="get /api/v1/categories/{category}/resources/{resource}">client.categories.resources.<a href="./src/payi/resources/categories/resources.py">list</a>(resource, \*, category, \*\*<a href="src/payi/types/categories/resource_list_params.py">params</a>) -> <a href="./src/payi/types/category_resource_response.py">SyncCursorPage[CategoryResourceResponse]</a></code>
|
|
109
109
|
- <code title="delete /api/v1/categories/{category}/resources/{resource}/{resource_id}">client.categories.resources.<a href="./src/payi/resources/categories/resources.py">delete</a>(resource_id, \*, category, resource) -> <a href="./src/payi/types/category_resource_response.py">CategoryResourceResponse</a></code>
|
|
110
110
|
|
|
111
|
+
## FixedCostResources
|
|
112
|
+
|
|
113
|
+
Methods:
|
|
114
|
+
|
|
115
|
+
- <code title="post /api/v1/categories/{category}/fixed_cost_resources/{resource}">client.categories.fixed_cost_resources.<a href="./src/payi/resources/categories/fixed_cost_resources.py">create</a>(resource, \*, category, \*\*<a href="src/payi/types/categories/fixed_cost_resource_create_params.py">params</a>) -> <a href="./src/payi/types/category_resource_response.py">CategoryResourceResponse</a></code>
|
|
116
|
+
|
|
111
117
|
# Experiences
|
|
112
118
|
|
|
113
119
|
Types:
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import json
|
|
1
2
|
from typing import Any, Union, Optional, Sequence
|
|
2
3
|
from typing_extensions import override
|
|
3
4
|
|
|
@@ -17,6 +18,12 @@ class AnthropicInstrumentor:
|
|
|
17
18
|
|
|
18
19
|
return isinstance(instance._client, (AsyncAnthropicVertex, AnthropicVertex))
|
|
19
20
|
|
|
21
|
+
@staticmethod
|
|
22
|
+
def is_bedrock(instance: Any) -> bool:
|
|
23
|
+
from anthropic import AnthropicBedrock, AsyncAnthropicBedrock # type: ignore # noqa: I001
|
|
24
|
+
|
|
25
|
+
return isinstance(instance._client, (AsyncAnthropicBedrock, AnthropicBedrock))
|
|
26
|
+
|
|
20
27
|
@staticmethod
|
|
21
28
|
def instrument(instrumentor: _PayiInstrumentor) -> None:
|
|
22
29
|
try:
|
|
@@ -125,94 +132,46 @@ async def astream_messages_wrapper(
|
|
|
125
132
|
|
|
126
133
|
class _AnthropicProviderRequest(_ProviderRequest):
|
|
127
134
|
def __init__(self, instrumentor: _PayiInstrumentor, streaming_type: _StreamingType, instance: Any = None) -> None:
|
|
128
|
-
self.
|
|
135
|
+
self._is_vertex: bool = AnthropicInstrumentor.is_vertex(instance)
|
|
136
|
+
self._is_bedrock: bool = AnthropicInstrumentor.is_bedrock(instance)
|
|
137
|
+
|
|
138
|
+
category: str = ""
|
|
139
|
+
if self._is_vertex:
|
|
140
|
+
category = PayiCategories.google_vertex
|
|
141
|
+
elif self._is_bedrock:
|
|
142
|
+
category = PayiCategories.aws_bedrock
|
|
143
|
+
else:
|
|
144
|
+
category = PayiCategories.anthropic
|
|
145
|
+
|
|
146
|
+
instrumentor._logger.debug(f"Anthropic messages instrumenting category {category}")
|
|
147
|
+
|
|
129
148
|
super().__init__(
|
|
130
149
|
instrumentor=instrumentor,
|
|
131
|
-
category=
|
|
150
|
+
category=category,
|
|
132
151
|
streaming_type=streaming_type,
|
|
133
152
|
)
|
|
134
153
|
|
|
135
154
|
@override
|
|
136
155
|
def process_chunk(self, chunk: Any) -> _ChunkResult:
|
|
137
|
-
|
|
138
|
-
if chunk.type == "message_start":
|
|
139
|
-
self._ingest["provider_response_id"] = chunk.message.id
|
|
140
|
-
|
|
141
|
-
usage = chunk.message.usage
|
|
142
|
-
units = self._ingest["units"]
|
|
143
|
-
|
|
144
|
-
input = _PayiInstrumentor.update_for_vision(usage.input_tokens, units, self._estimated_prompt_tokens)
|
|
145
|
-
|
|
146
|
-
units["text"] = Units(input=input, output=0)
|
|
147
|
-
|
|
148
|
-
if hasattr(usage, "cache_creation_input_tokens") and usage.cache_creation_input_tokens > 0:
|
|
149
|
-
text_cache_write = usage.cache_creation_input_tokens
|
|
150
|
-
units["text_cache_write"] = Units(input=text_cache_write, output=0)
|
|
151
|
-
|
|
152
|
-
if hasattr(usage, "cache_read_input_tokens") and usage.cache_read_input_tokens > 0:
|
|
153
|
-
text_cache_read = usage.cache_read_input_tokens
|
|
154
|
-
units["text_cache_read"] = Units(input=text_cache_read, output=0)
|
|
155
|
-
|
|
156
|
-
elif chunk.type == "message_delta":
|
|
157
|
-
usage = chunk.usage
|
|
158
|
-
ingest = True
|
|
159
|
-
|
|
160
|
-
# Web search will return an updated input tokens value at the end of streaming
|
|
161
|
-
if usage.input_tokens > 0:
|
|
162
|
-
self._ingest["units"]["text"]["input"] = usage.input_tokens
|
|
163
|
-
|
|
164
|
-
self._ingest["units"]["text"]["output"] = usage.output_tokens
|
|
165
|
-
|
|
166
|
-
return _ChunkResult(send_chunk_to_caller=True, ingest=ingest)
|
|
156
|
+
return anthropic_process_chunk(self, chunk.to_dict(), assign_id=True)
|
|
167
157
|
|
|
168
158
|
@override
|
|
169
159
|
def process_synchronous_response(self, response: Any, log_prompt_and_response: bool, kwargs: Any) -> Any:
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
if hasattr(usage, "cache_creation_input_tokens") and usage.cache_creation_input_tokens > 0:
|
|
176
|
-
text_cache_write = usage.cache_creation_input_tokens
|
|
177
|
-
units["text_cache_write"] = Units(input=text_cache_write, output=0)
|
|
178
|
-
|
|
179
|
-
if hasattr(usage, "cache_read_input_tokens") and usage.cache_read_input_tokens > 0:
|
|
180
|
-
text_cache_read = usage.cache_read_input_tokens
|
|
181
|
-
units["text_cache_read"] = Units(input=text_cache_read, output=0)
|
|
160
|
+
anthropic_process_synchronous_response(
|
|
161
|
+
request=self,
|
|
162
|
+
response=response.to_dict(),
|
|
163
|
+
log_prompt_and_response=log_prompt_and_response,
|
|
164
|
+
assign_id=True)
|
|
182
165
|
|
|
183
|
-
input = _PayiInstrumentor.update_for_vision(input, units, self._estimated_prompt_tokens)
|
|
184
|
-
|
|
185
|
-
units["text"] = Units(input=input, output=output)
|
|
186
|
-
|
|
187
|
-
if log_prompt_and_response:
|
|
188
|
-
self._ingest["provider_response_json"] = response.to_json()
|
|
189
|
-
|
|
190
|
-
self._ingest["provider_response_id"] = response.id
|
|
191
|
-
|
|
192
166
|
return None
|
|
193
167
|
|
|
194
168
|
@override
|
|
195
169
|
def process_request(self, instance: Any, extra_headers: 'dict[str, str]', args: Sequence[Any], kwargs: Any) -> bool:
|
|
196
|
-
self._ingest["resource"] = ("anthropic." if self.
|
|
170
|
+
self._ingest["resource"] = ("anthropic." if self._is_vertex else "") + kwargs.get("model", "")
|
|
197
171
|
|
|
198
172
|
messages = kwargs.get("messages")
|
|
199
173
|
if messages:
|
|
200
|
-
|
|
201
|
-
has_image = False
|
|
202
|
-
|
|
203
|
-
try:
|
|
204
|
-
enc = tiktoken.get_encoding("cl100k_base")
|
|
205
|
-
for message in messages:
|
|
206
|
-
msg_has_image, msg_prompt_tokens = has_image_and_get_texts(enc, message.get('content', ''))
|
|
207
|
-
if msg_has_image:
|
|
208
|
-
has_image = True
|
|
209
|
-
estimated_token_count += msg_prompt_tokens
|
|
210
|
-
|
|
211
|
-
if has_image and estimated_token_count > 0:
|
|
212
|
-
self._estimated_prompt_tokens = estimated_token_count
|
|
213
|
-
|
|
214
|
-
except Exception:
|
|
215
|
-
self._instrumentor._logger.warning("Error getting encoding for cl100k_base")
|
|
174
|
+
anthropic_has_image_and_get_texts(self, messages)
|
|
216
175
|
|
|
217
176
|
return True
|
|
218
177
|
|
|
@@ -248,6 +207,88 @@ class _AnthropicProviderRequest(_ProviderRequest):
|
|
|
248
207
|
|
|
249
208
|
return True
|
|
250
209
|
|
|
210
|
+
def anthropic_process_synchronous_response(request: _ProviderRequest, response: 'dict[str, Any]', log_prompt_and_response: bool, assign_id: bool) -> Any:
|
|
211
|
+
usage = response['usage']
|
|
212
|
+
input = usage['input_tokens']
|
|
213
|
+
output = usage['output_tokens']
|
|
214
|
+
units: dict[str, Units] = request._ingest["units"]
|
|
215
|
+
|
|
216
|
+
cache_creation_input_tokens = usage.get("cache_creation_input_tokens", 0)
|
|
217
|
+
if cache_creation_input_tokens > 0:
|
|
218
|
+
units["text_cache_write"] = Units(input=cache_creation_input_tokens, output=0)
|
|
219
|
+
|
|
220
|
+
cache_read_input_tokens = usage.get("cache_read_input_tokens", 0)
|
|
221
|
+
if cache_read_input_tokens > 0:
|
|
222
|
+
units["text_cache_read"] = Units(input=cache_read_input_tokens, output=0)
|
|
223
|
+
|
|
224
|
+
input = _PayiInstrumentor.update_for_vision(input, units, request._estimated_prompt_tokens)
|
|
225
|
+
|
|
226
|
+
units["text"] = Units(input=input, output=output)
|
|
227
|
+
|
|
228
|
+
if log_prompt_and_response:
|
|
229
|
+
request._ingest["provider_response_json"] = json.dumps(response)
|
|
230
|
+
|
|
231
|
+
if assign_id:
|
|
232
|
+
request._ingest["provider_response_id"] = response.get('id', None)
|
|
233
|
+
|
|
234
|
+
return None
|
|
235
|
+
|
|
236
|
+
def anthropic_process_chunk(request: _ProviderRequest, chunk: 'dict[str, Any]', assign_id: bool) -> _ChunkResult:
|
|
237
|
+
ingest = False
|
|
238
|
+
type = chunk.get('type', "")
|
|
239
|
+
|
|
240
|
+
if type == "message_start":
|
|
241
|
+
message = chunk['message']
|
|
242
|
+
|
|
243
|
+
if assign_id:
|
|
244
|
+
request._ingest["provider_response_id"] = message.get('id', None)
|
|
245
|
+
|
|
246
|
+
usage = message['usage']
|
|
247
|
+
units = request._ingest["units"]
|
|
248
|
+
|
|
249
|
+
input = _PayiInstrumentor.update_for_vision(usage['input_tokens'], units, request._estimated_prompt_tokens)
|
|
250
|
+
|
|
251
|
+
units["text"] = Units(input=input, output=0)
|
|
252
|
+
|
|
253
|
+
text_cache_write: int = usage.get("cache_creation_input_tokens", 0)
|
|
254
|
+
if text_cache_write > 0:
|
|
255
|
+
units["text_cache_write"] = Units(input=text_cache_write, output=0)
|
|
256
|
+
|
|
257
|
+
text_cache_read: int = usage.get("cache_read_input_tokens", 0)
|
|
258
|
+
if text_cache_read > 0:
|
|
259
|
+
units["text_cache_read"] = Units(input=text_cache_read, output=0)
|
|
260
|
+
|
|
261
|
+
elif type == "message_delta":
|
|
262
|
+
usage = chunk.get('usage', {})
|
|
263
|
+
ingest = True
|
|
264
|
+
|
|
265
|
+
# Web search will return an updated input tokens value at the end of streaming
|
|
266
|
+
input_tokens = usage.get('input_tokens', None)
|
|
267
|
+
if input_tokens is not None:
|
|
268
|
+
request._ingest["units"]["text"]["input"] = input_tokens
|
|
269
|
+
|
|
270
|
+
request._ingest["units"]["text"]["output"] = usage.get('output_tokens', 0)
|
|
271
|
+
|
|
272
|
+
return _ChunkResult(send_chunk_to_caller=True, ingest=ingest)
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
def anthropic_has_image_and_get_texts(request: _ProviderRequest, messages: Any) -> None:
|
|
276
|
+
estimated_token_count = 0
|
|
277
|
+
has_image = False
|
|
278
|
+
|
|
279
|
+
try:
|
|
280
|
+
enc = tiktoken.get_encoding("cl100k_base")
|
|
281
|
+
for message in messages:
|
|
282
|
+
msg_has_image, msg_prompt_tokens = has_image_and_get_texts(enc, message.get('content', ''))
|
|
283
|
+
if msg_has_image:
|
|
284
|
+
has_image = True
|
|
285
|
+
estimated_token_count += msg_prompt_tokens
|
|
286
|
+
|
|
287
|
+
if has_image and estimated_token_count > 0:
|
|
288
|
+
request._estimated_prompt_tokens = estimated_token_count
|
|
289
|
+
|
|
290
|
+
except Exception:
|
|
291
|
+
request._instrumentor._logger.warning("Error getting encoding for cl100k_base")
|
|
251
292
|
|
|
252
293
|
def has_image_and_get_texts(encoding: tiktoken.Encoding, content: Union[str, 'list[Any]']) -> 'tuple[bool, int]':
|
|
253
294
|
if isinstance(content, list): # type: ignore
|
|
@@ -7,12 +7,11 @@ from typing_extensions import override
|
|
|
7
7
|
from wrapt import ObjectProxy, wrap_function_wrapper # type: ignore
|
|
8
8
|
|
|
9
9
|
from payi.lib.helpers import PayiCategories, PayiHeaderNames, payi_aws_bedrock_url
|
|
10
|
-
from payi.types.ingest_units_params import Units
|
|
10
|
+
from payi.types.ingest_units_params import Units
|
|
11
11
|
from payi.types.pay_i_common_models_api_router_header_info_param import PayICommonModelsAPIRouterHeaderInfoParam
|
|
12
12
|
|
|
13
13
|
from .instrument import _ChunkResult, _IsStreaming, _StreamingType, _ProviderRequest, _PayiInstrumentor
|
|
14
14
|
|
|
15
|
-
_supported_model_prefixes = ["meta.llama3", "anthropic.", "amazon.nova-pro", "amazon.nova-lite", "amazon.nova-micro"]
|
|
16
15
|
|
|
17
16
|
class BedrockInstrumentor:
|
|
18
17
|
_instrumentor: _PayiInstrumentor
|
|
@@ -100,15 +99,13 @@ class InvokeResponseWrapper(ObjectProxy): # type: ignore
|
|
|
100
99
|
def __init__(
|
|
101
100
|
self,
|
|
102
101
|
response: Any,
|
|
103
|
-
|
|
104
|
-
ingest: IngestUnitsParams,
|
|
102
|
+
request: '_BedrockInvokeProviderRequest',
|
|
105
103
|
log_prompt_and_response: bool
|
|
106
104
|
) -> None:
|
|
107
105
|
|
|
108
106
|
super().__init__(response) # type: ignore
|
|
109
107
|
self._response = response
|
|
110
|
-
self.
|
|
111
|
-
self._ingest = ingest
|
|
108
|
+
self._request = request
|
|
112
109
|
self._log_prompt_and_response = log_prompt_and_response
|
|
113
110
|
|
|
114
111
|
def read(self, amt: Any =None) -> Any: # type: ignore
|
|
@@ -116,51 +113,50 @@ class InvokeResponseWrapper(ObjectProxy): # type: ignore
|
|
|
116
113
|
data: bytes = self.__wrapped__.read(amt) # type: ignore
|
|
117
114
|
response = json.loads(data) # type: ignore
|
|
118
115
|
|
|
119
|
-
|
|
116
|
+
ingest = self._request._ingest
|
|
117
|
+
|
|
118
|
+
resource = ingest["resource"]
|
|
120
119
|
if not resource:
|
|
121
120
|
return
|
|
122
121
|
|
|
123
122
|
input: int = 0
|
|
124
123
|
output: int = 0
|
|
125
|
-
units: dict[str, Units] =
|
|
124
|
+
units: dict[str, Units] = ingest["units"]
|
|
125
|
+
|
|
126
|
+
if self._request._is_anthropic:
|
|
127
|
+
from .AnthropicInstrumentor import anthropic_process_synchronous_response
|
|
126
128
|
|
|
127
|
-
|
|
129
|
+
anthropic_process_synchronous_response(
|
|
130
|
+
request=self._request,
|
|
131
|
+
response=response,
|
|
132
|
+
log_prompt_and_response=False, # will evaluate logging later
|
|
133
|
+
assign_id=False)
|
|
134
|
+
|
|
135
|
+
elif resource.startswith("meta.llama3"):
|
|
128
136
|
input = response['prompt_token_count']
|
|
129
137
|
output = response['generation_token_count']
|
|
130
|
-
|
|
131
|
-
usage = response['usage']
|
|
132
|
-
input = usage['input_tokens']
|
|
133
|
-
output = usage['output_tokens']
|
|
134
|
-
units["text"] = Units(input=input, output=output)
|
|
138
|
+
units["text"] = Units(input=input, output=output)
|
|
135
139
|
|
|
136
140
|
if self._log_prompt_and_response:
|
|
137
|
-
|
|
141
|
+
ingest["provider_response_json"] = data.decode('utf-8') # type: ignore
|
|
138
142
|
|
|
139
|
-
self._instrumentor._ingest_units(
|
|
143
|
+
self._request._instrumentor._ingest_units(ingest)
|
|
140
144
|
|
|
141
145
|
return data # type: ignore
|
|
142
146
|
|
|
143
|
-
def _is_supported_model(modelId: str) -> bool:
|
|
144
|
-
return any(prefix in modelId for prefix in _supported_model_prefixes)
|
|
145
|
-
|
|
146
147
|
def wrap_invoke(instrumentor: _PayiInstrumentor, wrapped: Any) -> Any:
|
|
147
148
|
@wraps(wrapped)
|
|
148
149
|
def invoke_wrapper(*args: Any, **kwargs: 'dict[str, Any]') -> Any:
|
|
149
150
|
modelId:str = kwargs.get("modelId", "") # type: ignore
|
|
150
151
|
|
|
151
|
-
|
|
152
|
-
instrumentor
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
kwargs,
|
|
160
|
-
)
|
|
161
|
-
|
|
162
|
-
instrumentor._logger.debug(f"bedrock invoke wrapper, unsupported modelId: {modelId}")
|
|
163
|
-
return wrapped(*args, **kwargs)
|
|
152
|
+
return instrumentor.invoke_wrapper(
|
|
153
|
+
_BedrockInvokeProviderRequest(instrumentor=instrumentor, model_id=modelId),
|
|
154
|
+
_IsStreaming.false,
|
|
155
|
+
wrapped,
|
|
156
|
+
None,
|
|
157
|
+
args,
|
|
158
|
+
kwargs,
|
|
159
|
+
)
|
|
164
160
|
|
|
165
161
|
return invoke_wrapper
|
|
166
162
|
|
|
@@ -169,18 +165,15 @@ def wrap_invoke_stream(instrumentor: _PayiInstrumentor, wrapped: Any) -> Any:
|
|
|
169
165
|
def invoke_wrapper(*args: Any, **kwargs: Any) -> Any:
|
|
170
166
|
modelId: str = kwargs.get("modelId", "") # type: ignore
|
|
171
167
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
)
|
|
182
|
-
instrumentor._logger.debug(f"bedrock invoke stream wrapper, unsupported modelId: {modelId}")
|
|
183
|
-
return wrapped(*args, **kwargs)
|
|
168
|
+
instrumentor._logger.debug(f"bedrock invoke stream wrapper, modelId: {modelId}")
|
|
169
|
+
return instrumentor.invoke_wrapper(
|
|
170
|
+
_BedrockInvokeProviderRequest(instrumentor=instrumentor, model_id=modelId),
|
|
171
|
+
_IsStreaming.true,
|
|
172
|
+
wrapped,
|
|
173
|
+
None,
|
|
174
|
+
args,
|
|
175
|
+
kwargs,
|
|
176
|
+
)
|
|
184
177
|
|
|
185
178
|
return invoke_wrapper
|
|
186
179
|
|
|
@@ -189,18 +182,15 @@ def wrap_converse(instrumentor: _PayiInstrumentor, wrapped: Any) -> Any:
|
|
|
189
182
|
def invoke_wrapper(*args: Any, **kwargs: 'dict[str, Any]') -> Any:
|
|
190
183
|
modelId:str = kwargs.get("modelId", "") # type: ignore
|
|
191
184
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
kwargs,
|
|
185
|
+
instrumentor._logger.debug(f"bedrock converse wrapper, modelId: {modelId}")
|
|
186
|
+
return instrumentor.invoke_wrapper(
|
|
187
|
+
_BedrockConverseProviderRequest(instrumentor=instrumentor),
|
|
188
|
+
_IsStreaming.false,
|
|
189
|
+
wrapped,
|
|
190
|
+
None,
|
|
191
|
+
args,
|
|
192
|
+
kwargs,
|
|
201
193
|
)
|
|
202
|
-
instrumentor._logger.debug(f"bedrock converse wrapper, unsupported modelId: {modelId}")
|
|
203
|
-
return wrapped(*args, **kwargs)
|
|
204
194
|
|
|
205
195
|
return invoke_wrapper
|
|
206
196
|
|
|
@@ -209,18 +199,15 @@ def wrap_converse_stream(instrumentor: _PayiInstrumentor, wrapped: Any) -> Any:
|
|
|
209
199
|
def invoke_wrapper(*args: Any, **kwargs: Any) -> Any:
|
|
210
200
|
modelId: str = kwargs.get("modelId", "") # type: ignore
|
|
211
201
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
)
|
|
222
|
-
instrumentor._logger.debug(f"bedrock converse stream wrapper, unsupported modelId: {modelId}")
|
|
223
|
-
return wrapped(*args, **kwargs)
|
|
202
|
+
instrumentor._logger.debug(f"bedrock converse stream wrapper, modelId: {modelId}")
|
|
203
|
+
return instrumentor.invoke_wrapper(
|
|
204
|
+
_BedrockConverseProviderRequest(instrumentor=instrumentor),
|
|
205
|
+
_IsStreaming.true,
|
|
206
|
+
wrapped,
|
|
207
|
+
None,
|
|
208
|
+
args,
|
|
209
|
+
kwargs,
|
|
210
|
+
)
|
|
224
211
|
|
|
225
212
|
return invoke_wrapper
|
|
226
213
|
|
|
@@ -230,6 +217,7 @@ class _BedrockProviderRequest(_ProviderRequest):
|
|
|
230
217
|
instrumentor=instrumentor,
|
|
231
218
|
category=PayiCategories.aws_bedrock,
|
|
232
219
|
streaming_type=_StreamingType.iterator,
|
|
220
|
+
is_aws_client=True,
|
|
233
221
|
)
|
|
234
222
|
|
|
235
223
|
@override
|
|
@@ -239,6 +227,10 @@ class _BedrockProviderRequest(_ProviderRequest):
|
|
|
239
227
|
self._ingest["resource"] = kwargs.get("modelId", "")
|
|
240
228
|
return True
|
|
241
229
|
|
|
230
|
+
@override
|
|
231
|
+
def process_initial_stream_response(self, response: Any) -> None:
|
|
232
|
+
self._ingest["provider_response_id"] = response.get("ResponseMetadata", {}).get("RequestId", None)
|
|
233
|
+
|
|
242
234
|
@override
|
|
243
235
|
def process_exception(self, exception: Exception, kwargs: Any, ) -> bool:
|
|
244
236
|
try:
|
|
@@ -264,10 +256,27 @@ class _BedrockProviderRequest(_ProviderRequest):
|
|
|
264
256
|
self._instrumentor._logger.debug(f"Error processing exception: {e}")
|
|
265
257
|
return False
|
|
266
258
|
|
|
267
|
-
class
|
|
259
|
+
class _BedrockInvokeProviderRequest(_BedrockProviderRequest):
|
|
268
260
|
def __init__(self, instrumentor: _PayiInstrumentor, model_id: str):
|
|
269
261
|
super().__init__(instrumentor=instrumentor)
|
|
270
|
-
self._is_anthropic: bool = model_id
|
|
262
|
+
self._is_anthropic: bool = 'anthropic' in model_id
|
|
263
|
+
|
|
264
|
+
@override
|
|
265
|
+
def process_request(self, instance: Any, extra_headers: 'dict[str, str]', args: Sequence[Any], kwargs: Any) -> bool:
|
|
266
|
+
from .AnthropicInstrumentor import anthropic_has_image_and_get_texts
|
|
267
|
+
|
|
268
|
+
super().process_request(instance, extra_headers, args, kwargs)
|
|
269
|
+
|
|
270
|
+
if self._is_anthropic:
|
|
271
|
+
try:
|
|
272
|
+
body = json.loads( kwargs.get("body", ""))
|
|
273
|
+
messages = body.get("messages", {})
|
|
274
|
+
if messages:
|
|
275
|
+
anthropic_has_image_and_get_texts(self, messages)
|
|
276
|
+
except Exception as e:
|
|
277
|
+
self._instrumentor._logger.debug(f"Bedrock invoke error processing request body: {e}")
|
|
278
|
+
|
|
279
|
+
return True
|
|
271
280
|
|
|
272
281
|
@override
|
|
273
282
|
def process_chunk(self, chunk: Any) -> _ChunkResult:
|
|
@@ -277,32 +286,9 @@ class _BedrockInvokeStreamingProviderRequest(_BedrockProviderRequest):
|
|
|
277
286
|
return self.process_invoke_streaming_llama_chunk(chunk)
|
|
278
287
|
|
|
279
288
|
def process_invoke_streaming_anthropic_chunk(self, chunk: str) -> _ChunkResult:
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
if type == "message_start":
|
|
285
|
-
usage = chunk_dict['message']['usage']
|
|
286
|
-
units = self._ingest["units"]
|
|
287
|
-
|
|
288
|
-
input = _PayiInstrumentor.update_for_vision(usage['input_tokens'], units, self._estimated_prompt_tokens)
|
|
289
|
-
|
|
290
|
-
units["text"] = Units(input=input, output=0)
|
|
291
|
-
|
|
292
|
-
text_cache_write: int = usage.get("cache_creation_input_tokens", 0)
|
|
293
|
-
if text_cache_write > 0:
|
|
294
|
-
units["text_cache_write"] = Units(input=text_cache_write, output=0)
|
|
295
|
-
|
|
296
|
-
text_cache_read: int = usage.get("cache_read_input_tokens", 0)
|
|
297
|
-
if text_cache_read > 0:
|
|
298
|
-
units["text_cache_read"] = Units(input=text_cache_read, output=0)
|
|
299
|
-
|
|
300
|
-
elif type == "message_delta":
|
|
301
|
-
usage = chunk_dict['usage']
|
|
302
|
-
self._ingest["units"]["text"]["output"] = usage['output_tokens']
|
|
303
|
-
ingest = True
|
|
304
|
-
|
|
305
|
-
return _ChunkResult(send_chunk_to_caller=True, ingest=ingest)
|
|
289
|
+
from .AnthropicInstrumentor import anthropic_process_chunk
|
|
290
|
+
|
|
291
|
+
return anthropic_process_chunk(self, json.loads(chunk), assign_id=False)
|
|
306
292
|
|
|
307
293
|
def process_invoke_streaming_llama_chunk(self, chunk: str) -> _ChunkResult:
|
|
308
294
|
ingest = False
|
|
@@ -316,7 +302,6 @@ class _BedrockInvokeStreamingProviderRequest(_BedrockProviderRequest):
|
|
|
316
302
|
|
|
317
303
|
return _ChunkResult(send_chunk_to_caller=True, ingest=ingest)
|
|
318
304
|
|
|
319
|
-
class _BedrockInvokeSynchronousProviderRequest(_BedrockProviderRequest):
|
|
320
305
|
@override
|
|
321
306
|
def process_synchronous_response(
|
|
322
307
|
self,
|
|
@@ -336,13 +321,12 @@ class _BedrockInvokeSynchronousProviderRequest(_BedrockProviderRequest):
|
|
|
336
321
|
|
|
337
322
|
response["body"] = InvokeResponseWrapper(
|
|
338
323
|
response=response["body"],
|
|
339
|
-
|
|
340
|
-
ingest=self._ingest,
|
|
324
|
+
request=self,
|
|
341
325
|
log_prompt_and_response=log_prompt_and_response)
|
|
342
326
|
|
|
343
327
|
return response
|
|
344
328
|
|
|
345
|
-
class
|
|
329
|
+
class _BedrockConverseProviderRequest(_BedrockProviderRequest):
|
|
346
330
|
@override
|
|
347
331
|
def process_synchronous_response(
|
|
348
332
|
self,
|
|
@@ -374,7 +358,6 @@ class _BedrockConverseSynchronousProviderRequest(_BedrockProviderRequest):
|
|
|
374
358
|
|
|
375
359
|
return None
|
|
376
360
|
|
|
377
|
-
class _BedrockConverseStreamingProviderRequest(_BedrockProviderRequest):
|
|
378
361
|
@override
|
|
379
362
|
def process_chunk(self, chunk: 'dict[str, Any]') -> _ChunkResult:
|
|
380
363
|
ingest = False
|