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