payi 0.1.0a63__tar.gz → 0.1.0a65__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.0a65/.release-please-manifest.json +3 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/CHANGELOG.md +16 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/PKG-INFO +1 -1
- {payi-0.1.0a63 → payi-0.1.0a65}/pyproject.toml +1 -1
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/_utils/_transform.py +22 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/_version.py +1 -1
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/lib/AnthropicInstrumentor.py +60 -60
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/lib/BedrockInstrumentor.py +102 -92
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/lib/OpenAIInstrumentor.py +90 -58
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/lib/helpers.py +3 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/lib/instrument.py +214 -238
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/test_transform.py +12 -0
- payi-0.1.0a63/.release-please-manifest.json +0 -3
- {payi-0.1.0a63 → payi-0.1.0a65}/.gitignore +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/CONTRIBUTING.md +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/LICENSE +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/README.md +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/SECURITY.md +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/api.md +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/bin/check-release-environment +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/bin/publish-pypi +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/examples/.keep +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/mypy.ini +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/noxfile.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/release-please-config.json +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/requirements-dev.lock +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/requirements.lock +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/__init__.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/_base_client.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/_client.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/_compat.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/_constants.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/_exceptions.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/_files.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/_models.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/_qs.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/_resource.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/_response.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/_streaming.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/_types.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/_utils/__init__.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/_utils/_logs.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/_utils/_proxy.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/_utils/_reflection.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/_utils/_streams.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/_utils/_sync.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/_utils/_typing.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/_utils/_utils.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/lib/.keep +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/lib/Stopwatch.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/pagination.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/py.typed +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/resources/__init__.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/resources/categories/__init__.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/resources/categories/categories.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/resources/categories/resources.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/resources/experiences/__init__.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/resources/experiences/experiences.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/resources/experiences/properties.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/resources/experiences/types/__init__.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/resources/experiences/types/limit_config.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/resources/experiences/types/types.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/resources/ingest.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/resources/limits/__init__.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/resources/limits/limits.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/resources/limits/tags.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/resources/requests/__init__.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/resources/requests/properties.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/resources/requests/requests.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/resources/requests/result.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/resources/use_cases/__init__.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/resources/use_cases/definitions/__init__.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/resources/use_cases/definitions/definitions.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/resources/use_cases/definitions/kpis.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/resources/use_cases/definitions/limit_config.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/resources/use_cases/definitions/version.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/resources/use_cases/kpis.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/resources/use_cases/properties.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/resources/use_cases/use_cases.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/__init__.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/bulk_ingest_response.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/categories/__init__.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/categories/resource_create_params.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/categories/resource_list_params.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/category_delete_resource_response.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/category_delete_response.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/category_list_params.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/category_list_resources_params.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/category_resource_response.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/category_response.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/cost_data.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/cost_details.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/default_response.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/experience_instance_response.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/experiences/__init__.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/experiences/experience_type.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/experiences/property_create_params.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/experiences/type_create_params.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/experiences/type_list_params.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/experiences/type_update_params.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/experiences/types/__init__.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/experiences/types/limit_config_create_params.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/ingest_bulk_params.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/ingest_event_param.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/ingest_response.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/ingest_units_params.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/limit_create_params.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/limit_history_response.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/limit_list_params.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/limit_list_response.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/limit_reset_params.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/limit_response.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/limit_update_params.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/limits/__init__.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/limits/limit_tags.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/limits/tag_create_params.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/limits/tag_create_response.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/limits/tag_delete_response.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/limits/tag_list_response.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/limits/tag_remove_params.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/limits/tag_remove_response.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/limits/tag_update_params.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/limits/tag_update_response.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/pay_i_common_models_api_router_header_info_param.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/requests/__init__.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/requests/property_create_params.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/requests/request_result.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/requests_data.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/shared/__init__.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/shared/evaluation_response.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/shared/pay_i_common_models_budget_management_cost_details_base.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/shared/pay_i_common_models_budget_management_create_limit_base.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/shared/properties_response.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/shared_params/__init__.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/shared_params/pay_i_common_models_budget_management_create_limit_base.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/total_cost_data.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/use_case_instance_response.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/use_cases/__init__.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/use_cases/definition_create_params.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/use_cases/definition_list_params.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/use_cases/definition_update_params.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/use_cases/definitions/__init__.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/use_cases/definitions/kpi_create_params.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/use_cases/definitions/kpi_create_response.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/use_cases/definitions/kpi_delete_response.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/use_cases/definitions/kpi_list_params.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/use_cases/definitions/kpi_list_response.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/use_cases/definitions/kpi_retrieve_response.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/use_cases/definitions/kpi_update_params.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/use_cases/definitions/kpi_update_response.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/use_cases/definitions/limit_config_create_params.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/use_cases/kpi_create_params.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/use_cases/kpi_list_params.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/use_cases/kpi_list_response.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/use_cases/kpi_update_params.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/use_cases/property_create_params.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/src/payi/types/use_cases/use_case_definition.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/__init__.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/api_resources/__init__.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/api_resources/categories/__init__.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/api_resources/categories/test_resources.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/api_resources/experiences/__init__.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/api_resources/experiences/test_properties.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/api_resources/experiences/test_types.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/api_resources/experiences/types/__init__.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/api_resources/experiences/types/test_limit_config.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/api_resources/limits/__init__.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/api_resources/limits/test_tags.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/api_resources/requests/__init__.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/api_resources/requests/test_properties.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/api_resources/requests/test_result.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/api_resources/test_categories.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/api_resources/test_experiences.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/api_resources/test_ingest.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/api_resources/test_limits.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/api_resources/test_use_cases.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/api_resources/use_cases/__init__.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/api_resources/use_cases/definitions/__init__.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/api_resources/use_cases/definitions/test_kpis.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/api_resources/use_cases/definitions/test_limit_config.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/api_resources/use_cases/definitions/test_version.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/api_resources/use_cases/test_definitions.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/api_resources/use_cases/test_kpis.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/api_resources/use_cases/test_properties.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/conftest.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/sample_file.txt +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/test_client.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/test_deepcopy.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/test_extract_files.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/test_files.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/test_models.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/test_qs.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/test_required_args.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/test_response.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/test_streaming.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/test_utils/test_proxy.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/test_utils/test_typing.py +0 -0
- {payi-0.1.0a63 → payi-0.1.0a65}/tests/utils.py +0 -0
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.0-alpha.65 (2025-04-10)
|
|
4
|
+
|
|
5
|
+
Full Changelog: [v0.1.0-alpha.64...v0.1.0-alpha.65](https://github.com/Pay-i/pay-i-python/compare/v0.1.0-alpha.64...v0.1.0-alpha.65)
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
* feat: simplify OpenAI streaming setup ([7b50eb2](https://github.com/Pay-i/pay-i-python/commit/7b50eb276c6bb464cb94d6551e342e32b0b76181))
|
|
10
|
+
|
|
11
|
+
## 0.1.0-alpha.64 (2025-04-09)
|
|
12
|
+
|
|
13
|
+
Full Changelog: [v0.1.0-alpha.63...v0.1.0-alpha.64](https://github.com/Pay-i/pay-i-python/compare/v0.1.0-alpha.63...v0.1.0-alpha.64)
|
|
14
|
+
|
|
15
|
+
### Chores
|
|
16
|
+
|
|
17
|
+
* **internal:** slight transform perf improvement ([#283](https://github.com/Pay-i/pay-i-python/issues/283)) ([4b3f9e6](https://github.com/Pay-i/pay-i-python/commit/4b3f9e60fbecf99f8ddffed5903f916f3d5445c5))
|
|
18
|
+
|
|
3
19
|
## 0.1.0-alpha.63 (2025-04-08)
|
|
4
20
|
|
|
5
21
|
Full Changelog: [v0.1.0-alpha.62...v0.1.0-alpha.63](https://github.com/Pay-i/pay-i-python/compare/v0.1.0-alpha.62...v0.1.0-alpha.63)
|
|
@@ -142,6 +142,10 @@ def _maybe_transform_key(key: str, type_: type) -> str:
|
|
|
142
142
|
return key
|
|
143
143
|
|
|
144
144
|
|
|
145
|
+
def _no_transform_needed(annotation: type) -> bool:
|
|
146
|
+
return annotation == float or annotation == int
|
|
147
|
+
|
|
148
|
+
|
|
145
149
|
def _transform_recursive(
|
|
146
150
|
data: object,
|
|
147
151
|
*,
|
|
@@ -184,6 +188,15 @@ def _transform_recursive(
|
|
|
184
188
|
return cast(object, data)
|
|
185
189
|
|
|
186
190
|
inner_type = extract_type_arg(stripped_type, 0)
|
|
191
|
+
if _no_transform_needed(inner_type):
|
|
192
|
+
# for some types there is no need to transform anything, so we can get a small
|
|
193
|
+
# perf boost from skipping that work.
|
|
194
|
+
#
|
|
195
|
+
# but we still need to convert to a list to ensure the data is json-serializable
|
|
196
|
+
if is_list(data):
|
|
197
|
+
return data
|
|
198
|
+
return list(data)
|
|
199
|
+
|
|
187
200
|
return [_transform_recursive(d, annotation=annotation, inner_type=inner_type) for d in data]
|
|
188
201
|
|
|
189
202
|
if is_union_type(stripped_type):
|
|
@@ -332,6 +345,15 @@ async def _async_transform_recursive(
|
|
|
332
345
|
return cast(object, data)
|
|
333
346
|
|
|
334
347
|
inner_type = extract_type_arg(stripped_type, 0)
|
|
348
|
+
if _no_transform_needed(inner_type):
|
|
349
|
+
# for some types there is no need to transform anything, so we can get a small
|
|
350
|
+
# perf boost from skipping that work.
|
|
351
|
+
#
|
|
352
|
+
# but we still need to convert to a list to ensure the data is json-serializable
|
|
353
|
+
if is_list(data):
|
|
354
|
+
return data
|
|
355
|
+
return list(data)
|
|
356
|
+
|
|
335
357
|
return [await _async_transform_recursive(d, annotation=annotation, inner_type=inner_type) for d in data]
|
|
336
358
|
|
|
337
359
|
if is_union_type(stripped_type):
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
from typing import Any, Union
|
|
3
|
+
from typing_extensions import override
|
|
3
4
|
|
|
4
5
|
import tiktoken
|
|
5
6
|
from wrapt import wrap_function_wrapper # type: ignore
|
|
6
7
|
|
|
7
|
-
from payi.types import IngestUnitsParams
|
|
8
8
|
from payi.types.ingest_units_params import Units
|
|
9
9
|
|
|
10
|
-
from .instrument import _IsStreaming, _PayiInstrumentor
|
|
10
|
+
from .instrument import _IsStreaming, _ProviderRequest, _PayiInstrumentor
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class AnthropicIntrumentor:
|
|
@@ -55,9 +55,7 @@ def chat_wrapper(
|
|
|
55
55
|
) -> Any:
|
|
56
56
|
return instrumentor.chat_wrapper(
|
|
57
57
|
"system.anthropic",
|
|
58
|
-
|
|
59
|
-
process_request,
|
|
60
|
-
process_synchronous_response,
|
|
58
|
+
_AnthropicProviderRequest(instrumentor),
|
|
61
59
|
_IsStreaming.kwargs,
|
|
62
60
|
wrapped,
|
|
63
61
|
instance,
|
|
@@ -75,9 +73,7 @@ async def achat_wrapper(
|
|
|
75
73
|
) -> Any:
|
|
76
74
|
return await instrumentor.achat_wrapper(
|
|
77
75
|
"system.anthropic",
|
|
78
|
-
|
|
79
|
-
process_request,
|
|
80
|
-
process_synchronous_response,
|
|
76
|
+
_AnthropicProviderRequest(instrumentor),
|
|
81
77
|
_IsStreaming.kwargs,
|
|
82
78
|
wrapped,
|
|
83
79
|
instance,
|
|
@@ -85,17 +81,39 @@ async def achat_wrapper(
|
|
|
85
81
|
kwargs,
|
|
86
82
|
)
|
|
87
83
|
|
|
84
|
+
class _AnthropicProviderRequest(_ProviderRequest):
|
|
85
|
+
@override
|
|
86
|
+
def process_chunk(self, chunk: Any) -> bool:
|
|
87
|
+
if chunk.type == "message_start":
|
|
88
|
+
self._ingest["provider_response_id"] = chunk.message.id
|
|
88
89
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
ingest["provider_response_id"] = chunk.message.id
|
|
90
|
+
usage = chunk.message.usage
|
|
91
|
+
units = self._ingest["units"]
|
|
92
92
|
|
|
93
|
-
|
|
94
|
-
units = ingest["units"]
|
|
93
|
+
input = _PayiInstrumentor.update_for_vision(usage.input_tokens, units, self._estimated_prompt_tokens)
|
|
95
94
|
|
|
96
|
-
|
|
95
|
+
units["text"] = Units(input=input, output=0)
|
|
97
96
|
|
|
98
|
-
|
|
97
|
+
if hasattr(usage, "cache_creation_input_tokens") and usage.cache_creation_input_tokens > 0:
|
|
98
|
+
text_cache_write = usage.cache_creation_input_tokens
|
|
99
|
+
units["text_cache_write"] = Units(input=text_cache_write, output=0)
|
|
100
|
+
|
|
101
|
+
if hasattr(usage, "cache_read_input_tokens") and usage.cache_read_input_tokens > 0:
|
|
102
|
+
text_cache_read = usage.cache_read_input_tokens
|
|
103
|
+
units["text_cache_read"] = Units(input=text_cache_read, output=0)
|
|
104
|
+
|
|
105
|
+
elif chunk.type == "message_delta":
|
|
106
|
+
usage = chunk.usage
|
|
107
|
+
self._ingest["units"]["text"]["output"] = usage.output_tokens
|
|
108
|
+
|
|
109
|
+
return True
|
|
110
|
+
|
|
111
|
+
@override
|
|
112
|
+
def process_synchronous_response(self, response: Any, log_prompt_and_response: bool, kwargs: Any) -> Any:
|
|
113
|
+
usage = response.usage
|
|
114
|
+
input = usage.input_tokens
|
|
115
|
+
output = usage.output_tokens
|
|
116
|
+
units: dict[str, Units] = self._ingest["units"]
|
|
99
117
|
|
|
100
118
|
if hasattr(usage, "cache_creation_input_tokens") and usage.cache_creation_input_tokens > 0:
|
|
101
119
|
text_cache_write = usage.cache_creation_input_tokens
|
|
@@ -105,35 +123,37 @@ def process_chunk(chunk: Any, ingest: IngestUnitsParams) -> None:
|
|
|
105
123
|
text_cache_read = usage.cache_read_input_tokens
|
|
106
124
|
units["text_cache_read"] = Units(input=text_cache_read, output=0)
|
|
107
125
|
|
|
108
|
-
|
|
109
|
-
usage = chunk.usage
|
|
110
|
-
ingest["units"]["text"]["output"] = usage.output_tokens
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
def process_synchronous_response(response: Any, ingest: IngestUnitsParams, log_prompt_and_response: bool, *args: Any, **kwargs: 'dict[str, Any]') -> Any: # noqa: ARG001
|
|
114
|
-
usage = response.usage
|
|
115
|
-
input = usage.input_tokens
|
|
116
|
-
output = usage.output_tokens
|
|
117
|
-
units: dict[str, Units] = ingest["units"]
|
|
118
|
-
|
|
119
|
-
if hasattr(usage, "cache_creation_input_tokens") and usage.cache_creation_input_tokens > 0:
|
|
120
|
-
text_cache_write = usage.cache_creation_input_tokens
|
|
121
|
-
units["text_cache_write"] = Units(input=text_cache_write, output=0)
|
|
126
|
+
input = _PayiInstrumentor.update_for_vision(input, units, self._estimated_prompt_tokens)
|
|
122
127
|
|
|
123
|
-
|
|
124
|
-
text_cache_read = usage.cache_read_input_tokens
|
|
125
|
-
units["text_cache_read"] = Units(input=text_cache_read, output=0)
|
|
128
|
+
units["text"] = Units(input=input, output=output)
|
|
126
129
|
|
|
127
|
-
|
|
130
|
+
if log_prompt_and_response:
|
|
131
|
+
self._ingest["provider_response_json"] = response.to_json()
|
|
132
|
+
|
|
133
|
+
self._ingest["provider_response_id"] = response.id
|
|
134
|
+
|
|
135
|
+
return None
|
|
128
136
|
|
|
129
|
-
|
|
137
|
+
@override
|
|
138
|
+
def process_request(self, kwargs: Any) -> None:
|
|
139
|
+
messages = kwargs.get("messages")
|
|
140
|
+
if not messages or len(messages) == 0:
|
|
141
|
+
return
|
|
142
|
+
|
|
143
|
+
estimated_token_count = 0
|
|
144
|
+
has_image = False
|
|
130
145
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
146
|
+
enc = tiktoken.get_encoding("cl100k_base")
|
|
147
|
+
|
|
148
|
+
for message in messages:
|
|
149
|
+
msg_has_image, msg_prompt_tokens = has_image_and_get_texts(enc, message.get('content', ''))
|
|
150
|
+
if msg_has_image:
|
|
151
|
+
has_image = True
|
|
152
|
+
estimated_token_count += msg_prompt_tokens
|
|
153
|
+
|
|
154
|
+
if not has_image or estimated_token_count == 0:
|
|
155
|
+
return
|
|
156
|
+
self._estimated_prompt_tokens = estimated_token_count
|
|
137
157
|
|
|
138
158
|
def has_image_and_get_texts(encoding: tiktoken.Encoding, content: Union[str, 'list[Any]']) -> 'tuple[bool, int]':
|
|
139
159
|
if isinstance(content, str):
|
|
@@ -146,23 +166,3 @@ def has_image_and_get_texts(encoding: tiktoken.Encoding, content: Union[str, 'li
|
|
|
146
166
|
token_count = sum(len(encoding.encode(item.get("text", ""))) for item in content if item.get("type") == "text")
|
|
147
167
|
return has_image, token_count
|
|
148
168
|
|
|
149
|
-
def process_request(ingest: IngestUnitsParams, *args: Any, **kwargs: Any) -> None: # noqa: ARG001
|
|
150
|
-
messages = kwargs.get("messages")
|
|
151
|
-
if not messages or len(messages) == 0:
|
|
152
|
-
return
|
|
153
|
-
|
|
154
|
-
estimated_token_count = 0
|
|
155
|
-
has_image = False
|
|
156
|
-
|
|
157
|
-
enc = tiktoken.get_encoding("cl100k_base")
|
|
158
|
-
|
|
159
|
-
for message in messages:
|
|
160
|
-
msg_has_image, msg_prompt_tokens = has_image_and_get_texts(enc, message.get('content', ''))
|
|
161
|
-
if msg_has_image:
|
|
162
|
-
has_image = True
|
|
163
|
-
estimated_token_count += msg_prompt_tokens
|
|
164
|
-
|
|
165
|
-
if not has_image or estimated_token_count == 0:
|
|
166
|
-
return
|
|
167
|
-
|
|
168
|
-
ingest["units"][_PayiInstrumentor.estimated_prompt_tokens] = Units(input=estimated_token_count, output=0)
|
|
@@ -2,13 +2,14 @@ import json
|
|
|
2
2
|
import logging
|
|
3
3
|
from typing import Any
|
|
4
4
|
from functools import wraps
|
|
5
|
+
from typing_extensions import override
|
|
5
6
|
|
|
6
7
|
from wrapt import ObjectProxy, wrap_function_wrapper # type: ignore
|
|
7
8
|
|
|
8
9
|
from payi.types.ingest_units_params import Units, IngestUnitsParams
|
|
9
10
|
from payi.types.pay_i_common_models_api_router_header_info_param import PayICommonModelsAPIRouterHeaderInfoParam
|
|
10
11
|
|
|
11
|
-
from .instrument import _IsStreaming, _PayiInstrumentor
|
|
12
|
+
from .instrument import _IsStreaming, _ProviderRequest, _PayiInstrumentor
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
class BedrockInstrumentor:
|
|
@@ -103,9 +104,7 @@ def wrap_invoke(instrumentor: _PayiInstrumentor, wrapped: Any) -> Any:
|
|
|
103
104
|
if modelId.startswith("meta.llama3") or modelId.startswith("anthropic."):
|
|
104
105
|
return instrumentor.chat_wrapper(
|
|
105
106
|
"system.aws.bedrock",
|
|
106
|
-
|
|
107
|
-
process_invoke_request,
|
|
108
|
-
process_synchronous_invoke_response,
|
|
107
|
+
_BedrockInvokeSynchronousProviderRequest(instrumentor),
|
|
109
108
|
_IsStreaming.false,
|
|
110
109
|
wrapped,
|
|
111
110
|
None,
|
|
@@ -119,14 +118,12 @@ def wrap_invoke(instrumentor: _PayiInstrumentor, wrapped: Any) -> Any:
|
|
|
119
118
|
def wrap_invoke_stream(instrumentor: _PayiInstrumentor, wrapped: Any) -> Any:
|
|
120
119
|
@wraps(wrapped)
|
|
121
120
|
def invoke_wrapper(*args: Any, **kwargs: Any) -> Any:
|
|
122
|
-
|
|
121
|
+
model_id: str = kwargs.get("modelId", "") # type: ignore
|
|
123
122
|
|
|
124
|
-
if
|
|
123
|
+
if model_id.startswith("meta.llama3") or model_id.startswith("anthropic."):
|
|
125
124
|
return instrumentor.chat_wrapper(
|
|
126
125
|
"system.aws.bedrock",
|
|
127
|
-
|
|
128
|
-
process_invoke_request,
|
|
129
|
-
None,
|
|
126
|
+
_BedrockInvokeStreamingProviderRequest(instrumentor, model_id),
|
|
130
127
|
_IsStreaming.true,
|
|
131
128
|
wrapped,
|
|
132
129
|
None,
|
|
@@ -145,9 +142,7 @@ def wrap_converse(instrumentor: _PayiInstrumentor, wrapped: Any) -> Any:
|
|
|
145
142
|
if modelId.startswith("meta.llama3") or modelId.startswith("anthropic."):
|
|
146
143
|
return instrumentor.chat_wrapper(
|
|
147
144
|
"system.aws.bedrock",
|
|
148
|
-
|
|
149
|
-
process_converse_request,
|
|
150
|
-
process_synchronous_converse_response,
|
|
145
|
+
_BedrockConverseSynchronousProviderRequest(instrumentor),
|
|
151
146
|
_IsStreaming.false,
|
|
152
147
|
wrapped,
|
|
153
148
|
None,
|
|
@@ -161,14 +156,12 @@ def wrap_converse(instrumentor: _PayiInstrumentor, wrapped: Any) -> Any:
|
|
|
161
156
|
def wrap_converse_stream(instrumentor: _PayiInstrumentor, wrapped: Any) -> Any:
|
|
162
157
|
@wraps(wrapped)
|
|
163
158
|
def invoke_wrapper(*args: Any, **kwargs: Any) -> Any:
|
|
164
|
-
|
|
159
|
+
model_id: str = kwargs.get("modelId", "") # type: ignore
|
|
165
160
|
|
|
166
|
-
if
|
|
161
|
+
if model_id.startswith("meta.llama3") or model_id.startswith("anthropic."):
|
|
167
162
|
return instrumentor.chat_wrapper(
|
|
168
163
|
"system.aws.bedrock",
|
|
169
|
-
|
|
170
|
-
process_converse_request,
|
|
171
|
-
None,
|
|
164
|
+
_BedrockConverseStreamingProviderRequest(instrumentor),
|
|
172
165
|
_IsStreaming.true,
|
|
173
166
|
wrapped,
|
|
174
167
|
None,
|
|
@@ -179,104 +172,121 @@ def wrap_converse_stream(instrumentor: _PayiInstrumentor, wrapped: Any) -> Any:
|
|
|
179
172
|
|
|
180
173
|
return invoke_wrapper
|
|
181
174
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
175
|
+
class _BedrockInvokeStreamingProviderRequest(_ProviderRequest):
|
|
176
|
+
def __init__(self, instrumentor: _PayiInstrumentor, model_id: str):
|
|
177
|
+
super().__init__(instrumentor)
|
|
178
|
+
self._is_anthropic: bool = model_id.startswith("anthropic.")
|
|
185
179
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
180
|
+
@override
|
|
181
|
+
def process_chunk(self, chunk: Any) -> bool:
|
|
182
|
+
if self._is_anthropic:
|
|
183
|
+
return self.process_invoke_streaming_anthropic_chunk(chunk)
|
|
184
|
+
else:
|
|
185
|
+
return self.process_invoke_streaming_llama_chunk(chunk)
|
|
189
186
|
|
|
190
|
-
|
|
187
|
+
def process_invoke_streaming_anthropic_chunk(self, chunk: str) -> bool:
|
|
188
|
+
chunk_dict = json.loads(chunk)
|
|
189
|
+
type = chunk_dict.get("type", "")
|
|
191
190
|
|
|
192
|
-
|
|
191
|
+
if type == "message_start":
|
|
192
|
+
usage = chunk_dict['message']['usage']
|
|
193
|
+
units = self._ingest["units"]
|
|
193
194
|
|
|
194
|
-
|
|
195
|
-
if text_cache_write > 0:
|
|
196
|
-
units["text_cache_write"] = Units(input=text_cache_write, output=0)
|
|
195
|
+
input = _PayiInstrumentor.update_for_vision(usage['input_tokens'], units, self._estimated_prompt_tokens)
|
|
197
196
|
|
|
198
|
-
|
|
199
|
-
if text_cache_read > 0:
|
|
200
|
-
units["text_cache_read"] = Units(input=text_cache_read, output=0)
|
|
197
|
+
units["text"] = Units(input=input, output=0)
|
|
201
198
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
199
|
+
text_cache_write: int = usage.get("cache_creation_input_tokens", 0)
|
|
200
|
+
if text_cache_write > 0:
|
|
201
|
+
units["text_cache_write"] = Units(input=text_cache_write, output=0)
|
|
205
202
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
203
|
+
text_cache_read: int = usage.get("cache_read_input_tokens", 0)
|
|
204
|
+
if text_cache_read > 0:
|
|
205
|
+
units["text_cache_read"] = Units(input=text_cache_read, output=0)
|
|
206
|
+
|
|
207
|
+
elif type == "message_delta":
|
|
208
|
+
usage = chunk_dict['usage']
|
|
209
|
+
self._ingest["units"]["text"]["output"] = usage['output_tokens']
|
|
210
|
+
|
|
211
|
+
return True
|
|
212
|
+
|
|
213
|
+
def process_invoke_streaming_llama_chunk(self, chunk: str) -> bool:
|
|
214
|
+
chunk_dict = json.loads(chunk)
|
|
215
|
+
metrics = chunk_dict.get("amazon-bedrock-invocationMetrics", {})
|
|
216
|
+
if metrics:
|
|
217
|
+
input = metrics.get("inputTokenCount", 0)
|
|
218
|
+
output = metrics.get("outputTokenCount", 0)
|
|
219
|
+
self._ingest["units"]["text"] = Units(input=input, output=output)
|
|
220
|
+
|
|
221
|
+
return True
|
|
222
|
+
|
|
223
|
+
class _BedrockInvokeSynchronousProviderRequest(_ProviderRequest):
|
|
224
|
+
@override
|
|
225
|
+
def process_synchronous_response(
|
|
226
|
+
self,
|
|
215
227
|
response: Any,
|
|
216
|
-
ingest: IngestUnitsParams,
|
|
217
228
|
log_prompt_and_response: bool,
|
|
218
|
-
|
|
219
|
-
**kargs: Any) -> Any: # noqa: ARG001
|
|
229
|
+
kwargs: Any) -> Any:
|
|
220
230
|
|
|
221
|
-
|
|
231
|
+
metadata = response.get("ResponseMetadata", {})
|
|
222
232
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
233
|
+
request_id = metadata.get("RequestId", "")
|
|
234
|
+
if request_id:
|
|
235
|
+
self._ingest["provider_response_id"] = request_id
|
|
226
236
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
237
|
+
response_headers = metadata.get("HTTPHeaders", {}).copy()
|
|
238
|
+
if response_headers:
|
|
239
|
+
self._ingest["provider_response_headers"] = [PayICommonModelsAPIRouterHeaderInfoParam(name=k, value=v) for k, v in response_headers.items()]
|
|
230
240
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
241
|
+
response["body"] = InvokeResponseWrapper(
|
|
242
|
+
response=response["body"],
|
|
243
|
+
instrumentor=self._instrumentor,
|
|
244
|
+
ingest=self._ingest,
|
|
245
|
+
log_prompt_and_response=log_prompt_and_response)
|
|
236
246
|
|
|
237
|
-
|
|
247
|
+
return response
|
|
238
248
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
249
|
+
class _BedrockConverseSynchronousProviderRequest(_ProviderRequest):
|
|
250
|
+
@override
|
|
251
|
+
def process_synchronous_response(
|
|
252
|
+
self,
|
|
253
|
+
response: 'dict[str, Any]',
|
|
254
|
+
log_prompt_and_response: bool,
|
|
255
|
+
kwargs: Any) -> Any:
|
|
244
256
|
|
|
245
|
-
|
|
246
|
-
usage = metadata['usage']
|
|
257
|
+
usage = response["usage"]
|
|
247
258
|
input = usage["inputTokens"]
|
|
248
259
|
output = usage["outputTokens"]
|
|
249
|
-
|
|
260
|
+
|
|
261
|
+
units: dict[str, Units] = self._ingest["units"]
|
|
262
|
+
units["text"] = Units(input=input, output=output)
|
|
250
263
|
|
|
251
|
-
|
|
252
|
-
response: 'dict[str, Any]',
|
|
253
|
-
ingest: IngestUnitsParams,
|
|
254
|
-
log_prompt_and_response: bool,
|
|
255
|
-
**kargs: Any) -> Any: # noqa: ARG001
|
|
264
|
+
metadata = response.get("ResponseMetadata", {})
|
|
256
265
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
units: dict[str, Units] = ingest["units"]
|
|
262
|
-
units["text"] = Units(input=input, output=output)
|
|
266
|
+
request_id = metadata.get("RequestId", "")
|
|
267
|
+
if request_id:
|
|
268
|
+
self._ingest["provider_response_id"] = request_id
|
|
263
269
|
|
|
264
|
-
|
|
270
|
+
response_headers = metadata.get("HTTPHeaders", {})
|
|
271
|
+
if response_headers:
|
|
272
|
+
self._ingest["provider_response_headers"] = [PayICommonModelsAPIRouterHeaderInfoParam(name=k, value=v) for k, v in response_headers.items()]
|
|
265
273
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
274
|
+
if log_prompt_and_response:
|
|
275
|
+
response_without_metadata = response.copy()
|
|
276
|
+
response_without_metadata.pop("ResponseMetadata", None)
|
|
277
|
+
self._ingest["provider_response_json"] = json.dumps(response_without_metadata)
|
|
269
278
|
|
|
270
|
-
|
|
271
|
-
if response_headers:
|
|
272
|
-
ingest["provider_response_headers"] = [PayICommonModelsAPIRouterHeaderInfoParam(name=k, value=v) for k, v in response_headers.items()]
|
|
279
|
+
return None
|
|
273
280
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
281
|
+
class _BedrockConverseStreamingProviderRequest(_ProviderRequest):
|
|
282
|
+
@override
|
|
283
|
+
def process_chunk(self, chunk: 'dict[str, Any]') -> bool:
|
|
284
|
+
metadata = chunk.get("metadata", {})
|
|
278
285
|
|
|
279
|
-
|
|
286
|
+
if metadata:
|
|
287
|
+
usage = metadata['usage']
|
|
288
|
+
input = usage["inputTokens"]
|
|
289
|
+
output = usage["outputTokens"]
|
|
290
|
+
self._ingest["units"]["text"] = Units(input=input, output=output)
|
|
280
291
|
|
|
281
|
-
|
|
282
|
-
return
|
|
292
|
+
return True
|