From e7ce5460398adcefa9c1c9fcb8f927751f0c5789 Mon Sep 17 00:00:00 2001 From: Nik-Reddy Date: Sun, 14 Jun 2026 02:01:24 -0700 Subject: [PATCH] Add Cohere instrumentation package scaffolding --- eachdist.ini | 1 + instrumentation/README.md | 1 + .../.changelog/.gitignore | 1 + .../.changelog/102.added | 1 + .../LICENSE | 201 ++++++++++++++++++ .../README.rst | 62 ++++++ .../examples/manual/.env | 11 + .../examples/manual/README.rst | 38 ++++ .../examples/manual/main.py | 71 +++++++ .../examples/manual/requirements.txt | 5 + .../examples/zero-code/.env | 14 ++ .../examples/zero-code/README.rst | 45 ++++ .../examples/zero-code/main.py | 26 +++ .../examples/zero-code/requirements.txt | 6 + .../pyproject.toml | 88 ++++++++ .../instrumentation/genai/cohere/__init__.py | 83 ++++++++ .../instrumentation/genai/cohere/package.py | 4 + .../instrumentation/genai/cohere/patch.py | 2 + .../instrumentation/genai/cohere/version.py | 4 + .../tests/__init__.py | 2 + .../tests/conftest.py | 39 ++++ .../tests/requirements.latest.txt | 45 ++++ .../tests/requirements.oldest.txt | 25 +++ .../tests/test_instrumentor.py | 107 ++++++++++ pyproject.toml | 5 + tox.ini | 15 ++ uv.lock | 184 +++++++++++++++- 27 files changed, 1085 insertions(+), 1 deletion(-) create mode 100644 instrumentation/opentelemetry-instrumentation-genai-cohere/.changelog/.gitignore create mode 100644 instrumentation/opentelemetry-instrumentation-genai-cohere/.changelog/102.added create mode 100644 instrumentation/opentelemetry-instrumentation-genai-cohere/LICENSE create mode 100644 instrumentation/opentelemetry-instrumentation-genai-cohere/README.rst create mode 100644 instrumentation/opentelemetry-instrumentation-genai-cohere/examples/manual/.env create mode 100644 instrumentation/opentelemetry-instrumentation-genai-cohere/examples/manual/README.rst create mode 100644 instrumentation/opentelemetry-instrumentation-genai-cohere/examples/manual/main.py create mode 100644 instrumentation/opentelemetry-instrumentation-genai-cohere/examples/manual/requirements.txt create mode 100644 instrumentation/opentelemetry-instrumentation-genai-cohere/examples/zero-code/.env create mode 100644 instrumentation/opentelemetry-instrumentation-genai-cohere/examples/zero-code/README.rst create mode 100644 instrumentation/opentelemetry-instrumentation-genai-cohere/examples/zero-code/main.py create mode 100644 instrumentation/opentelemetry-instrumentation-genai-cohere/examples/zero-code/requirements.txt create mode 100644 instrumentation/opentelemetry-instrumentation-genai-cohere/pyproject.toml create mode 100644 instrumentation/opentelemetry-instrumentation-genai-cohere/src/opentelemetry/instrumentation/genai/cohere/__init__.py create mode 100644 instrumentation/opentelemetry-instrumentation-genai-cohere/src/opentelemetry/instrumentation/genai/cohere/package.py create mode 100644 instrumentation/opentelemetry-instrumentation-genai-cohere/src/opentelemetry/instrumentation/genai/cohere/patch.py create mode 100644 instrumentation/opentelemetry-instrumentation-genai-cohere/src/opentelemetry/instrumentation/genai/cohere/version.py create mode 100644 instrumentation/opentelemetry-instrumentation-genai-cohere/tests/__init__.py create mode 100644 instrumentation/opentelemetry-instrumentation-genai-cohere/tests/conftest.py create mode 100644 instrumentation/opentelemetry-instrumentation-genai-cohere/tests/requirements.latest.txt create mode 100644 instrumentation/opentelemetry-instrumentation-genai-cohere/tests/requirements.oldest.txt create mode 100644 instrumentation/opentelemetry-instrumentation-genai-cohere/tests/test_instrumentor.py diff --git a/eachdist.ini b/eachdist.ini index 65f83f553..e4a93786e 100644 --- a/eachdist.ini +++ b/eachdist.ini @@ -17,6 +17,7 @@ packages= # Packages the release workflows may publish (eachdist.py list-release-packages). packages= opentelemetry-instrumentation-genai-anthropic + opentelemetry-instrumentation-genai-cohere opentelemetry-instrumentation-google-genai opentelemetry-instrumentation-genai-langchain opentelemetry-instrumentation-genai-openai diff --git a/instrumentation/README.md b/instrumentation/README.md index 48ee952fe..61981d9c1 100644 --- a/instrumentation/README.md +++ b/instrumentation/README.md @@ -3,6 +3,7 @@ | --------------- | ------------------ | --------------- | -------------- | | [opentelemetry-instrumentation-genai-anthropic](./opentelemetry-instrumentation-genai-anthropic) | anthropic >= 0.16.0 | No | development | [opentelemetry-instrumentation-genai-claude-agent-sdk](./opentelemetry-instrumentation-genai-claude-agent-sdk) | claude-agent-sdk >= 0.1.14 | No | development +| [opentelemetry-instrumentation-genai-cohere](./opentelemetry-instrumentation-genai-cohere) | cohere >= 5.13.0 | No | development | [opentelemetry-instrumentation-genai-langchain](./opentelemetry-instrumentation-genai-langchain) | langchain >= 0.3.21 | No | development | [opentelemetry-instrumentation-genai-openai](./opentelemetry-instrumentation-genai-openai) | openai >= 1.26.0 | Yes | development | [opentelemetry-instrumentation-genai-openai-agents](./opentelemetry-instrumentation-genai-openai-agents) | openai-agents >= 0.3.3 | No | development diff --git a/instrumentation/opentelemetry-instrumentation-genai-cohere/.changelog/.gitignore b/instrumentation/opentelemetry-instrumentation-genai-cohere/.changelog/.gitignore new file mode 100644 index 000000000..f935021a8 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-genai-cohere/.changelog/.gitignore @@ -0,0 +1 @@ +!.gitignore diff --git a/instrumentation/opentelemetry-instrumentation-genai-cohere/.changelog/102.added b/instrumentation/opentelemetry-instrumentation-genai-cohere/.changelog/102.added new file mode 100644 index 000000000..cc499d0b7 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-genai-cohere/.changelog/102.added @@ -0,0 +1 @@ +Add Cohere instrumentation package scaffolding diff --git a/instrumentation/opentelemetry-instrumentation-genai-cohere/LICENSE b/instrumentation/opentelemetry-instrumentation-genai-cohere/LICENSE new file mode 100644 index 000000000..4f0c128f3 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-genai-cohere/LICENSE @@ -0,0 +1,201 @@ +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Support. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright The OpenTelemetry Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/instrumentation/opentelemetry-instrumentation-genai-cohere/README.rst b/instrumentation/opentelemetry-instrumentation-genai-cohere/README.rst new file mode 100644 index 000000000..1a96c0e90 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-genai-cohere/README.rst @@ -0,0 +1,62 @@ +OpenTelemetry Cohere Instrumentation +==================================== + +This library allows tracing LLM requests made by the +`Cohere Python SDK `_. + +Installation +------------ + +:: + + pip install opentelemetry-instrumentation-genai-cohere + +If you don't have a Cohere application yet, try our `examples `_ +which only need a valid Cohere API key. + +Check out the `zero-code example `_ for a quick start. + +Usage +----- + +This section describes how to set up Cohere instrumentation if you're setting OpenTelemetry up manually. +Check out the `manual example `_ for more details. + +.. code-block:: python + + from opentelemetry.instrumentation.genai.cohere import CohereInstrumentor + import cohere + + # Instrument Cohere + CohereInstrumentor().instrument() + + # Use the Cohere V2 client as normal + co = cohere.ClientV2() + response = co.chat( + model="command-r-plus-08-2024", + messages=[{"role": "user", "content": "hello world!"}], + ) + print(response) + + +Configuration +------------- + +Capture Message Content +*********************** + +By default, prompts and completions are not captured. To enable message content capture, +set the environment variable: + +:: + + export OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true + + +References +---------- + +* `OpenTelemetry Project `_ +* `OpenTelemetry GenAI semantic conventions `_ +* `Cohere Python SDK `_ +* `Cohere Documentation `_ diff --git a/instrumentation/opentelemetry-instrumentation-genai-cohere/examples/manual/.env b/instrumentation/opentelemetry-instrumentation-genai-cohere/examples/manual/.env new file mode 100644 index 000000000..ababe00ff --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-genai-cohere/examples/manual/.env @@ -0,0 +1,11 @@ +# Update this with your real Cohere API key +CO_API_KEY=YOUR_COHERE_API_KEY + +# Uncomment and change to your OTLP endpoint +# OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317 +# OTEL_EXPORTER_OTLP_PROTOCOL=grpc + +OTEL_SERVICE_NAME=opentelemetry-python-cohere + +# Change to 'false' to hide prompt and completion content +OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true diff --git a/instrumentation/opentelemetry-instrumentation-genai-cohere/examples/manual/README.rst b/instrumentation/opentelemetry-instrumentation-genai-cohere/examples/manual/README.rst new file mode 100644 index 000000000..a78d3c290 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-genai-cohere/examples/manual/README.rst @@ -0,0 +1,38 @@ +OpenTelemetry Cohere Instrumentation Example +============================================ + +This is a placeholder for an example showing how to instrument Cohere +calls when configuring OpenTelemetry SDK and Instrumentations manually. + +The ``CohereInstrumentor`` shipped in this release is scaffold-only: +calling ``.instrument()`` sets up tracer, logger, and meter providers +but does not yet wrap any Cohere client methods. Chat completions and +streaming wrapping land in a follow-up PR. + +Setup +----- + +Minimally, update the `.env <.env>`_ file with your ``CO_API_KEY``. An +OTLP compatible endpoint should be listening for traces and logs on +http://localhost:4317. If not, update ``OTEL_EXPORTER_OTLP_ENDPOINT`` as well. + +Next, set up a virtual environment like this: + +:: + + python3 -m venv .venv + source .venv/bin/activate + pip install "python-dotenv[cli]" + pip install -r requirements.txt + +Run +--- + +Run the example like this: + +:: + + dotenv run -- python main.py + +Once the follow-up PR lands, you will see Cohere chat completions +exported as spans and logs to your configured observability tool. diff --git a/instrumentation/opentelemetry-instrumentation-genai-cohere/examples/manual/main.py b/instrumentation/opentelemetry-instrumentation-genai-cohere/examples/manual/main.py new file mode 100644 index 000000000..e0c38449b --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-genai-cohere/examples/manual/main.py @@ -0,0 +1,71 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +# pylint: skip-file +"""Placeholder example for Cohere instrumentation with manual OpenTelemetry setup. + +The CohereInstrumentor shipped in this release is scaffold-only; it does +not yet wrap any client methods. Chat completions wrapping lands in a +follow-up PR. This file shows the planned wiring shape so the example +directory mirrors other instrumentation packages. +""" + +import cohere + +# NOTE: OpenTelemetry Python Logs and Events APIs are in beta +from opentelemetry import _logs, metrics, trace +from opentelemetry.exporter.otlp.proto.grpc._log_exporter import ( + OTLPLogExporter, +) +from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import ( + OTLPMetricExporter, +) +from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import ( + OTLPSpanExporter, +) +from opentelemetry.instrumentation.genai.cohere import CohereInstrumentor +from opentelemetry.sdk._logs import LoggerProvider +from opentelemetry.sdk._logs.export import BatchLogRecordProcessor +from opentelemetry.sdk.metrics import MeterProvider +from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader +from opentelemetry.sdk.trace import TracerProvider +from opentelemetry.sdk.trace.export import BatchSpanProcessor + +# configure tracing +trace.set_tracer_provider(TracerProvider()) +trace.get_tracer_provider().add_span_processor( + BatchSpanProcessor(OTLPSpanExporter()) +) + +# configure logging and events +_logs.set_logger_provider(LoggerProvider()) +_logs.get_logger_provider().add_log_record_processor( + BatchLogRecordProcessor(OTLPLogExporter()) +) + +# configure metrics +metrics.set_meter_provider( + MeterProvider( + metric_readers=[ + PeriodicExportingMetricReader( + OTLPMetricExporter(), + ), + ] + ) +) + +# instrument Cohere (no-op until the chat completions wrapping PR lands) +CohereInstrumentor().instrument() + + +def main() -> None: + co = cohere.ClientV2() + response = co.chat( + model="command-r-plus-08-2024", + messages=[{"role": "user", "content": "hello world!"}], + ) + print(response) + + +if __name__ == "__main__": + main() diff --git a/instrumentation/opentelemetry-instrumentation-genai-cohere/examples/manual/requirements.txt b/instrumentation/opentelemetry-instrumentation-genai-cohere/examples/manual/requirements.txt new file mode 100644 index 000000000..61022161d --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-genai-cohere/examples/manual/requirements.txt @@ -0,0 +1,5 @@ +cohere>=5.13.0 + +opentelemetry-sdk~=1.42.0 +opentelemetry-exporter-otlp-proto-grpc~=1.42.0 +opentelemetry-instrumentation-genai-cohere diff --git a/instrumentation/opentelemetry-instrumentation-genai-cohere/examples/zero-code/.env b/instrumentation/opentelemetry-instrumentation-genai-cohere/examples/zero-code/.env new file mode 100644 index 000000000..0911767e1 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-genai-cohere/examples/zero-code/.env @@ -0,0 +1,14 @@ +# Update this with your real Cohere API key +CO_API_KEY=YOUR_COHERE_API_KEY + +# Uncomment and change to your OTLP endpoint +# OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317 +# OTEL_EXPORTER_OTLP_PROTOCOL=grpc + +OTEL_SERVICE_NAME=opentelemetry-python-cohere + +# Uncomment if your OTLP endpoint doesn't support logs +# OTEL_LOGS_EXPORTER=console + +# Change to 'false' to hide prompt and completion content +OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true diff --git a/instrumentation/opentelemetry-instrumentation-genai-cohere/examples/zero-code/README.rst b/instrumentation/opentelemetry-instrumentation-genai-cohere/examples/zero-code/README.rst new file mode 100644 index 000000000..09d641969 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-genai-cohere/examples/zero-code/README.rst @@ -0,0 +1,45 @@ +OpenTelemetry Cohere Zero-Code Instrumentation Example +====================================================== + +This is a placeholder for an example showing how to instrument Cohere +calls with zero code changes, using ``opentelemetry-instrument``. + +The ``CohereInstrumentor`` shipped in this release is scaffold-only: +the entry point is registered under ``opentelemetry_instrumentor`` so +``opentelemetry-instrument`` discovers it, but no Cohere client methods +are wrapped yet. Chat completions wrapping lands in a follow-up PR. + +Setup +----- + +Minimally, update the `.env <.env>`_ file with your ``CO_API_KEY``. An +OTLP compatible endpoint should be listening for traces and logs on +http://localhost:4317. If not, update ``OTEL_EXPORTER_OTLP_ENDPOINT`` as well. + +Next, set up a virtual environment like this: + +:: + + python3 -m venv .venv + source .venv/bin/activate + pip install "python-dotenv[cli]" + pip install -r requirements.txt + +Run +--- + +Run the example with zero-code instrumentation like this: + +:: + + dotenv run -- opentelemetry-instrument python main.py + +Once the follow-up PR lands, you will see Cohere chat completions +exported as spans and logs without any changes to ``main.py``. + +Learn More +---------- + +See the `OpenTelemetry Python automatic instrumentation docs +`_ for more +information about zero-code instrumentation. diff --git a/instrumentation/opentelemetry-instrumentation-genai-cohere/examples/zero-code/main.py b/instrumentation/opentelemetry-instrumentation-genai-cohere/examples/zero-code/main.py new file mode 100644 index 000000000..70d9090b1 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-genai-cohere/examples/zero-code/main.py @@ -0,0 +1,26 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +# pylint: skip-file +"""Placeholder example for Cohere instrumentation via opentelemetry-instrument. + +The CohereInstrumentor shipped in this release is scaffold-only; it does +not yet wrap any client methods. Chat completions wrapping lands in a +follow-up PR. This file shows the planned client surface so the example +directory mirrors other instrumentation packages. +""" + +import cohere + + +def main() -> None: + co = cohere.ClientV2() + response = co.chat( + model="command-r-plus-08-2024", + messages=[{"role": "user", "content": "hello world!"}], + ) + print(response) + + +if __name__ == "__main__": + main() diff --git a/instrumentation/opentelemetry-instrumentation-genai-cohere/examples/zero-code/requirements.txt b/instrumentation/opentelemetry-instrumentation-genai-cohere/examples/zero-code/requirements.txt new file mode 100644 index 000000000..440fd9094 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-genai-cohere/examples/zero-code/requirements.txt @@ -0,0 +1,6 @@ +cohere>=5.13.0 + +opentelemetry-sdk~=1.42.0 +opentelemetry-exporter-otlp-proto-grpc~=1.42.0 +opentelemetry-distro~=0.57b0 +opentelemetry-instrumentation-genai-cohere diff --git a/instrumentation/opentelemetry-instrumentation-genai-cohere/pyproject.toml b/instrumentation/opentelemetry-instrumentation-genai-cohere/pyproject.toml new file mode 100644 index 000000000..167c8534e --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-genai-cohere/pyproject.toml @@ -0,0 +1,88 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "opentelemetry-instrumentation-genai-cohere" +dynamic = ["version"] +description = "OpenTelemetry Cohere instrumentation" +readme = "README.rst" +license = "Apache-2.0" +requires-python = ">=3.10" +authors = [ + { name = "OpenTelemetry Authors", email = "cncf-opentelemetry-contributors@lists.cncf.io" }, +] +classifiers = [ + "Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", +] +dependencies = [ + "opentelemetry-api ~= 1.43", + "opentelemetry-instrumentation >= 0.64b0, <1", + "opentelemetry-semantic-conventions >= 0.64b0, <1", + "opentelemetry-util-genai >= 1.0b0, <2", +] + +[project.optional-dependencies] +instruments = ["cohere >= 5.13.0"] + +[project.entry-points.opentelemetry_instrumentor] +cohere = "opentelemetry.instrumentation.genai.cohere:CohereInstrumentor" + +[project.urls] +Homepage = "https://github.com/open-telemetry/opentelemetry-python-genai/tree/main/instrumentation/opentelemetry-instrumentation-genai-cohere" +Repository = "https://github.com/open-telemetry/opentelemetry-python-genai" + +[tool.hatch.version] +path = "src/opentelemetry/instrumentation/genai/cohere/version.py" + +[tool.hatch.build.targets.sdist] +include = ["/src", "/tests", "/examples"] + +[tool.hatch.build.targets.wheel] +packages = ["src/opentelemetry"] + +[tool.pytest.ini_options] +testpaths = ["tests"] + +[tool.towncrier] +directory = ".changelog" +filename = "CHANGELOG.md" +start_string = "\n" +template = "../../scripts/changelog_template.j2" +issue_format = "[#{issue}](https://github.com/open-telemetry/opentelemetry-python-genai/pull/{issue})" +wrap = true +issue_pattern = "^(\\d+)" + +[[tool.towncrier.type]] +directory = "added" +name = "Added" +showcontent = true + +[[tool.towncrier.type]] +directory = "changed" +name = "Changed" +showcontent = true + +[[tool.towncrier.type]] +directory = "deprecated" +name = "Deprecated" +showcontent = true + +[[tool.towncrier.type]] +directory = "removed" +name = "Removed" +showcontent = true + +[[tool.towncrier.type]] +directory = "fixed" +name = "Fixed" +showcontent = true diff --git a/instrumentation/opentelemetry-instrumentation-genai-cohere/src/opentelemetry/instrumentation/genai/cohere/__init__.py b/instrumentation/opentelemetry-instrumentation-genai-cohere/src/opentelemetry/instrumentation/genai/cohere/__init__.py new file mode 100644 index 000000000..f0c7c5112 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-genai-cohere/src/opentelemetry/instrumentation/genai/cohere/__init__.py @@ -0,0 +1,83 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +""" +OpenTelemetry Cohere Instrumentation +==================================== + +Instrumentation for the `Cohere Python SDK +`_. + +Usage +----- + +.. code-block:: python + + from opentelemetry.instrumentation.genai.cohere import CohereInstrumentor + import cohere + + # Enable instrumentation + CohereInstrumentor().instrument() + + # Use the Cohere V2 client normally + co = cohere.ClientV2() + response = co.chat( + model="command-r-plus-08-2024", + messages=[{"role": "user", "content": "hello world!"}], + ) + print(response) + +Configuration +------------- + +Message content capture can be enabled by setting the environment variable: +``OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true`` + +API +--- +""" + +from typing import Any, Collection + +from opentelemetry.instrumentation.genai.cohere.package import ( + _instruments, +) +from opentelemetry.instrumentation.instrumentor import BaseInstrumentor +from opentelemetry.util.genai.handler import TelemetryHandler + + +class CohereInstrumentor(BaseInstrumentor): + """An instrumentor for the Cohere Python SDK.""" + + def __init__(self) -> None: + super().__init__() + + # pylint: disable=no-self-use + def instrumentation_dependencies(self) -> Collection[str]: + return _instruments + + def _instrument(self, **kwargs: Any) -> None: + """Enable Cohere instrumentation. + + Args: + **kwargs: Optional arguments + - tracer_provider: TracerProvider instance + - meter_provider: MeterProvider instance + - logger_provider: LoggerProvider instance + """ + tracer_provider = kwargs.get("tracer_provider") + meter_provider = kwargs.get("meter_provider") + logger_provider = kwargs.get("logger_provider") + + handler = TelemetryHandler( + tracer_provider=tracer_provider, + meter_provider=meter_provider, + logger_provider=logger_provider, + ) + + # Patching will be added in a follow-up PR + self._handler = handler + + def _uninstrument(self, **kwargs: Any) -> None: + """Disable Cohere instrumentation.""" + # Unpatching will be added in a follow-up PR diff --git a/instrumentation/opentelemetry-instrumentation-genai-cohere/src/opentelemetry/instrumentation/genai/cohere/package.py b/instrumentation/opentelemetry-instrumentation-genai-cohere/src/opentelemetry/instrumentation/genai/cohere/package.py new file mode 100644 index 000000000..30db89371 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-genai-cohere/src/opentelemetry/instrumentation/genai/cohere/package.py @@ -0,0 +1,4 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +_instruments = ("cohere >= 5.13.0",) diff --git a/instrumentation/opentelemetry-instrumentation-genai-cohere/src/opentelemetry/instrumentation/genai/cohere/patch.py b/instrumentation/opentelemetry-instrumentation-genai-cohere/src/opentelemetry/instrumentation/genai/cohere/patch.py new file mode 100644 index 000000000..e57cf4aba --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-genai-cohere/src/opentelemetry/instrumentation/genai/cohere/patch.py @@ -0,0 +1,2 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 diff --git a/instrumentation/opentelemetry-instrumentation-genai-cohere/src/opentelemetry/instrumentation/genai/cohere/version.py b/instrumentation/opentelemetry-instrumentation-genai-cohere/src/opentelemetry/instrumentation/genai/cohere/version.py new file mode 100644 index 000000000..cefb388ff --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-genai-cohere/src/opentelemetry/instrumentation/genai/cohere/version.py @@ -0,0 +1,4 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +__version__ = "1.0b0.dev" diff --git a/instrumentation/opentelemetry-instrumentation-genai-cohere/tests/__init__.py b/instrumentation/opentelemetry-instrumentation-genai-cohere/tests/__init__.py new file mode 100644 index 000000000..e57cf4aba --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-genai-cohere/tests/__init__.py @@ -0,0 +1,2 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 diff --git a/instrumentation/opentelemetry-instrumentation-genai-cohere/tests/conftest.py b/instrumentation/opentelemetry-instrumentation-genai-cohere/tests/conftest.py new file mode 100644 index 000000000..923a24a36 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-genai-cohere/tests/conftest.py @@ -0,0 +1,39 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +"""Test configuration and fixtures for Cohere instrumentation tests.""" +# pylint: disable=redefined-outer-name + +import pytest + +pytest_plugins = ["opentelemetry.test_util_genai.fixtures"] + + +@pytest.fixture +def instrument_cohere(tracer_provider, logger_provider, meter_provider): + """Fixture to instrument Cohere with test providers.""" + # pylint: disable=import-outside-toplevel + from opentelemetry.instrumentation.genai.cohere import ( # noqa: PLC0415 + CohereInstrumentor, + ) + + instrumentor = CohereInstrumentor() + instrumentor.instrument( + tracer_provider=tracer_provider, + logger_provider=logger_provider, + meter_provider=meter_provider, + ) + yield instrumentor + instrumentor.uninstrument() + + +@pytest.fixture +def uninstrument_cohere(): + """Fixture to ensure Cohere is uninstrumented after test.""" + yield + # pylint: disable=import-outside-toplevel + from opentelemetry.instrumentation.genai.cohere import ( # noqa: PLC0415 + CohereInstrumentor, + ) + + CohereInstrumentor().uninstrument() diff --git a/instrumentation/opentelemetry-instrumentation-genai-cohere/tests/requirements.latest.txt b/instrumentation/opentelemetry-instrumentation-genai-cohere/tests/requirements.latest.txt new file mode 100644 index 000000000..6aa80ebe4 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-genai-cohere/tests/requirements.latest.txt @@ -0,0 +1,45 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# ******************************** +# WARNING: NOT HERMETIC !!!!!!!!!! +# ******************************** +# +# This "requirements.txt" is installed in conjunction +# with multiple other dependencies in the top-level "tox.ini" +# file. In particular, please see: +# +# cohere-latest: {[testenv]test_deps} +# cohere-latest: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-genai-cohere/tests/requirements.latest.txt +# +# This provides additional dependencies, namely: +# +# opentelemetry-api +# opentelemetry-sdk +# opentelemetry-semantic-conventions +# opentelemetry-instrumentation +# +# ... with a "dev" version based on the latest distribution. +# +# +# This variant of the requirements aims to test the system using +# the newest supported version of external dependencies. + +cohere +wrapt==2.2.1 +# test with the latest version of opentelemetry-api, sdk, semantic conventions, and instrumentation + +-e util/opentelemetry-util-genai +-e instrumentation/opentelemetry-instrumentation-genai-cohere diff --git a/instrumentation/opentelemetry-instrumentation-genai-cohere/tests/requirements.oldest.txt b/instrumentation/opentelemetry-instrumentation-genai-cohere/tests/requirements.oldest.txt new file mode 100644 index 000000000..34eb366f7 --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-genai-cohere/tests/requirements.oldest.txt @@ -0,0 +1,25 @@ +# Copyright The OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Oldest test-only dependency pins. +# +# The package's own declared deps (cohere via the instruments extra, opentelemetry-api, +# opentelemetry-instrumentation, opentelemetry-semantic-conventions, opentelemetry-util-genai) +# are resolved to their pyproject.toml floors by UV_RESOLUTION=lowest-direct on the oldest tox +# factor, so they are NOT pinned here -- pyproject.toml is the single source of truth. The +# OpenTelemetry SDK and test utilities come transitively from opentelemetry-test-util-genai, which +# every oldest env installs. Pin here only test-only deps that nothing else already provides. +# +# There is currently nothing to pin: cohere has no test-only dependency that isn't already +# provided by a declared bound or by the shared test fixtures. diff --git a/instrumentation/opentelemetry-instrumentation-genai-cohere/tests/test_instrumentor.py b/instrumentation/opentelemetry-instrumentation-genai-cohere/tests/test_instrumentor.py new file mode 100644 index 000000000..e645dfb9f --- /dev/null +++ b/instrumentation/opentelemetry-instrumentation-genai-cohere/tests/test_instrumentor.py @@ -0,0 +1,107 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +"""Tests for the CohereInstrumentor class.""" + +from opentelemetry.instrumentation.genai.cohere import ( + CohereInstrumentor, +) + + +def test_instrumentor_instantiation(): + """Test that the instrumentor can be instantiated.""" + instrumentor = CohereInstrumentor() + assert instrumentor is not None + assert isinstance(instrumentor, CohereInstrumentor) + + +def test_instrumentation_dependencies(): + """Test that instrumentation dependencies are correctly reported.""" + instrumentor = CohereInstrumentor() + dependencies = instrumentor.instrumentation_dependencies() + + assert dependencies is not None + assert len(dependencies) > 0 + assert "cohere >= 5.13.0" in dependencies + + +def test_instrument_uninstrument_cycle( + tracer_provider, logger_provider, meter_provider +): + """Test that instrument() and uninstrument() can be called multiple times.""" + instrumentor = CohereInstrumentor() + + # First instrumentation + instrumentor.instrument( + tracer_provider=tracer_provider, + logger_provider=logger_provider, + meter_provider=meter_provider, + ) + + # First uninstrumentation + instrumentor.uninstrument() + + # Second instrumentation (should work) + instrumentor.instrument( + tracer_provider=tracer_provider, + logger_provider=logger_provider, + meter_provider=meter_provider, + ) + + # Second uninstrumentation + instrumentor.uninstrument() + + +def test_multiple_instrumentation_calls( + tracer_provider, logger_provider, meter_provider +): + """Test that multiple instrument() calls don't cause issues.""" + instrumentor = CohereInstrumentor() + + # First call + instrumentor.instrument( + tracer_provider=tracer_provider, + logger_provider=logger_provider, + meter_provider=meter_provider, + ) + + # Second call (should be idempotent or handle gracefully) + instrumentor.instrument( + tracer_provider=tracer_provider, + logger_provider=logger_provider, + meter_provider=meter_provider, + ) + + # Clean up + instrumentor.uninstrument() + + +def test_uninstrument_without_instrument(): + """Test that uninstrument() can be called without prior instrument().""" + instrumentor = CohereInstrumentor() + + # This should not raise an error + instrumentor.uninstrument() + + +def test_instrument_with_no_providers(): + """Test that instrument() works without explicit providers.""" + instrumentor = CohereInstrumentor() + + # Should use global providers + instrumentor.instrument() + + # Clean up + instrumentor.uninstrument() + + +def test_instrumentor_has_required_attributes(): + """Test that the instrumentor has the required methods.""" + instrumentor = CohereInstrumentor() + + assert hasattr(instrumentor, "instrument") + assert hasattr(instrumentor, "uninstrument") + assert hasattr(instrumentor, "instrumentation_dependencies") + assert callable(instrumentor.instrument) + assert callable(instrumentor.uninstrument) + assert callable(instrumentor.instrumentation_dependencies) diff --git a/pyproject.toml b/pyproject.toml index 74e2c0b04..3ff3c6e5a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,6 +13,7 @@ dependencies = [ "opentelemetry-util-genai", "opentelemetry-instrumentation-genai-anthropic[instruments]", "opentelemetry-instrumentation-genai-claude-agent-sdk[instruments]", + "opentelemetry-instrumentation-genai-cohere[instruments]", "opentelemetry-instrumentation-google-genai[instruments]", "opentelemetry-instrumentation-genai-langchain[instruments]", "opentelemetry-instrumentation-genai-openai[instruments]", @@ -32,6 +33,7 @@ opentelemetry-test-util-genai = { workspace = true } opentelemetry-util-genai = { workspace = true } opentelemetry-instrumentation-genai-anthropic = { workspace = true } opentelemetry-instrumentation-genai-claude-agent-sdk = { workspace = true } +opentelemetry-instrumentation-genai-cohere = { workspace = true } opentelemetry-instrumentation-google-genai = { workspace = true } opentelemetry-instrumentation-genai-langchain = { workspace = true } opentelemetry-instrumentation-genai-openai = { workspace = true } @@ -96,6 +98,7 @@ reportDeprecated = false # Ignore deprecation on GenAI enums in opentelemetry.s include = [ "instrumentation/opentelemetry-instrumentation-genai-anthropic", "instrumentation/opentelemetry-instrumentation-genai-claude-agent-sdk", + "instrumentation/opentelemetry-instrumentation-genai-cohere", "instrumentation/opentelemetry-instrumentation-genai-langchain", "instrumentation/opentelemetry-instrumentation-genai-openai-agents", "instrumentation/opentelemetry-instrumentation-genai-weaviate-client", @@ -108,6 +111,8 @@ exclude = [ "instrumentation/opentelemetry-instrumentation-genai-anthropic/examples/**/*.py", "instrumentation/opentelemetry-instrumentation-genai-claude-agent-sdk/tests/**/*.py", "instrumentation/opentelemetry-instrumentation-genai-claude-agent-sdk/examples/**/*.py", + "instrumentation/opentelemetry-instrumentation-genai-cohere/tests/**/*.py", + "instrumentation/opentelemetry-instrumentation-genai-cohere/examples/**/*.py", "instrumentation/opentelemetry-instrumentation-genai-langchain/tests/**/*.py", "instrumentation/opentelemetry-instrumentation-genai-langchain/examples/**/*.py", "instrumentation/opentelemetry-instrumentation-genai-openai-agents/tests/**/*.py", diff --git a/tox.ini b/tox.ini index ab363522f..bb8621c4a 100644 --- a/tox.ini +++ b/tox.ini @@ -43,6 +43,11 @@ envlist = # No pypy3: jiter (an anthropic dependency) ships no PyPy wheels, so it would need a Rust source build lint-instrumentation-genai-claude-agent-sdk + ; instrumentation-genai-cohere + py3{10,11,12,13,14}-test-instrumentation-genai-cohere-latest + py310-test-instrumentation-genai-cohere-oldest + lint-instrumentation-genai-cohere + ; instrumentation-genai-langchain py3{12,13}-test-instrumentation-genai-langchain-latest py312-test-instrumentation-genai-langchain-oldest @@ -132,6 +137,12 @@ deps = claude-agent-sdk-latest: {[testenv]pytest_deps} claude-agent-sdk-latest: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-genai-claude-agent-sdk/tests/requirements.latest.txt + cohere-{oldest,latest}: {[testenv]pytest_deps} + cohere-oldest: -e {toxinidir}/instrumentation/opentelemetry-instrumentation-genai-cohere[instruments] + cohere-oldest: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-genai-cohere/tests/requirements.oldest.txt + cohere-latest: {[testenv]test_deps} + cohere-latest: -r {toxinidir}/instrumentation/opentelemetry-instrumentation-genai-cohere/tests/requirements.latest.txt + ; Langchain unit tests langchain-{oldest,latest}: {[testenv]pytest_deps} ; oldest: declared deps (opentelemetry-instrumentation, util-genai, langchain) resolve from PyPI to @@ -192,6 +203,9 @@ commands = test-instrumentation-genai-claude-agent-sdk: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-genai-claude-agent-sdk/tests --vcr-record=none {posargs} lint-instrumentation-genai-claude-agent-sdk: sh -c "cd instrumentation && ruff check opentelemetry-instrumentation-genai-claude-agent-sdk" + test-instrumentation-genai-cohere-{oldest,latest}: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-genai-cohere/tests --vcr-record=none {posargs} + lint-instrumentation-genai-cohere: sh -c "cd instrumentation && ruff check opentelemetry-instrumentation-genai-cohere" + test-instrumentation-genai-langchain-{oldest,latest}: pytest --ignore={toxinidir}/instrumentation/opentelemetry-instrumentation-genai-langchain/tests/test_conformance.py {toxinidir}/instrumentation/opentelemetry-instrumentation-genai-langchain/tests --vcr-record=none {posargs} test-instrumentation-genai-langchain-conformance: pytest {toxinidir}/instrumentation/opentelemetry-instrumentation-genai-langchain/tests/test_conformance.py --vcr-record=none {posargs} lint-instrumentation-genai-langchain: sh -c "cd instrumentation && ruff check opentelemetry-instrumentation-genai-langchain" @@ -285,6 +299,7 @@ deps = {toxinidir}/instrumentation/opentelemetry-instrumentation-genai-anthropic[instruments] {toxinidir}/instrumentation/opentelemetry-instrumentation-genai-langchain[instruments] {toxinidir}/instrumentation/opentelemetry-instrumentation-genai-claude-agent-sdk[instruments] + {toxinidir}/instrumentation/opentelemetry-instrumentation-genai-cohere[instruments] {toxinidir}/instrumentation/opentelemetry-instrumentation-genai-openai-agents[instruments] {toxinidir}/instrumentation/opentelemetry-instrumentation-genai-weaviate-client[instruments] diff --git a/uv.lock b/uv.lock index 94f9b8f1c..513404ebd 100644 --- a/uv.lock +++ b/uv.lock @@ -14,6 +14,7 @@ resolution-markers = [ members = [ "opentelemetry-instrumentation-genai-anthropic", "opentelemetry-instrumentation-genai-claude-agent-sdk", + "opentelemetry-instrumentation-genai-cohere", "opentelemetry-instrumentation-genai-langchain", "opentelemetry-instrumentation-genai-openai", "opentelemetry-instrumentation-genai-openai-agents", @@ -355,6 +356,25 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/fb/e2/79c688af8b210d232694e31e59da9f6ec747bae31c3f5946e4e9b98860d5/click-8.4.2-py3-none-any.whl", hash = "sha256:e6f9f66136c816745b9d65817da91d61d957fb16e02e4dcd0552553c5a197b76", size = 119243, upload-time = "2026-06-24T17:45:13.73Z" }, ] +[[package]] +name = "cohere" +version = "7.0.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "fastavro" }, + { name = "httpx" }, + { name = "pydantic" }, + { name = "pydantic-core" }, + { name = "requests" }, + { name = "tokenizers" }, + { name = "types-requests" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/78/23/cbb8ef34b8395ecea3cef2464d6abcb25174853fe8ad948841204f81f9a8/cohere-7.0.5.tar.gz", hash = "sha256:7fc682bb5c408402fc5ce59322bfa3f6aae27bde1ecc2450b0a25370040707ed", size = 208820, upload-time = "2026-06-29T20:30:53.132Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e6/eb/64ca464baa34d0fa8144fc09ec7a35c8fcdeea1be878a518e901b0a6032b/cohere-7.0.5-py3-none-any.whl", hash = "sha256:fd98f82be28c969da7625adddede0bb85f8f84de399daf3a98c40c0e7b93e104", size = 352049, upload-time = "2026-06-29T20:30:51.472Z" }, +] + [[package]] name = "colorama" version = "0.4.6" @@ -453,13 +473,65 @@ name = "exceptiongroup" version = "1.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, ] +[[package]] +name = "fastavro" +version = "1.12.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6e/5b/ccb338db71f347e3bc031d268bf6dc41e5ead63b6997b8e72af92f05e18e/fastavro-1.12.2.tar.gz", hash = "sha256:3c79502d56cf6b76210032e1c53494ddfbc73c140bccf2ef4092b3f0825323ab", size = 1030127, upload-time = "2026-04-24T14:36:01.269Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3c/91/16c3508447e7cf9f413a6a01792a990ed94d17505fc80a7fb76027078aed/fastavro-1.12.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c7c6d26c731a0e1e8e7d4ae8f13ae524eb6ec0e90d99c8147a19fdbae14eb807", size = 976824, upload-time = "2026-04-24T14:36:04.233Z" }, + { url = "https://files.pythonhosted.org/packages/2d/3a/97534561a1b4615366345ac066ad1f54698a59aa510eece3153c3a603d29/fastavro-1.12.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7caeecf519eff50f007ca4bee16b6e0a8252e5fe682c94432192a20867239888", size = 3185186, upload-time = "2026-04-24T14:36:06.395Z" }, + { url = "https://files.pythonhosted.org/packages/ee/e4/26512b52f58305b9d2194169de2e82c16d5131f0a0b6359e50d34faf4021/fastavro-1.12.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:731aefe6c4bf2bafa0798ef83927676d06e44d1d18202cfb56d63b40422ab900", size = 3196799, upload-time = "2026-04-24T14:36:09.028Z" }, + { url = "https://files.pythonhosted.org/packages/58/69/22f3b29a4555eb805a26f209f12532df8aafa48685d1cd1879aa42758d04/fastavro-1.12.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f089f24225a28ddafa5cfad7c41cfa84db1a55f2d473370769a95c0e3bac60c9", size = 3112396, upload-time = "2026-04-24T14:36:11.401Z" }, + { url = "https://files.pythonhosted.org/packages/e9/2a/fc61ef522050e1079ccf1aee07192881f3b11129f5e2b76811fd4fc3bb2f/fastavro-1.12.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:653c4f90dd21d8a1e74309919e08934e420d9aef51d051d14bf5a1c0e8293c22", size = 3180452, upload-time = "2026-04-24T14:36:13.634Z" }, + { url = "https://files.pythonhosted.org/packages/a6/6a/43ce9d713e9f1122e19c80d94d0dc0a356b8562d33eea90081dac781dd97/fastavro-1.12.2-cp310-cp310-win_amd64.whl", hash = "sha256:030f17eb4c7978538a31b55dea451ceace851a88dc9816b1923f8fb8a260db4c", size = 445396, upload-time = "2026-04-24T14:36:15.243Z" }, + { url = "https://files.pythonhosted.org/packages/89/77/058f3c93348624cb695399b27f3f0c1c3d1190586065797e4a48f75d4147/fastavro-1.12.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d48cd7094598a7e9d4297e8bf4bbe0dc9dc2ba4367d83dbb603e3b3c6aa35566", size = 974559, upload-time = "2026-04-24T14:36:17.172Z" }, + { url = "https://files.pythonhosted.org/packages/a5/ef/08bbfa643addd2b98a9ce536613e2098928aa5e3ca098fd5b74f3c03b96a/fastavro-1.12.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:070c6134604bd7b6fd44409406ac50445339682b2e872885db2e859f92d22e93", size = 3352777, upload-time = "2026-04-24T14:36:19.679Z" }, + { url = "https://files.pythonhosted.org/packages/d3/ec/55c11108529bdb59e635899f737651f729485ea5af36e128fb6560969c3d/fastavro-1.12.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2b73d50978d5e57416fa68461f9f3c8f39ea39e761cb1e12f919745adefe26a7", size = 3387036, upload-time = "2026-04-24T14:36:21.794Z" }, + { url = "https://files.pythonhosted.org/packages/d9/b3/4459f7c61804e9b42b49f02fba8fbbb041af76c7cab43cee4018532ecd00/fastavro-1.12.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c57a9920400166398695d92580eca21fd7a79f3c67d691ac7e20a7d1b5300735", size = 3284780, upload-time = "2026-04-24T14:36:24.193Z" }, + { url = "https://files.pythonhosted.org/packages/5d/e3/d7f510b9b8c7b73409a6232a9a8d282faa8560f85d024d7212e4c5dff3df/fastavro-1.12.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:81f6108f3ac292fb6cd05758c9e531389d8fc5e94e8c949b9298f4fb0a239662", size = 3368557, upload-time = "2026-04-24T14:36:26.667Z" }, + { url = "https://files.pythonhosted.org/packages/cb/10/14fa0abf8e7da07258393ae2b783dd4bb60d1fb93ad790296d27561f33ce/fastavro-1.12.2-cp311-cp311-win_amd64.whl", hash = "sha256:eec44256856fd59d29d1f1d0950ace18a58e4228e7d49de5d5e1b1875b227dde", size = 446499, upload-time = "2026-04-24T14:36:28.547Z" }, + { url = "https://files.pythonhosted.org/packages/86/d2/c36f646296794c05d29a07bec84a6c56bfd285203e389a8954987ec1c515/fastavro-1.12.2-cp311-cp311-win_arm64.whl", hash = "sha256:ecd1b23ea7f9af09c865ac8503d07afd7e6bf782d76bb83cbbdba15b7a0db807", size = 388198, upload-time = "2026-04-24T14:36:29.791Z" }, + { url = "https://files.pythonhosted.org/packages/0e/bc/fe5731d6724d978694fbd3196bc1c0d7cab3fd0766e9551c40c39f798b52/fastavro-1.12.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0e331896e8efffc72fa03e63b87ebfc37960113127da8e0f5152d91664ffed68", size = 964331, upload-time = "2026-04-24T14:36:31.297Z" }, + { url = "https://files.pythonhosted.org/packages/98/36/50abf1145e4f1c4f418cd4b5f2ac806643d0b14e360b60e953826edf1b34/fastavro-1.12.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7f01ebaada59d74fdf6d28e5031a961a413b3752e9edb0c03866fa18480cf4c8", size = 3340170, upload-time = "2026-04-24T14:36:33.364Z" }, + { url = "https://files.pythonhosted.org/packages/fc/8c/76ef4641e6c1c1aa3e6bb3c9efb5533ffda5dd975c8b5ae54e794322d9e3/fastavro-1.12.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:25ef6855935f67582740ffa6bb978e40ec51be876117a3555c36fa2488dcdf25", size = 3425061, upload-time = "2026-04-24T14:36:35.497Z" }, + { url = "https://files.pythonhosted.org/packages/31/10/379ff23425b2b470d5209cbc6736a6e5cbc34392ff17bb7355b8fd4aa0ca/fastavro-1.12.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:84a4f76a0aece0aa72b5ed8162ba2ff8c78908b8361b5a5d92ddd161977ccb74", size = 3243618, upload-time = "2026-04-24T14:36:37.969Z" }, + { url = "https://files.pythonhosted.org/packages/88/29/4c8f9e7cd78f932f0d82823899e67a6d7f7e8f2524992db03956f9d9f5ef/fastavro-1.12.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:81e8da77d201916f6771fc357fda8267c2a256d7aa11923d43bc5f2fc155878b", size = 3378427, upload-time = "2026-04-24T14:36:40.278Z" }, + { url = "https://files.pythonhosted.org/packages/e2/a1/eafeb302aaaea6055d4a9c11272b4aeaf713e43fe8eaf782f43a1fee2b44/fastavro-1.12.2-cp312-cp312-win_amd64.whl", hash = "sha256:1924349c74666c89417bd5cc2749f598e2f15f1d56ee81428b2317ab02c88aae", size = 441077, upload-time = "2026-04-24T14:36:41.791Z" }, + { url = "https://files.pythonhosted.org/packages/56/9d/67e831041ba8efc16265c65bd71ba92e1095bba19b91be99e102f19d9be6/fastavro-1.12.2-cp312-cp312-win_arm64.whl", hash = "sha256:4c346cf449baf3b113e997c34151ad205e7135bc429469b005b180ade7e65e28", size = 378205, upload-time = "2026-04-24T14:36:43.679Z" }, + { url = "https://files.pythonhosted.org/packages/83/39/f489a441d41cc9c0a8449fb1325d7a9c9eb57a5634e6ab19dfb0a1105324/fastavro-1.12.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:57bb6b908cb2e05baab63b04c3a31be3b4545a10bfab9748b8763016b5256704", size = 958566, upload-time = "2026-04-24T14:36:45.49Z" }, + { url = "https://files.pythonhosted.org/packages/31/69/776cc025aee2d02acacb734cf690d2fbc295eaadde1b5d47caf8c77a6a2b/fastavro-1.12.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a007f95cc682f56e6d83f1d17c29c00bf719d6fe8e003282b535af3a1ba09c0", size = 3276390, upload-time = "2026-04-24T14:36:47.875Z" }, + { url = "https://files.pythonhosted.org/packages/8c/bc/b7e15fa788f42cbe65827af2ec06c9ad91bb9f72c213110dbef61b53a5b0/fastavro-1.12.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5e90460b0cd21f62be3cb26087e706e2cebb7b3fcef9e05b4473b61bb0415b5e", size = 3372779, upload-time = "2026-04-24T14:36:50.122Z" }, + { url = "https://files.pythonhosted.org/packages/79/c2/98993ca810231fc1397212f48c3d46626983722a24bbaaa5c27ee0963751/fastavro-1.12.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7ccd15966b8218d41b06ec3e7c2556be89a8a693026c771e6564d2e40bbaf8ea", size = 3187591, upload-time = "2026-04-24T14:36:52.451Z" }, + { url = "https://files.pythonhosted.org/packages/c6/bb/c180f340eba6478f1b20deccdd17e2b4a4d5074dafd812e3c4254fd035f7/fastavro-1.12.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:06b6971d3dae10cb34353b857d16ad21ebd6f0ea394e86c96abdcad109005d6e", size = 3320589, upload-time = "2026-04-24T14:36:54.647Z" }, + { url = "https://files.pythonhosted.org/packages/4d/e9/aca0456216b5b8992e7b0a8542711b66799c05bfe24c8e32ef6f56e7eb93/fastavro-1.12.2-cp313-cp313-win_amd64.whl", hash = "sha256:98dfcdfaf1498ae2f0e2fafe900a82e8320cc81d8ae5a95b8b8879eaa3298c39", size = 440883, upload-time = "2026-04-24T14:36:56.585Z" }, + { url = "https://files.pythonhosted.org/packages/e3/7e/984896e716af504927be71b80a1e9661aa96c6f9e1e777d52823aacb99f2/fastavro-1.12.2-cp313-cp313-win_arm64.whl", hash = "sha256:3888ef7a51adc77cdf07251bc762566a1be36211e1cff689f13980f3776a2f36", size = 377536, upload-time = "2026-04-24T14:36:58.274Z" }, + { url = "https://files.pythonhosted.org/packages/e9/42/09a1e1f8d9998d73848a6ff0aad6713ae6abf0dbf99918776f8ef33344a7/fastavro-1.12.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:283dcd3129b632021894425974bedd0eb6db3bbf5994e448ccad10db4d803d31", size = 1049506, upload-time = "2026-04-24T14:36:59.797Z" }, + { url = "https://files.pythonhosted.org/packages/52/ef/80cc16f43919d532f25a707f34b275cccc09dca87a05b000fbbfc8e8f255/fastavro-1.12.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2d125e210d5a0a1f701f12c0ecad9a03f1b04b5eddbce6ca36a1fc217da977ef", size = 3495899, upload-time = "2026-04-24T14:37:02.306Z" }, + { url = "https://files.pythonhosted.org/packages/c1/54/a0817d1d0236e9e0233f5c996f450cc795b056b8e06edb531f24b9df82ed/fastavro-1.12.2-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2d4d66afad78e8f47feaa307728a6b71fe3effc63ba2b9eeb109ee687c9bd397", size = 3399232, upload-time = "2026-04-24T14:37:04.837Z" }, + { url = "https://files.pythonhosted.org/packages/38/0a/650f256c15f5875b6081544b9ba7ed8254329213e7e49e3db0aec68b5bee/fastavro-1.12.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:2328ec07925c04c89719e3971c9068a165c7fd474ea87675b1204de0440e71ff", size = 3320222, upload-time = "2026-04-24T14:37:07.281Z" }, + { url = "https://files.pythonhosted.org/packages/f5/54/8351d388f94fbb0870e8cffaae41d3cc607acc8d6a8a6a217e2794829593/fastavro-1.12.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:55dea7e74b834d4b70467fc19c5b9ccb5509fe39abc4d26891187c1b22176423", size = 3337096, upload-time = "2026-04-24T14:37:09.452Z" }, + { url = "https://files.pythonhosted.org/packages/da/eb/b36ba9a88826e8c272df02e2f8b5da717e88b6eb508fddca3ca450043731/fastavro-1.12.2-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:8d37c87826ae7195cfbd20fcd448801f2f563bb38f2691ec6574e39cb9eca6c8", size = 963119, upload-time = "2026-04-24T14:37:11.557Z" }, + { url = "https://files.pythonhosted.org/packages/e1/02/3d7f540fb26ba4ea1f4ebd2783c586614da9ac00906a3092e92fd3f104a2/fastavro-1.12.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4c463a3701f293e30d3d62e71e1989f112028d07f87432baf4507eeb57ec3831", size = 3266238, upload-time = "2026-04-24T14:37:13.84Z" }, + { url = "https://files.pythonhosted.org/packages/4c/0b/b77be56c5109da0fc7dcfd7e6b6752fe0a61d0a5c58c6a65e38b4501946a/fastavro-1.12.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f604ba83498e209fff4c7ecc5063a39421dc538dace694bc592f9f338254f3dc", size = 3324020, upload-time = "2026-04-24T14:37:16.096Z" }, + { url = "https://files.pythonhosted.org/packages/e7/6e/951d41f244107e91bf2f59245b71783c03eaab4bdbc960d58316c19652bb/fastavro-1.12.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:bfac2dada8ddc002e8b7d8289d6fad4f070bc1fec20371cec684a7d10d932e96", size = 3170160, upload-time = "2026-04-24T14:37:18.168Z" }, + { url = "https://files.pythonhosted.org/packages/94/6f/2adb571fda448d4afd2466e1cef2963fefdc6b37847da05249983e415f17/fastavro-1.12.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:bc44ba6289fb1f5ee318335958dde6ad6d742dcb4bb8930de843e9024c64b68c", size = 3281842, upload-time = "2026-04-24T14:37:20.833Z" }, + { url = "https://files.pythonhosted.org/packages/17/07/4bad2e96c4c6bae40253be2573cc09c1e5b9ccf821e1ff74e0d33b64bf90/fastavro-1.12.2-cp314-cp314-win_amd64.whl", hash = "sha256:a475418f71c5aed69899813ecccf392429c08c3a63df3030129db71760b0db8f", size = 450903, upload-time = "2026-04-24T14:37:23.059Z" }, + { url = "https://files.pythonhosted.org/packages/5b/b7/180f67ba9a46ba23a1ff6432f48d3087d4f2048579ecc262b00426cb1c63/fastavro-1.12.2-cp314-cp314-win_arm64.whl", hash = "sha256:daec9f9655a1d4636613c47d6d3343f6e039150d66cdce62543e20ca36612a8a", size = 391076, upload-time = "2026-04-24T14:37:24.756Z" }, + { url = "https://files.pythonhosted.org/packages/dd/8f/18f60329b627d2118a4a2b19e8741fbd807d60bf0470554e1bbfb7f1bca3/fastavro-1.12.2-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:57594b72cf663bbd0f3ad8a319a999fc3d7c71065a6799b2c1d1a6a137894c5b", size = 1055430, upload-time = "2026-05-09T21:53:14.364Z" }, + { url = "https://files.pythonhosted.org/packages/d2/ac/a1fa1fc29df0efc89d4946a743b09bdc9500591b5b92083eaf8e93664916/fastavro-1.12.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:74412132bbfb153cbf704517f2c89f7d3e170feb681b13bceace690f66f8d5fa", size = 3503075, upload-time = "2026-04-24T14:37:26.826Z" }, + { url = "https://files.pythonhosted.org/packages/82/bf/4f669e10b6bc38a731ee3400aed1a1e2d0a3e3cf411e72f6b320d3af0eaf/fastavro-1.12.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e367a84c9133018e0a3bc822abe78d7f1f9a6092991a0ec409468cf4ef260282", size = 3410900, upload-time = "2026-04-24T14:37:29.233Z" }, + { url = "https://files.pythonhosted.org/packages/10/39/ecb19fdae4158a7730b5963fbf1b6d38d74678392d73083be518642af0c1/fastavro-1.12.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:044fafca0853e9ae14009de7763ac9e8e8f8b96f8a4e90bd58b695443266a370", size = 3335637, upload-time = "2026-04-24T14:37:31.472Z" }, + { url = "https://files.pythonhosted.org/packages/32/f1/f21bd5319113e89ceceed2df840df21e9c5150d181db74b6ba80400f9f48/fastavro-1.12.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:afede7324822800e4f90e96b9514188a237a60f35e8e7a10b2129c10c78f6e4d", size = 3356664, upload-time = "2026-04-24T14:37:34.231Z" }, +] + [[package]] name = "filelock" version = "3.29.7" @@ -596,6 +668,30 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, ] +[[package]] +name = "hf-xet" +version = "1.5.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/63/39/67be8d71f900d9a55761b6022821d6679fb56c64f1b6063d5af2c2606727/hf_xet-1.5.2.tar.gz", hash = "sha256:73044bd31bae33c984af832d19c752a0dffb67518fee9ddbd91d616e1101cf47", size = 903674, upload-time = "2026-07-16T17:29:56.833Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/29/be/525eabac5d1736b679c39e342ecd4292534012546a2d18f0043c8e3b6021/hf_xet-1.5.2-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:4a5ecb9cda8512ba2aa8ee5d37c87a1422992165892d653098c7b90247481c3b", size = 4064284, upload-time = "2026-07-16T17:29:29.907Z" }, + { url = "https://files.pythonhosted.org/packages/c5/3f/699749dd78442480eda4e4fca494284b0e3542e4063cc37654d5fdc929e6/hf_xet-1.5.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:8764488197c1d7b1378c8438c18d2eea902e150dbca0b0f0d2d32603fb9b5576", size = 3828537, upload-time = "2026-07-16T17:29:31.549Z" }, + { url = "https://files.pythonhosted.org/packages/22/d7/2658ac0a5b9f4664ca27ce31bd015044fe9dea50ed455fb5197aba819c11/hf_xet-1.5.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8d7446f72abbf7e01ca5ff131786bc2e74a56393462c17a6bf1e303fbab81db4", size = 4417133, upload-time = "2026-07-16T17:29:33.391Z" }, + { url = "https://files.pythonhosted.org/packages/d9/58/8343f3cb63c8fa058d576136df3871550f7d5214a8f048a7ea2eab6ac906/hf_xet-1.5.2-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:580e59e29bf37aece1f2b68537de1e3fb04f43a23d910dcf6f128280b5bfbba4", size = 4212613, upload-time = "2026-07-16T17:29:34.989Z" }, + { url = "https://files.pythonhosted.org/packages/0c/33/a968f4e4535037b36941ec00714625fb60e026302407e7e26ca9f3e65f4e/hf_xet-1.5.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:bee28c619622d36968056532fd49cf2b35ca75099b1d616c31a618a893491380", size = 4412710, upload-time = "2026-07-16T17:29:36.646Z" }, + { url = "https://files.pythonhosted.org/packages/7b/d9/9e33981173dbaf194ba0015202b02d467b624d44d4eba89e1bf06c0d2995/hf_xet-1.5.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e396ab0faf6298199ad7a95305c3ca8498cb825978a6485be6d00587ee4ec577", size = 4628455, upload-time = "2026-07-16T17:29:38.352Z" }, + { url = "https://files.pythonhosted.org/packages/e9/4b/cc682832de4264a03880a2d1b5ec3e1fab3bf307f508817250baafdb9996/hf_xet-1.5.2-cp314-cp314t-win_amd64.whl", hash = "sha256:fd3add255549e8ef58fa35b2e42dc016961c050600444e7d77d030ba6b57120e", size = 3979044, upload-time = "2026-07-16T17:29:40.329Z" }, + { url = "https://files.pythonhosted.org/packages/ea/09/b2cdf2a0fb39a08af3222b96092a36bd3b40c54123eef07de4422e870971/hf_xet-1.5.2-cp314-cp314t-win_arm64.whl", hash = "sha256:d6f9c58549407b84b9a5383afd68db0acc42345326a3159990b36a5ca8a20e4e", size = 3808037, upload-time = "2026-07-16T17:29:42.357Z" }, + { url = "https://files.pythonhosted.org/packages/de/ba/2b70603c7552db82baeb2623e2336898304a17328845151be4fe1f48d420/hf_xet-1.5.2-cp38-abi3-macosx_10_12_x86_64.whl", hash = "sha256:f922b8f5fb84f1dd3d7ab7a1316354a1bca9b1c73ecfc19c76e51a2a49d29799", size = 4033760, upload-time = "2026-07-16T17:29:43.884Z" }, + { url = "https://files.pythonhosted.org/packages/60/ac/b097a86a1e4a6098f3a79382643ab09d5733d87ccc864877ad1e12b49b70/hf_xet-1.5.2-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:045f84440c55cdeb659cf1a1dd48c77bcd0d2e93632e2fea8f2c3bdee79f38ed", size = 3841438, upload-time = "2026-07-16T17:29:45.539Z" }, + { url = "https://files.pythonhosted.org/packages/d3/35/db860aa3a0780660324a506ad4b3d322ddc6ecbba4b9340aed0942cbf21c/hf_xet-1.5.2-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:db78c39c83d6279daddc98e2238f373ab8980685556d42472b4ec51abcf03e8c", size = 4428006, upload-time = "2026-07-16T17:29:46.996Z" }, + { url = "https://files.pythonhosted.org/packages/af/6b/832dd980af4b0c3ae0660e309285f2ffcdff2faa38129390dbb47aa4a3f9/hf_xet-1.5.2-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:7db73c810500c54c6760be8c39d4b2e476974de85424c50063efc22fdda13025", size = 4221099, upload-time = "2026-07-16T17:29:48.525Z" }, + { url = "https://files.pythonhosted.org/packages/9e/05/ae50f0d34e3254e6c3e208beb2519f6b8673016fc4b3643badaf6450d186/hf_xet-1.5.2-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:6395cfe3c9cbead4f16b31808b0e67eac428b66c656f856e99636adaddea878f", size = 4420766, upload-time = "2026-07-16T17:29:50.092Z" }, + { url = "https://files.pythonhosted.org/packages/07/a9/c050bc2743a2bcd68928bfee157b08681667a164a24ec95fbfcfcd717e08/hf_xet-1.5.2-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:cde8cd167126bb6109b2ceb19b844433a4988643e8f3e01dd9dd0e4a34535097", size = 4636716, upload-time = "2026-07-16T17:29:51.62Z" }, + { url = "https://files.pythonhosted.org/packages/e9/f8/68b01c5c2edb56ac9a67b3d076ffddcb90867abaee923923eb34e7a14e76/hf_xet-1.5.2-cp38-abi3-win_amd64.whl", hash = "sha256:ecf63d1cb69a9a7319910f8f83fcf9b46e7a32dfcf4b8f8eeddb55f647306e65", size = 3988373, upload-time = "2026-07-16T17:29:53.395Z" }, + { url = "https://files.pythonhosted.org/packages/39/c6/988383e9dc17294d536fcbcd6fd16eed882e411ad16c954984a53e47b09c/hf_xet-1.5.2-cp38-abi3-win_arm64.whl", hash = "sha256:1da28519496eb7c8094c11e4d25509b4a468457a0302d58136099db2fd9a671d", size = 3816957, upload-time = "2026-07-16T17:29:54.991Z" }, +] + [[package]] name = "httpcore" version = "1.0.9" @@ -633,6 +729,26 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d2/fd/6668e5aec43ab844de6fc74927e155a3b37bf40d7c3790e49fc0406b6578/httpx_sse-0.4.3-py3-none-any.whl", hash = "sha256:0ac1c9fe3c0afad2e0ebb25a934a59f4c7823b60792691f779fad2c5568830fc", size = 8960, upload-time = "2025-10-10T21:48:21.158Z" }, ] +[[package]] +name = "huggingface-hub" +version = "1.23.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "filelock" }, + { name = "fsspec" }, + { name = "hf-xet", marker = "platform_machine == 'AMD64' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'arm64' or platform_machine == 'x86_64'" }, + { name = "httpx" }, + { name = "packaging" }, + { name = "pyyaml" }, + { name = "tqdm" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1a/8f/999e4dda11c6187c78f090eac00895a47e11a0049308f07579bcb7aa3aa2/huggingface_hub-1.23.0.tar.gz", hash = "sha256:c04997fb8bbdace1e57b7703d30ed7678af51f70d00d241819ff411b92ae9a88", size = 919163, upload-time = "2026-07-09T14:49:32.315Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f1/ce/13b2ba57838b8db1e6bd033c1b21ce0b9f6153b87d4e4939f77074e41eb0/huggingface_hub-1.23.0-py3-none-any.whl", hash = "sha256:b1d604788f5adc7f0eb246e03e0ec19011ca06e38400218c347dccc3dffa64a2", size = 770336, upload-time = "2026-07-09T14:49:30.597Z" }, +] + [[package]] name = "identify" version = "2.6.19" @@ -1195,6 +1311,31 @@ requires-dist = [ ] provides-extras = ["instruments"] +[[package]] +name = "opentelemetry-instrumentation-genai-cohere" +source = { editable = "instrumentation/opentelemetry-instrumentation-genai-cohere" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "opentelemetry-util-genai" }, +] + +[package.optional-dependencies] +instruments = [ + { name = "cohere" }, +] + +[package.metadata] +requires-dist = [ + { name = "cohere", marker = "extra == 'instruments'", specifier = ">=5.13.0" }, + { name = "opentelemetry-api", specifier = "~=1.43" }, + { name = "opentelemetry-instrumentation", specifier = ">=0.64b0,<1" }, + { name = "opentelemetry-semantic-conventions", specifier = ">=0.64b0,<1" }, + { name = "opentelemetry-util-genai", editable = "util/opentelemetry-util-genai" }, +] +provides-extras = ["instruments"] + [[package]] name = "opentelemetry-instrumentation-genai-langchain" source = { editable = "instrumentation/opentelemetry-instrumentation-genai-langchain" } @@ -1325,6 +1466,7 @@ dependencies = [ { name = "opentelemetry-instrumentation" }, { name = "opentelemetry-instrumentation-genai-anthropic", extra = ["instruments"] }, { name = "opentelemetry-instrumentation-genai-claude-agent-sdk", extra = ["instruments"] }, + { name = "opentelemetry-instrumentation-genai-cohere", extra = ["instruments"] }, { name = "opentelemetry-instrumentation-genai-langchain", extra = ["instruments"] }, { name = "opentelemetry-instrumentation-genai-openai", extra = ["instruments"] }, { name = "opentelemetry-instrumentation-genai-openai-agents", extra = ["instruments"] }, @@ -1351,6 +1493,7 @@ requires-dist = [ { name = "opentelemetry-instrumentation" }, { name = "opentelemetry-instrumentation-genai-anthropic", extras = ["instruments"], editable = "instrumentation/opentelemetry-instrumentation-genai-anthropic" }, { name = "opentelemetry-instrumentation-genai-claude-agent-sdk", extras = ["instruments"], editable = "instrumentation/opentelemetry-instrumentation-genai-claude-agent-sdk" }, + { name = "opentelemetry-instrumentation-genai-cohere", extras = ["instruments"], editable = "instrumentation/opentelemetry-instrumentation-genai-cohere" }, { name = "opentelemetry-instrumentation-genai-langchain", extras = ["instruments"], editable = "instrumentation/opentelemetry-instrumentation-genai-langchain" }, { name = "opentelemetry-instrumentation-genai-openai", extras = ["instruments"], editable = "instrumentation/opentelemetry-instrumentation-genai-openai" }, { name = "opentelemetry-instrumentation-genai-openai-agents", extras = ["instruments"], editable = "instrumentation/opentelemetry-instrumentation-genai-openai-agents" }, @@ -2357,6 +2500,33 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d7/c1/eb8f9debc45d3b7918a32ab756658a0904732f75e555402972246b0b8e71/tenacity-9.1.4-py3-none-any.whl", hash = "sha256:6095a360c919085f28c6527de529e76a06ad89b23659fa881ae0649b867a9d55", size = 28926, upload-time = "2026-02-07T10:45:32.24Z" }, ] +[[package]] +name = "tokenizers" +version = "0.23.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "huggingface-hub" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c1/60/21f715d9faba5f5407ff759472ade058ec4a507ad62bcea47cb847239a73/tokenizers-0.23.1.tar.gz", hash = "sha256:1feeeadf865a7915adc25445dea30e9933e593c31bb96c277cee36de227c8bfa", size = 365748, upload-time = "2026-04-27T14:43:25.606Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/87/39/b87a87d5bb9470610b80a2d31df42fcffeaf35118b8b97952b2aff598cc7/tokenizers-0.23.1-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:e03d6ffcbe0d56ee9c1ccd070e70a13fa750727c0277e138152acbc0252c2224", size = 3146732, upload-time = "2026-04-27T14:43:15.427Z" }, + { url = "https://files.pythonhosted.org/packages/e2/6a/068ed9f6e444c9d7e9d55ce134181325700f3d7f30410721bdc8f848d727/tokenizers-0.23.1-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:e0948bbb1ac1d7cdfc9fb6d62c596e3b7550036ad60ecd654a66ad273326324e", size = 3054954, upload-time = "2026-04-27T14:43:13.745Z" }, + { url = "https://files.pythonhosted.org/packages/6c/36/e006edf031154cba92b8416057d92c3abe3635e4c4b0aa0b5b9bb39dde70/tokenizers-0.23.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bf13402aff9bc533c89cb849ec3b412dc3fbeacc9744840e423d7bf3f7dc0e3", size = 3374081, upload-time = "2026-04-27T14:43:01.241Z" }, + { url = "https://files.pythonhosted.org/packages/a2/ef/7735d226f9c7f874a6bee5e3f27fb25ecabdf207d37b8cf45286d0795893/tokenizers-0.23.1-cp310-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f836ca703b89ae07919a309f9651f7a88fd5a33d5f718ba5ad0870ec0256bad6", size = 3247641, upload-time = "2026-04-27T14:43:03.856Z" }, + { url = "https://files.pythonhosted.org/packages/b9/d9/24827036f6e21297bfffda0768e58eb6096a4f411e932964a01707857931/tokenizers-0.23.1-cp310-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae848657742035523fdf261773630cb819a26995fcd3d9ecae0c1daf6e5a4959", size = 3585624, upload-time = "2026-04-27T14:43:10.664Z" }, + { url = "https://files.pythonhosted.org/packages/0c/9a/22f3582b3a4f49358293a5206e25317621ee4526bfe9cdaa0f07a12e770e/tokenizers-0.23.1-cp310-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:53b09e85775d5187941e7bab30e941b4134ab4a7dd8c68e783d231fb7ca27c51", size = 3844062, upload-time = "2026-04-27T14:43:05.643Z" }, + { url = "https://files.pythonhosted.org/packages/7e/65/b8f8814eef95800f20721384136d9a1d22241d50b2874357cb70542c392f/tokenizers-0.23.1-cp310-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea5a0ce170074329faaa8ea3f6400ecde604b6678192688533af80980daae71a", size = 3460098, upload-time = "2026-04-27T14:43:08.854Z" }, + { url = "https://files.pythonhosted.org/packages/0d/d5/1353e5f677ec27c2494fb6a6725e82d56c985f53e90ec511369e7e4f02c6/tokenizers-0.23.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5075b405006415ea148a992d093699c66eb01952bf59f4d5727089a98bda45a4", size = 3346235, upload-time = "2026-04-27T14:43:12.377Z" }, + { url = "https://files.pythonhosted.org/packages/71/89/39b6b8fc073fb6d413d0147aa333dc7eff7be65639ac9d19930a0b21bf33/tokenizers-0.23.1-cp310-abi3-manylinux_2_31_riscv64.whl", hash = "sha256:56f3a77de629917652f876294dc9fe6bad4a0c43bc229dc72e59bb23a0f4729a", size = 3426398, upload-time = "2026-04-27T14:43:07.264Z" }, + { url = "https://files.pythonhosted.org/packages/0f/80/127c854da64827e5b79264ce524993a90dddcb320e5cd42412c5c02f9e8a/tokenizers-0.23.1-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9d10a6d957ef01896dc274e890eee27d41bd0e74ef31e60616f0fc311345184e", size = 9823279, upload-time = "2026-04-27T14:43:17.222Z" }, + { url = "https://files.pythonhosted.org/packages/fe/ba/44c2502feb1a058f096ddfb4e0996ef3225a01a388e1a9b094e91689fe93/tokenizers-0.23.1-cp310-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:1974288a609c343774f1b897c8b482c791ab17b75ab5c8c2b1737565c1d82288", size = 9644986, upload-time = "2026-04-27T14:43:19.45Z" }, + { url = "https://files.pythonhosted.org/packages/9e/c1/464019a9fb059870bfe4eebb4ba12208f3042035e258bf5e782906bd3847/tokenizers-0.23.1-cp310-abi3-musllinux_1_2_i686.whl", hash = "sha256:120468fb4c24faf0543c835a4fabafa4deb3f20a035c9b6e83d0b553a97615d4", size = 9976181, upload-time = "2026-04-27T14:43:21.463Z" }, + { url = "https://files.pythonhosted.org/packages/79/94/3ac1432bda31626071e9b6a12709b97ae05131c804b94c8f3ac622c5da32/tokenizers-0.23.1-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:e3d8f40ea6268047de7046906326abed5134f27d4e8447b23763afe5808c8a96", size = 10113853, upload-time = "2026-04-27T14:43:23.617Z" }, + { url = "https://files.pythonhosted.org/packages/6a/dd/631b21433c771b1382535326f0eca80b9c9cee2e64961dd993bc9ac4669e/tokenizers-0.23.1-cp310-abi3-win32.whl", hash = "sha256:93120a930b919416da7cd10a2f606ac9919cc69cacae7980fa2140e277660948", size = 2536263, upload-time = "2026-04-27T14:43:29.888Z" }, + { url = "https://files.pythonhosted.org/packages/97/c9/2553f72aaf65a2797d4229e37fa7fbe38ffbf3e32912d31bdd78b3323e59/tokenizers-0.23.1-cp310-abi3-win_amd64.whl", hash = "sha256:e7bfaf995c1bdbbd21d13539decb6650967013759318627d85daeb7881af16b7", size = 2798223, upload-time = "2026-04-27T14:43:28.51Z" }, + { url = "https://files.pythonhosted.org/packages/cd/2b/2be299bab55fc595e3d38567edb1a87f86e594842968fa9515a07bdcf422/tokenizers-0.23.1-cp310-abi3-win_arm64.whl", hash = "sha256:a26197957d8e4425dfba746315f3c425ea00cfa8367c5fbc4ec73447893dcea9", size = 2664127, upload-time = "2026-04-27T14:43:26.949Z" }, +] + [[package]] name = "tomli" version = "2.4.1" @@ -2495,6 +2665,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/22/2a/5e5e750890ada51017d18d0d4c30da696e5b5bd3180947729927628fc3cb/tqdm-4.68.4-py3-none-any.whl", hash = "sha256:5168118b2368f48c561afda8020fd79195b1bdb0bdf8086b88442c267a315dc2", size = 676612, upload-time = "2026-07-07T09:58:16.256Z" }, ] +[[package]] +name = "types-requests" +version = "2.33.0.20260712" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/db/51/703318f7b7be8bee126ec13bf615050f932d0179b8784420f3a0199cc769/types_requests-2.33.0.20260712.tar.gz", hash = "sha256:2141b67ab534a5c5cd2dac5034f2a35f42e699c5bf185eee608c5246a069d7fb", size = 25084, upload-time = "2026-07-12T05:14:20.455Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/e7/010c87f559e216d83f9dc51e939633fd0d0ead3377340181ab0e223cd3b5/types_requests-2.33.0.20260712-py3-none-any.whl", hash = "sha256:de027e28c171d3da529689cbfa023b0b4eab188c8dfa22fd834eebd2cee6e7bb", size = 21392, upload-time = "2026-07-12T05:14:19.616Z" }, +] + [[package]] name = "typing-extensions" version = "4.16.0"