payi 0.1.0a39__tar.gz → 0.1.0a41__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.0a41/.release-please-manifest.json +3 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/CHANGELOG.md +17 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/PKG-INFO +2 -1
- {payi-0.1.0a39 → payi-0.1.0a41}/pyproject.toml +3 -2
- {payi-0.1.0a39 → payi-0.1.0a41}/requirements-dev.lock +13 -2
- {payi-0.1.0a39 → payi-0.1.0a41}/requirements.lock +12 -1
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/_constants.py +1 -1
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/_models.py +1 -1
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/_version.py +1 -1
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/lib/AnthropicInstrumentor.py +54 -13
- payi-0.1.0a41/src/payi/lib/BedrockInstrumentor.py +288 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/lib/Instruments.py +1 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/lib/OpenAIInstrumentor.py +50 -11
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/lib/instrument.py +126 -18
- payi-0.1.0a39/.release-please-manifest.json +0 -3
- {payi-0.1.0a39 → payi-0.1.0a41}/.gitignore +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/CONTRIBUTING.md +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/LICENSE +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/README.md +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/SECURITY.md +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/api.md +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/bin/check-release-environment +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/bin/publish-pypi +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/examples/.keep +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/mypy.ini +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/noxfile.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/release-please-config.json +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/__init__.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/_base_client.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/_client.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/_compat.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/_exceptions.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/_files.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/_qs.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/_resource.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/_response.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/_streaming.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/_types.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/_utils/__init__.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/_utils/_logs.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/_utils/_proxy.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/_utils/_reflection.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/_utils/_streams.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/_utils/_sync.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/_utils/_transform.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/_utils/_typing.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/_utils/_utils.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/lib/.keep +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/lib/Stopwatch.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/lib/helpers.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/py.typed +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/resources/__init__.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/resources/billing_models.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/resources/categories/__init__.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/resources/categories/categories.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/resources/categories/resources.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/resources/experiences/__init__.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/resources/experiences/experiences.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/resources/experiences/properties.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/resources/experiences/types/__init__.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/resources/experiences/types/limit_config.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/resources/experiences/types/types.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/resources/ingest.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/resources/limits/__init__.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/resources/limits/limits.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/resources/limits/tags.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/resources/price_modifiers.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/resources/requests/__init__.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/resources/requests/properties.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/resources/requests/requests.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/resources/requests/result.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/__init__.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/billing_model.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/billing_model_create_params.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/billing_model_list_response.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/billing_model_update_params.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/categories/__init__.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/categories/resource_create_params.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/categories/resource_list_response.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/category_delete_resource_response.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/category_delete_response.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/category_list_resources_response.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/category_list_response.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/category_resource_response.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/category_response.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/cost_data.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/cost_details.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/default_response.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/experience_instance_response.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/experiences/__init__.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/experiences/experience_type.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/experiences/properties_response.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/experiences/property_create_params.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/experiences/type_create_params.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/experiences/type_list_params.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/experiences/type_list_response.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/experiences/type_update_params.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/experiences/types/__init__.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/experiences/types/limit_config_create_params.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/ingest_response.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/ingest_units_params.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/limit_create_params.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/limit_history_response.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/limit_list_params.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/limit_reset_params.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/limit_response.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/limit_update_params.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/limits/__init__.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/limits/limit_tags.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/limits/tag_create_params.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/limits/tag_create_response.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/limits/tag_delete_response.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/limits/tag_list_response.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/limits/tag_remove_params.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/limits/tag_remove_response.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/limits/tag_update_params.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/limits/tag_update_response.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/paged_limit_list.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/pay_i_common_models_api_router_header_info_param.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/price_modifier.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/price_modifier_create_params.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/price_modifier_retrieve_response.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/price_modifier_update_params.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/requests/__init__.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/requests/property_create_params.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/requests/request_result.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/requests_data.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/shared/__init__.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/shared/evaluation_response.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/shared/pay_i_common_models_budget_management_cost_details_base.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/src/payi/types/total_cost_data.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/tests/__init__.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/tests/api_resources/__init__.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/tests/api_resources/categories/__init__.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/tests/api_resources/categories/test_resources.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/tests/api_resources/experiences/__init__.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/tests/api_resources/experiences/test_properties.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/tests/api_resources/experiences/test_types.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/tests/api_resources/experiences/types/__init__.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/tests/api_resources/experiences/types/test_limit_config.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/tests/api_resources/limits/__init__.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/tests/api_resources/limits/test_tags.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/tests/api_resources/requests/__init__.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/tests/api_resources/requests/test_properties.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/tests/api_resources/requests/test_result.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/tests/api_resources/test_billing_models.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/tests/api_resources/test_categories.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/tests/api_resources/test_experiences.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/tests/api_resources/test_ingest.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/tests/api_resources/test_limits.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/tests/api_resources/test_price_modifiers.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/tests/conftest.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/tests/sample_file.txt +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/tests/test_client.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/tests/test_deepcopy.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/tests/test_extract_files.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/tests/test_files.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/tests/test_models.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/tests/test_qs.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/tests/test_required_args.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/tests/test_response.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/tests/test_streaming.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/tests/test_transform.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/tests/test_utils/test_proxy.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/tests/test_utils/test_typing.py +0 -0
- {payi-0.1.0a39 → payi-0.1.0a41}/tests/utils.py +0 -0
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.0-alpha.41 (2025-02-04)
|
|
4
|
+
|
|
5
|
+
Full Changelog: [v0.1.0-alpha.40...v0.1.0-alpha.41](https://github.com/Pay-i/pay-i-python/compare/v0.1.0-alpha.40...v0.1.0-alpha.41)
|
|
6
|
+
|
|
7
|
+
### Chores
|
|
8
|
+
|
|
9
|
+
* **internal:** bummp ruff dependency ([#204](https://github.com/Pay-i/pay-i-python/issues/204)) ([d6e457f](https://github.com/Pay-i/pay-i-python/commit/d6e457f7e62b5d08199e170abfda75fab75099f6))
|
|
10
|
+
* **internal:** change default timeout to an int ([#202](https://github.com/Pay-i/pay-i-python/issues/202)) ([c65e2c5](https://github.com/Pay-i/pay-i-python/commit/c65e2c5c8f420505025be81f7d566f048aa7bc19))
|
|
11
|
+
|
|
12
|
+
## 0.1.0-alpha.40 (2025-01-31)
|
|
13
|
+
|
|
14
|
+
Full Changelog: [v0.1.0-alpha.39...v0.1.0-alpha.40](https://github.com/Pay-i/pay-i-python/compare/v0.1.0-alpha.39...v0.1.0-alpha.40)
|
|
15
|
+
|
|
16
|
+
### Features
|
|
17
|
+
|
|
18
|
+
* update units calculation ([a8dda4a](https://github.com/Pay-i/pay-i-python/commit/a8dda4a72b4fa6720e7e3b621f503e435630481f))
|
|
19
|
+
|
|
3
20
|
## 0.1.0-alpha.39 (2025-01-31)
|
|
4
21
|
|
|
5
22
|
Full Changelog: [v0.1.0-alpha.38...v0.1.0-alpha.39](https://github.com/Pay-i/pay-i-python/compare/v0.1.0-alpha.38...v0.1.0-alpha.39)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: payi
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.0a41
|
|
4
4
|
Summary: The official Python library for the payi API
|
|
5
5
|
Project-URL: Homepage, https://github.com/Pay-i/pay-i-python
|
|
6
6
|
Project-URL: Repository, https://github.com/Pay-i/pay-i-python
|
|
@@ -27,6 +27,7 @@ Requires-Dist: distro<2,>=1.7.0
|
|
|
27
27
|
Requires-Dist: httpx<1,>=0.23.0
|
|
28
28
|
Requires-Dist: pydantic<3,>=1.9.0
|
|
29
29
|
Requires-Dist: sniffio
|
|
30
|
+
Requires-Dist: tiktoken>=0.8.0
|
|
30
31
|
Requires-Dist: typing-extensions<5,>=4.10
|
|
31
32
|
Requires-Dist: wrapt>=1.17.2
|
|
32
33
|
Description-Content-Type: text/markdown
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "payi"
|
|
3
|
-
version = "0.1.0-alpha.
|
|
3
|
+
version = "0.1.0-alpha.41"
|
|
4
4
|
description = "The official Python library for the payi API"
|
|
5
5
|
dynamic = ["readme"]
|
|
6
6
|
license = "Apache-2.0"
|
|
@@ -15,6 +15,7 @@ dependencies = [
|
|
|
15
15
|
"distro>=1.7.0, <2",
|
|
16
16
|
"sniffio",
|
|
17
17
|
"wrapt>=1.17.2",
|
|
18
|
+
"tiktoken>=0.8.0",
|
|
18
19
|
]
|
|
19
20
|
requires-python = ">= 3.8"
|
|
20
21
|
classifiers = [
|
|
@@ -179,7 +180,7 @@ select = [
|
|
|
179
180
|
"T201",
|
|
180
181
|
"T203",
|
|
181
182
|
# misuse of typing.TYPE_CHECKING
|
|
182
|
-
"
|
|
183
|
+
"TC004",
|
|
183
184
|
# import rules
|
|
184
185
|
"TID251",
|
|
185
186
|
]
|
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
# all-features: true
|
|
8
8
|
# with-sources: false
|
|
9
9
|
# generate-hashes: false
|
|
10
|
-
# universal: false
|
|
11
10
|
|
|
12
11
|
-e file:.
|
|
13
12
|
annotated-types==0.6.0
|
|
@@ -20,6 +19,9 @@ argcomplete==3.1.2
|
|
|
20
19
|
certifi==2023.7.22
|
|
21
20
|
# via httpcore
|
|
22
21
|
# via httpx
|
|
22
|
+
# via requests
|
|
23
|
+
charset-normalizer==3.4.1
|
|
24
|
+
# via requests
|
|
23
25
|
colorlog==6.7.0
|
|
24
26
|
# via nox
|
|
25
27
|
dirty-equals==0.6.0
|
|
@@ -42,6 +44,7 @@ httpx==0.28.1
|
|
|
42
44
|
idna==3.4
|
|
43
45
|
# via anyio
|
|
44
46
|
# via httpx
|
|
47
|
+
# via requests
|
|
45
48
|
importlib-metadata==7.0.0
|
|
46
49
|
iniconfig==2.0.0
|
|
47
50
|
# via pytest
|
|
@@ -77,9 +80,13 @@ python-dateutil==2.8.2
|
|
|
77
80
|
# via time-machine
|
|
78
81
|
pytz==2023.3.post1
|
|
79
82
|
# via dirty-equals
|
|
83
|
+
regex==2024.11.6
|
|
84
|
+
# via tiktoken
|
|
85
|
+
requests==2.32.3
|
|
86
|
+
# via tiktoken
|
|
80
87
|
respx==0.22.0
|
|
81
88
|
rich==13.7.1
|
|
82
|
-
ruff==0.
|
|
89
|
+
ruff==0.9.4
|
|
83
90
|
setuptools==68.2.2
|
|
84
91
|
# via nodeenv
|
|
85
92
|
six==1.16.0
|
|
@@ -87,6 +94,8 @@ six==1.16.0
|
|
|
87
94
|
sniffio==1.3.0
|
|
88
95
|
# via anyio
|
|
89
96
|
# via payi
|
|
97
|
+
tiktoken==0.8.0
|
|
98
|
+
# via payi
|
|
90
99
|
time-machine==2.9.0
|
|
91
100
|
tomli==2.0.2
|
|
92
101
|
# via mypy
|
|
@@ -98,6 +107,8 @@ typing-extensions==4.12.2
|
|
|
98
107
|
# via pydantic
|
|
99
108
|
# via pydantic-core
|
|
100
109
|
# via pyright
|
|
110
|
+
urllib3==2.3.0
|
|
111
|
+
# via requests
|
|
101
112
|
virtualenv==20.24.5
|
|
102
113
|
# via nox
|
|
103
114
|
wrapt==1.17.2
|
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
# all-features: true
|
|
8
8
|
# with-sources: false
|
|
9
9
|
# generate-hashes: false
|
|
10
|
-
# universal: false
|
|
11
10
|
|
|
12
11
|
-e file:.
|
|
13
12
|
annotated-types==0.6.0
|
|
@@ -18,6 +17,9 @@ anyio==4.4.0
|
|
|
18
17
|
certifi==2023.7.22
|
|
19
18
|
# via httpcore
|
|
20
19
|
# via httpx
|
|
20
|
+
# via requests
|
|
21
|
+
charset-normalizer==3.4.1
|
|
22
|
+
# via requests
|
|
21
23
|
distro==1.8.0
|
|
22
24
|
# via payi
|
|
23
25
|
exceptiongroup==1.2.2
|
|
@@ -31,17 +33,26 @@ httpx==0.28.1
|
|
|
31
33
|
idna==3.4
|
|
32
34
|
# via anyio
|
|
33
35
|
# via httpx
|
|
36
|
+
# via requests
|
|
34
37
|
pydantic==2.10.3
|
|
35
38
|
# via payi
|
|
36
39
|
pydantic-core==2.27.1
|
|
37
40
|
# via pydantic
|
|
41
|
+
regex==2024.11.6
|
|
42
|
+
# via tiktoken
|
|
43
|
+
requests==2.32.3
|
|
44
|
+
# via tiktoken
|
|
38
45
|
sniffio==1.3.0
|
|
39
46
|
# via anyio
|
|
40
47
|
# via payi
|
|
48
|
+
tiktoken==0.8.0
|
|
49
|
+
# via payi
|
|
41
50
|
typing-extensions==4.12.2
|
|
42
51
|
# via anyio
|
|
43
52
|
# via payi
|
|
44
53
|
# via pydantic
|
|
45
54
|
# via pydantic-core
|
|
55
|
+
urllib3==2.3.0
|
|
56
|
+
# via requests
|
|
46
57
|
wrapt==1.17.2
|
|
47
58
|
# via payi
|
|
@@ -6,7 +6,7 @@ RAW_RESPONSE_HEADER = "X-Stainless-Raw-Response"
|
|
|
6
6
|
OVERRIDE_CAST_TO_HEADER = "____stainless_override_cast_to"
|
|
7
7
|
|
|
8
8
|
# default timeout is 1 minute
|
|
9
|
-
DEFAULT_TIMEOUT = httpx.Timeout(timeout=60
|
|
9
|
+
DEFAULT_TIMEOUT = httpx.Timeout(timeout=60, connect=5.0)
|
|
10
10
|
DEFAULT_MAX_RETRIES = 2
|
|
11
11
|
DEFAULT_CONNECTION_LIMITS = httpx.Limits(max_connections=100, max_keepalive_connections=20)
|
|
12
12
|
|
|
@@ -172,7 +172,7 @@ class BaseModel(pydantic.BaseModel):
|
|
|
172
172
|
@override
|
|
173
173
|
def __str__(self) -> str:
|
|
174
174
|
# mypy complains about an invalid self arg
|
|
175
|
-
return f
|
|
175
|
+
return f"{self.__repr_name__()}({self.__repr_str__(', ')})" # type: ignore[misc]
|
|
176
176
|
|
|
177
177
|
# Override the 'construct' method in a way that supports recursive parsing without validation.
|
|
178
178
|
# Based on https://github.com/samuelcolvin/pydantic/issues/1168#issuecomment-817742836.
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from typing import Any
|
|
2
|
+
from typing import Any, Union
|
|
3
3
|
|
|
4
|
+
import tiktoken
|
|
4
5
|
from wrapt import wrap_function_wrapper # type: ignore
|
|
5
6
|
|
|
6
7
|
from payi.types import IngestUnitsParams
|
|
7
8
|
from payi.types.ingest_units_params import Units
|
|
8
9
|
|
|
9
|
-
from .instrument import PayiInstrumentor
|
|
10
|
+
from .instrument import IsStreaming, PayiInstrumentor
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
class AnthropicIntrumentor:
|
|
@@ -47,13 +48,15 @@ def chat_wrapper(
|
|
|
47
48
|
kwargs: Any,
|
|
48
49
|
) -> Any:
|
|
49
50
|
return instrumentor.chat_wrapper(
|
|
50
|
-
"system.anthropic",
|
|
51
|
-
process_chunk,
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
51
|
+
category="system.anthropic",
|
|
52
|
+
process_chunk=process_chunk,
|
|
53
|
+
process_request=process_request,
|
|
54
|
+
process_synchronous_response=process_synchronous_response,
|
|
55
|
+
is_streaming=IsStreaming.kwargs,
|
|
56
|
+
wrapped=wrapped,
|
|
57
|
+
instance=instance,
|
|
58
|
+
args=args,
|
|
59
|
+
kwargs=kwargs,
|
|
57
60
|
)
|
|
58
61
|
|
|
59
62
|
|
|
@@ -62,7 +65,9 @@ def process_chunk(chunk: Any, ingest: IngestUnitsParams) -> None:
|
|
|
62
65
|
usage = chunk.message.usage
|
|
63
66
|
units = ingest["units"]
|
|
64
67
|
|
|
65
|
-
|
|
68
|
+
input = PayiInstrumentor.update_for_vision(usage.input_tokens, units)
|
|
69
|
+
|
|
70
|
+
units["text"] = Units(input=input, output=0)
|
|
66
71
|
|
|
67
72
|
if hasattr(usage, "cache_creation_input_tokens") and usage.cache_creation_input_tokens > 0:
|
|
68
73
|
text_cache_write = usage.cache_creation_input_tokens
|
|
@@ -77,10 +82,10 @@ def process_chunk(chunk: Any, ingest: IngestUnitsParams) -> None:
|
|
|
77
82
|
ingest["units"]["text"]["output"] = usage.output_tokens
|
|
78
83
|
|
|
79
84
|
|
|
80
|
-
def process_synchronous_response(response: Any, ingest: IngestUnitsParams, log_prompt_and_response: bool) ->
|
|
85
|
+
def process_synchronous_response(response: Any, ingest: IngestUnitsParams, log_prompt_and_response: bool, *args: Any, **kwargs: 'dict[str, Any]') -> Any: # noqa: ARG001
|
|
81
86
|
usage = response.usage
|
|
82
87
|
input = usage.input_tokens
|
|
83
|
-
|
|
88
|
+
output = usage.output_tokens
|
|
84
89
|
units: dict[str, Units] = ingest["units"]
|
|
85
90
|
|
|
86
91
|
if hasattr(usage, "cache_creation_input_tokens") and usage.cache_creation_input_tokens > 0:
|
|
@@ -91,7 +96,43 @@ def process_synchronous_response(response: Any, ingest: IngestUnitsParams, log_p
|
|
|
91
96
|
text_cache_read = usage.cache_read_input_tokens
|
|
92
97
|
units["text_cache_read"] = Units(input=text_cache_read, output=0)
|
|
93
98
|
|
|
94
|
-
|
|
99
|
+
input = PayiInstrumentor.update_for_vision(input, units)
|
|
100
|
+
|
|
101
|
+
units["text"] = Units(input=input, output=output)
|
|
95
102
|
|
|
96
103
|
if log_prompt_and_response:
|
|
97
104
|
ingest["provider_response_json"] = response.to_json()
|
|
105
|
+
|
|
106
|
+
return None
|
|
107
|
+
|
|
108
|
+
def has_image_and_get_texts(encoding: tiktoken.Encoding, content: Union[str, 'list[Any]']) -> 'tuple[bool, int]':
|
|
109
|
+
if isinstance(content, str):
|
|
110
|
+
return False, 0
|
|
111
|
+
elif isinstance(content, list): # type: ignore
|
|
112
|
+
has_image = any(item.get("type") == "image" for item in content)
|
|
113
|
+
if has_image is False:
|
|
114
|
+
return has_image, 0
|
|
115
|
+
|
|
116
|
+
token_count = sum(len(encoding.encode(item.get("text", ""))) for item in content if item.get("type") == "text")
|
|
117
|
+
return has_image, token_count
|
|
118
|
+
|
|
119
|
+
def process_request(ingest: IngestUnitsParams, kwargs: Any) -> None:
|
|
120
|
+
messages = kwargs.get("messages")
|
|
121
|
+
if not messages or len(messages) == 0:
|
|
122
|
+
return
|
|
123
|
+
|
|
124
|
+
estimated_token_count = 0
|
|
125
|
+
has_image = False
|
|
126
|
+
|
|
127
|
+
enc = tiktoken.get_encoding("cl100k_base")
|
|
128
|
+
|
|
129
|
+
for message in messages:
|
|
130
|
+
msg_has_image, msg_prompt_tokens = has_image_and_get_texts(enc, message.get('content', ''))
|
|
131
|
+
if msg_has_image:
|
|
132
|
+
has_image = True
|
|
133
|
+
estimated_token_count += msg_prompt_tokens
|
|
134
|
+
|
|
135
|
+
if not has_image or estimated_token_count == 0:
|
|
136
|
+
return
|
|
137
|
+
|
|
138
|
+
ingest["units"][PayiInstrumentor.estimated_prompt_tokens] = Units(input=estimated_token_count, output=0)
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import logging
|
|
3
|
+
from typing import Any
|
|
4
|
+
from functools import wraps
|
|
5
|
+
|
|
6
|
+
from wrapt import ObjectProxy, wrap_function_wrapper # type: ignore
|
|
7
|
+
|
|
8
|
+
from payi.types.ingest_units_params import Units, IngestUnitsParams
|
|
9
|
+
from payi.types.pay_i_common_models_api_router_header_info_param import PayICommonModelsAPIRouterHeaderInfoParam
|
|
10
|
+
|
|
11
|
+
from .instrument import IsStreaming, PayiInstrumentor
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class BedrockInstrumentor:
|
|
15
|
+
@staticmethod
|
|
16
|
+
def instrument(instrumentor: PayiInstrumentor) -> None:
|
|
17
|
+
try:
|
|
18
|
+
import boto3 # type: ignore # noqa: F401 I001
|
|
19
|
+
|
|
20
|
+
# wrap_function_wrapper(
|
|
21
|
+
# "anthropic.resources.completions",
|
|
22
|
+
# "Completions.create",
|
|
23
|
+
# chat_wrapper(instrumentor),
|
|
24
|
+
# )
|
|
25
|
+
|
|
26
|
+
wrap_function_wrapper(
|
|
27
|
+
"botocore.client",
|
|
28
|
+
"ClientCreator.create_client",
|
|
29
|
+
create_client_wrapper(instrumentor),
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
wrap_function_wrapper(
|
|
33
|
+
"botocore.session",
|
|
34
|
+
"Session.create_client",
|
|
35
|
+
create_client_wrapper(instrumentor),
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
except Exception as e:
|
|
39
|
+
logging.debug(f"Error instrumenting bedrock: {e}")
|
|
40
|
+
return
|
|
41
|
+
|
|
42
|
+
@PayiInstrumentor.payi_wrapper
|
|
43
|
+
def create_client_wrapper(instrumentor: PayiInstrumentor, wrapped: Any, instance: Any, args: Any, kwargs: Any) -> Any: # noqa: ARG001
|
|
44
|
+
if kwargs.get("service_name") != "bedrock-runtime":
|
|
45
|
+
return wrapped(*args, **kwargs)
|
|
46
|
+
|
|
47
|
+
try:
|
|
48
|
+
client: Any = wrapped(*args, **kwargs)
|
|
49
|
+
client.invoke_model = wrap_invoke(instrumentor, client.invoke_model)
|
|
50
|
+
client.invoke_model_with_response_stream = wrap_invoke_stream(instrumentor, client.invoke_model_with_response_stream)
|
|
51
|
+
client.converse = wrap_converse(instrumentor, client.converse)
|
|
52
|
+
client.converse_stream = wrap_converse_stream(instrumentor, client.converse_stream)
|
|
53
|
+
|
|
54
|
+
return client
|
|
55
|
+
except Exception as e:
|
|
56
|
+
logging.debug(f"Error instrumenting bedrock client: {e}")
|
|
57
|
+
|
|
58
|
+
return wrapped(*args, **kwargs)
|
|
59
|
+
|
|
60
|
+
class InvokeResponseWrapper(ObjectProxy): # type: ignore
|
|
61
|
+
def __init__(
|
|
62
|
+
self,
|
|
63
|
+
response: Any,
|
|
64
|
+
instrumentor: PayiInstrumentor,
|
|
65
|
+
ingest: IngestUnitsParams,
|
|
66
|
+
log_prompt_and_response: bool
|
|
67
|
+
) -> None:
|
|
68
|
+
|
|
69
|
+
super().__init__(response) # type: ignore
|
|
70
|
+
self._response = response
|
|
71
|
+
self._instrumentor = instrumentor
|
|
72
|
+
self._ingest = ingest
|
|
73
|
+
self._log_prompt_and_response = log_prompt_and_response
|
|
74
|
+
|
|
75
|
+
def read(self, amt: Any =None): # type: ignore
|
|
76
|
+
# data is array of bytes
|
|
77
|
+
data: Any = self.__wrapped__.read(amt) # type: ignore
|
|
78
|
+
response = json.loads(data)
|
|
79
|
+
|
|
80
|
+
resource = self._ingest["resource"]
|
|
81
|
+
if not resource:
|
|
82
|
+
return
|
|
83
|
+
|
|
84
|
+
input: int = 0
|
|
85
|
+
output: int = 0
|
|
86
|
+
units: dict[str, Units] = self._ingest["units"]
|
|
87
|
+
|
|
88
|
+
if resource.startswith("meta.llama3"):
|
|
89
|
+
input = response['prompt_token_count']
|
|
90
|
+
output = response['generation_token_count']
|
|
91
|
+
elif resource.startswith("anthropic."):
|
|
92
|
+
usage = response['usage']
|
|
93
|
+
input = usage['input_tokens']
|
|
94
|
+
output = usage['output_tokens']
|
|
95
|
+
units["text"] = Units(input=input, output=output)
|
|
96
|
+
|
|
97
|
+
if self._log_prompt_and_response:
|
|
98
|
+
self._ingest["provider_response_json"] = data.decode('utf-8')
|
|
99
|
+
|
|
100
|
+
self._instrumentor._ingest_units(self._ingest)
|
|
101
|
+
|
|
102
|
+
return data
|
|
103
|
+
|
|
104
|
+
def wrap_invoke(instrumentor: PayiInstrumentor, wrapped: Any) -> Any:
|
|
105
|
+
@wraps(wrapped)
|
|
106
|
+
def invoke_wrapper(*args: Any, **kwargs: 'dict[str, Any]') -> Any:
|
|
107
|
+
modelId:str = kwargs.get("modelId", "") # type: ignore
|
|
108
|
+
|
|
109
|
+
if modelId.startswith("meta.llama3") or modelId.startswith("anthropic."):
|
|
110
|
+
return instrumentor.chat_wrapper(
|
|
111
|
+
category="system.aws.bedrock",
|
|
112
|
+
process_chunk=None,
|
|
113
|
+
process_request=process_invoke_request,
|
|
114
|
+
process_synchronous_response=process_synchronous_invoke_response,
|
|
115
|
+
is_streaming=IsStreaming.false,
|
|
116
|
+
wrapped=wrapped,
|
|
117
|
+
instance=None,
|
|
118
|
+
args=args,
|
|
119
|
+
kwargs=kwargs,
|
|
120
|
+
)
|
|
121
|
+
return wrapped(*args, **kwargs)
|
|
122
|
+
|
|
123
|
+
return invoke_wrapper
|
|
124
|
+
|
|
125
|
+
def wrap_invoke_stream(instrumentor: PayiInstrumentor, wrapped: Any) -> Any:
|
|
126
|
+
@wraps(wrapped)
|
|
127
|
+
def invoke_wrapper(*args: Any, **kwargs: Any) -> Any:
|
|
128
|
+
modelId:str = kwargs.get("modelId", "") # type: ignore
|
|
129
|
+
|
|
130
|
+
if modelId.startswith("meta.llama3") or modelId.startswith("anthropic."):
|
|
131
|
+
return instrumentor.chat_wrapper(
|
|
132
|
+
category="system.aws.bedrock",
|
|
133
|
+
process_chunk=process_invoke_streaming_anthropic_chunk if modelId.startswith("anthropic.") else process_invoke_streaming_llama_chunk,
|
|
134
|
+
process_request=process_invoke_request,
|
|
135
|
+
process_synchronous_response=None,
|
|
136
|
+
is_streaming=IsStreaming.true,
|
|
137
|
+
wrapped=wrapped,
|
|
138
|
+
instance=None,
|
|
139
|
+
args=args,
|
|
140
|
+
kwargs=kwargs,
|
|
141
|
+
)
|
|
142
|
+
return wrapped(*args, **kwargs)
|
|
143
|
+
|
|
144
|
+
return invoke_wrapper
|
|
145
|
+
|
|
146
|
+
def wrap_converse(instrumentor: PayiInstrumentor, wrapped: Any) -> Any:
|
|
147
|
+
@wraps(wrapped)
|
|
148
|
+
def invoke_wrapper(*args: Any, **kwargs: 'dict[str, Any]') -> Any:
|
|
149
|
+
modelId:str = kwargs.get("modelId", "") # type: ignore
|
|
150
|
+
|
|
151
|
+
if modelId.startswith("meta.llama3") or modelId.startswith("anthropic."):
|
|
152
|
+
return instrumentor.chat_wrapper(
|
|
153
|
+
category="system.aws.bedrock",
|
|
154
|
+
process_chunk=None,
|
|
155
|
+
process_request=process_converse_request,
|
|
156
|
+
process_synchronous_response=process_synchronous_converse_response,
|
|
157
|
+
is_streaming=IsStreaming.false,
|
|
158
|
+
wrapped=wrapped,
|
|
159
|
+
instance=None,
|
|
160
|
+
args=args,
|
|
161
|
+
kwargs=kwargs,
|
|
162
|
+
)
|
|
163
|
+
return wrapped(*args, **kwargs)
|
|
164
|
+
|
|
165
|
+
return invoke_wrapper
|
|
166
|
+
|
|
167
|
+
def wrap_converse_stream(instrumentor: PayiInstrumentor, wrapped: Any) -> Any:
|
|
168
|
+
@wraps(wrapped)
|
|
169
|
+
def invoke_wrapper(*args: Any, **kwargs: Any) -> Any:
|
|
170
|
+
modelId:str = kwargs.get("modelId", "") # type: ignore
|
|
171
|
+
|
|
172
|
+
if modelId.startswith("meta.llama3") or modelId.startswith("anthropic."):
|
|
173
|
+
return instrumentor.chat_wrapper(
|
|
174
|
+
category="system.aws.bedrock",
|
|
175
|
+
process_chunk=process_converse_streaming_chunk,
|
|
176
|
+
process_request=process_converse_request,
|
|
177
|
+
process_synchronous_response=None,
|
|
178
|
+
is_streaming=IsStreaming.true,
|
|
179
|
+
wrapped=wrapped,
|
|
180
|
+
instance=None,
|
|
181
|
+
args=args,
|
|
182
|
+
kwargs=kwargs,
|
|
183
|
+
)
|
|
184
|
+
return wrapped(*args, **kwargs)
|
|
185
|
+
|
|
186
|
+
return invoke_wrapper
|
|
187
|
+
|
|
188
|
+
def process_invoke_streaming_anthropic_chunk(chunk: str, ingest: IngestUnitsParams) -> None:
|
|
189
|
+
chunk_dict = json.loads(chunk)
|
|
190
|
+
type = chunk_dict.get("type", "")
|
|
191
|
+
|
|
192
|
+
if type == "message_start":
|
|
193
|
+
usage = chunk_dict['message']['usage']
|
|
194
|
+
units = ingest["units"]
|
|
195
|
+
|
|
196
|
+
input = PayiInstrumentor.update_for_vision(usage['input_tokens'], units)
|
|
197
|
+
|
|
198
|
+
units["text"] = Units(input=input, output=0)
|
|
199
|
+
|
|
200
|
+
text_cache_write: int = usage.get("cache_creation_input_tokens", 0)
|
|
201
|
+
if text_cache_write > 0:
|
|
202
|
+
units["text_cache_write"] = Units(input=text_cache_write, output=0)
|
|
203
|
+
|
|
204
|
+
text_cache_read: int = usage.get("cache_read_input_tokens", 0)
|
|
205
|
+
if text_cache_read > 0:
|
|
206
|
+
units["text_cache_read"] = Units(input=text_cache_read, output=0)
|
|
207
|
+
|
|
208
|
+
elif type == "message_delta":
|
|
209
|
+
usage = chunk_dict['usage']
|
|
210
|
+
ingest["units"]["text"]["output"] = usage['output_tokens']
|
|
211
|
+
|
|
212
|
+
def process_invoke_streaming_llama_chunk(chunk: str, ingest: IngestUnitsParams) -> None:
|
|
213
|
+
chunk_dict = json.loads(chunk)
|
|
214
|
+
metrics = chunk_dict.get("amazon-bedrock-invocationMetrics", {})
|
|
215
|
+
if metrics:
|
|
216
|
+
input = metrics.get("inputTokenCount", 0)
|
|
217
|
+
output = metrics.get("outputTokenCount", 0)
|
|
218
|
+
ingest["units"]["text"] = Units(input=input, output=output)
|
|
219
|
+
|
|
220
|
+
def process_synchronous_invoke_response(
|
|
221
|
+
response: Any,
|
|
222
|
+
ingest: IngestUnitsParams,
|
|
223
|
+
log_prompt_and_response: bool,
|
|
224
|
+
instrumentor: PayiInstrumentor,
|
|
225
|
+
**kargs: Any) -> Any: # noqa: ARG001
|
|
226
|
+
|
|
227
|
+
metadata = response.get("ResponseMetadata", {})
|
|
228
|
+
|
|
229
|
+
# request_id = metadata.get("RequestId", "")
|
|
230
|
+
# if request_id:
|
|
231
|
+
# ingest["provider_request_id"] = request_id
|
|
232
|
+
|
|
233
|
+
response_headers = metadata.get("HTTPHeaders", {}).copy()
|
|
234
|
+
if response_headers:
|
|
235
|
+
ingest["provider_response_headers"] = [PayICommonModelsAPIRouterHeaderInfoParam(name=k, value=v) for k, v in response_headers.items()]
|
|
236
|
+
|
|
237
|
+
response["body"] = InvokeResponseWrapper(
|
|
238
|
+
response=response["body"],
|
|
239
|
+
instrumentor=instrumentor,
|
|
240
|
+
ingest=ingest,
|
|
241
|
+
log_prompt_and_response=log_prompt_and_response)
|
|
242
|
+
|
|
243
|
+
return response
|
|
244
|
+
|
|
245
|
+
def process_invoke_request(ingest: IngestUnitsParams, kwargs: Any) -> None: # noqa: ARG001
|
|
246
|
+
return
|
|
247
|
+
|
|
248
|
+
def process_converse_streaming_chunk(chunk: 'dict[str, Any]', ingest: IngestUnitsParams) -> None:
|
|
249
|
+
metadata = chunk.get("metadata", {})
|
|
250
|
+
|
|
251
|
+
if metadata:
|
|
252
|
+
usage = metadata['usage']
|
|
253
|
+
input = usage["inputTokens"]
|
|
254
|
+
output = usage["outputTokens"]
|
|
255
|
+
ingest["units"]["text"] = Units(input=input, output=output)
|
|
256
|
+
|
|
257
|
+
def process_synchronous_converse_response(
|
|
258
|
+
response: 'dict[str, Any]',
|
|
259
|
+
ingest: IngestUnitsParams,
|
|
260
|
+
log_prompt_and_response: bool,
|
|
261
|
+
**kargs: Any) -> Any: # noqa: ARG001
|
|
262
|
+
|
|
263
|
+
usage = response["usage"]
|
|
264
|
+
input = usage["inputTokens"]
|
|
265
|
+
output = usage["outputTokens"]
|
|
266
|
+
|
|
267
|
+
units: dict[str, Units] = ingest["units"]
|
|
268
|
+
units["text"] = Units(input=input, output=output)
|
|
269
|
+
|
|
270
|
+
metadata = response.get("ResponseMetadata", {})
|
|
271
|
+
|
|
272
|
+
# request_id = metadata.get("RequestId", "")
|
|
273
|
+
# if request_id:
|
|
274
|
+
# ingest["provider_request_id"] = request_id
|
|
275
|
+
|
|
276
|
+
response_headers = metadata.get("HTTPHeaders", {})
|
|
277
|
+
if response_headers:
|
|
278
|
+
ingest["provider_response_headers"] = [PayICommonModelsAPIRouterHeaderInfoParam(name=k, value=v) for k, v in response_headers.items()]
|
|
279
|
+
|
|
280
|
+
if log_prompt_and_response:
|
|
281
|
+
response_without_metadata = response.copy()
|
|
282
|
+
response_without_metadata.pop("ResponseMetadata", None)
|
|
283
|
+
ingest["provider_response_json"] = json.dumps(response_without_metadata)
|
|
284
|
+
|
|
285
|
+
return None
|
|
286
|
+
|
|
287
|
+
def process_converse_request(ingest: IngestUnitsParams, kwargs: Any) -> None: # noqa: ARG001
|
|
288
|
+
return
|