From 221f15dee8b7e8d98dff693718b67ddd4d778e61 Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Thu, 29 Aug 2024 11:33:24 -0700 Subject: [PATCH 1/9] Merge branch 'main' of https://github.com/open-telemetry/opentelemetry-python-contrib into bugfix/registered-method-error From 4ba8ae79d1492c5d7a81b02898b84fa92aed0c88 Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Mon, 2 Dec 2024 13:34:28 -0800 Subject: [PATCH 2/9] message --- .../CHANGELOG.md | 11 + .../LICENSE | 201 +++++ .../README.rst | 29 + .../example/main.py | 25 + .../pyproject.toml | 54 ++ .../instrumentation/cohere_v2/__init__.py | 93 ++ .../instrumentation/cohere_v2/package.py | 16 + .../instrumentation/cohere_v2/patch.py | 66 ++ .../instrumentation/cohere_v2/utils.py | 142 +++ .../instrumentation/cohere_v2/version.py | 15 + .../tests/__init__.py | 0 .../test_async_chat_completion_404.yaml | 89 ++ ...st_async_chat_completion_extra_params.yaml | 137 +++ ...sync_chat_completion_multiple_choices.yaml | 143 +++ ...completion_multiple_choices_streaming.yaml | 382 ++++++++ ...n_multiple_tools_streaming_no_content.yaml | 164 ++++ ...multiple_tools_streaming_with_content.yaml | 164 ++++ .../test_async_chat_completion_streaming.yaml | 117 +++ ...hat_completion_streaming_not_complete.yaml | 112 +++ ...chat_completion_tool_calls_no_content.yaml | 342 +++++++ ...at_completion_tool_calls_with_content.yaml | 342 +++++++ ...st_async_chat_completion_with_content.yaml | 132 +++ .../cassettes/test_chat_completion_404.yaml | 91 ++ .../test_chat_completion_extra_params.yaml | 139 +++ ...test_chat_completion_multiple_choices.yaml | 145 +++ ...completion_multiple_choices_streaming.yaml | 326 +++++++ ...n_multiple_tools_streaming_no_content.yaml | 166 ++++ ...multiple_tools_streaming_with_content.yaml | 166 ++++ .../test_chat_completion_streaming.yaml | 119 +++ ...hat_completion_streaming_not_complete.yaml | 114 +++ ...chat_completion_tool_calls_no_content.yaml | 346 +++++++ ...at_completion_tool_calls_with_content.yaml | 346 +++++++ .../test_chat_completion_with_content.yaml | 134 +++ .../tests/conftest.py | 186 ++++ .../tests/test_async_chat_completions.py | 847 ++++++++++++++++++ .../tests/test_chat_completions.py | 825 +++++++++++++++++ .../README.rst | 4 +- .../pyproject.toml | 2 +- .../instrumentation/openai_v2/__init__.py | 2 +- .../instrumentation/openai_v2/patch.py | 6 +- .../instrumentation/openai_v2/utils.py | 9 - .../instrumentation/genai_utils.py | 51 ++ 42 files changed, 6786 insertions(+), 14 deletions(-) create mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/CHANGELOG.md create mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/LICENSE create mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/README.rst create mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/example/main.py create mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/pyproject.toml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/__init__.py create mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/package.py create mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/patch.py create mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/utils.py create mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/version.py create mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/__init__.py create mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_404.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_extra_params.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_multiple_choices.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_multiple_choices_streaming.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_multiple_tools_streaming_no_content.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_multiple_tools_streaming_with_content.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_streaming.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_streaming_not_complete.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_tool_calls_no_content.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_tool_calls_with_content.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_with_content.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_404.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_extra_params.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_multiple_choices.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_multiple_choices_streaming.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_no_content.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_with_content.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_streaming.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_streaming_not_complete.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_tool_calls_no_content.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_tool_calls_with_content.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_with_content.yaml create mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/conftest.py create mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/test_async_chat_completions.py create mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/test_chat_completions.py create mode 100644 opentelemetry-instrumentation/src/opentelemetry/instrumentation/genai_utils.py diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/CHANGELOG.md b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/CHANGELOG.md new file mode 100644 index 0000000000..f3f2bd3f56 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/CHANGELOG.md @@ -0,0 +1,11 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## Unreleased + +- Initial Cohere instrumentation + ([#2759](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2759)) diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/LICENSE b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/LICENSE new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/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 Liability. 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 [yyyy] [name of copyright owner] + + 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-genai/opentelemetry-instrumentation-cohere-v2/README.rst b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/README.rst new file mode 100644 index 0000000000..f167d4e6c8 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/README.rst @@ -0,0 +1,29 @@ +OpenTelemetry Cohere Instrumentation +==================================== + +|pypi| + +.. |pypi| image:: https://badge.fury.io/py/opentelemetry-instrumentation-cohere-v2.svg + :target: https://pypi.org/project/opentelemetry-instrumentation-cohere-v2/ + +This library allows tracing LLM requests and logging of messages made by the +`Cohere Python API library `_. + + +Installation +------------ + +If your application is already instrumented with OpenTelemetry, add this +package to your requirements. +:: + + pip install opentelemetry-instrumentation-cohere-v2 + +If you don't have an Cohere application, yet, try our `example `_ +which only needs a valid Cohere API key. + +References +---------- +* `OpenTelemetry Cohere Instrumentation `_ +* `OpenTelemetry Project `_ +* `OpenTelemetry Python Examples `_ diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/example/main.py b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/example/main.py new file mode 100644 index 0000000000..3f2450159c --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/example/main.py @@ -0,0 +1,25 @@ +import cohere + +from opentelemetry import trace +from opentelemetry.instrumentation.cohere_v2 import CohereInstrumentor +from opentelemetry.sdk.trace import TracerProvider +from opentelemetry.sdk.trace.export import ( + BatchSpanProcessor, + ConsoleSpanExporter, +) + +CohereInstrumentor().instrument() + +trace.set_tracer_provider(TracerProvider()) +trace.get_tracer_provider().add_span_processor( + BatchSpanProcessor(ConsoleSpanExporter()) +) +tracer = trace.get_tracer(__name__) + +co = cohere.ClientV2('Z4EInAKRbIRKQV9lRZTciJqYyUBHXZGVUOAFBlRJ') + +with tracer.start_as_current_span("foo"): + response = co.chat( + model="command-r-plus", + messages=[{"role": "user", "content": "Write a short poem on OpenTelemetry."}] + ) diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/pyproject.toml new file mode 100644 index 0000000000..9d0fed4428 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/pyproject.toml @@ -0,0 +1,54 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "opentelemetry-instrumentation-cohere-v2" +dynamic = ["version"] +description = "OpenTelemetry Official Cohere instrumentation" +readme = "README.rst" +license = "Apache-2.0" +requires-python = ">=3.8" +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.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", +] +dependencies = [ + "opentelemetry-api ~= 1.28", + "opentelemetry-instrumentation ~= 0.49b0", + "opentelemetry-semantic-conventions ~= 0.49b0" +] + +[project.optional-dependencies] +instruments = [ + "cohere >= 5.11.4", +] + +[project.entry-points.opentelemetry_instrumentor] +openai = "opentelemetry.instrumentation.cohere_v2:CohereInstrumentor" + +[project.urls] +Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation-genai/opentelemetry-instrumentation-cohere-v2" + +[tool.hatch.version] +path = "src/opentelemetry/instrumentation/cohere_v2/version.py" + +[tool.hatch.build.targets.sdist] +include = [ + "/src", + "/tests", +] + +[tool.hatch.build.targets.wheel] +packages = ["src/opentelemetry"] diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/__init__.py b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/__init__.py new file mode 100644 index 0000000000..74a60952c4 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/__init__.py @@ -0,0 +1,93 @@ +# 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. + +""" +Cohere client instrumentation supporting `cohere`, it can be enabled by +using ``CohereInstrumentor``. + +.. _openai: https://pypi.org/project/cohere/ + +Usage +----- + +.. code:: python + + import cohere + from opentelemetry.instrumentation.cohere_v2 import CohereInstrumentor + + CohereInstrumentor().instrument() + + co = cohere.ClientV2('') + + response = co.chat( + model="command-r-plus", + messages=[{"role": "user", "content": "Write a short poem on OpenTelemetry."}] + ) + +API +--- +""" + +from typing import Collection + +from wrapt import wrap_function_wrapper + +from opentelemetry._events import get_event_logger +from opentelemetry.instrumentation.genai_utils import is_content_enabled +from opentelemetry.instrumentation.instrumentor import BaseInstrumentor +from opentelemetry.instrumentation.cohere_v2.package import _instruments +from opentelemetry.instrumentation.cohere_v2.version import __version__ +from opentelemetry.instrumentation.utils import unwrap +from opentelemetry.semconv.schemas import Schemas +from opentelemetry.trace import get_tracer + +from .patch import client_chat + + +class CohereInstrumentor(BaseInstrumentor): + """An instrumentor for Cohere's client library.""" + + def instrumentation_dependencies(self) -> Collection[str]: + return _instruments + + def _instrument(self, **kwargs): + """Enable Cohere instrumentation.""" + tracer_provider = kwargs.get("tracer_provider") + tracer = get_tracer( + __name__, + __version__, + tracer_provider, + schema_url=Schemas.V1_28_0.value, + ) + event_logger_provider = kwargs.get("event_logger_provider") + event_logger = get_event_logger( + __name__, + __version__, + schema_url=Schemas.V1_28_0.value, + event_logger_provider=event_logger_provider, + ) + + wrap_function_wrapper( + module="cohere.client_v2", + name="ClientV2.chat", + wrapper=client_chat( + tracer, event_logger, is_content_enabled() + ), + ) + + + def _uninstrument(self, **kwargs): + import cohere # pylint: disable=import-outside-toplevel + + unwrap(cohere.client_v2.ClientV2, "chat") diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/package.py b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/package.py new file mode 100644 index 0000000000..b7be16a26f --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/package.py @@ -0,0 +1,16 @@ +# 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. + + +_instruments = ("cohere >= 5.11.4",) diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/patch.py b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/patch.py new file mode 100644 index 0000000000..bf74dd7187 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/patch.py @@ -0,0 +1,66 @@ +# 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. + +from opentelemetry._events import Event, EventLogger +from opentelemetry.trace import Span, SpanKind, Tracer +from opentelemetry.instrumentation.genai_utils import ( + get_span_name, + handle_span_exception +) +from opentelemetry.instrumentation.utils import is_instrumentation_enabled +from .utils import ( + get_llm_request_attributes, + message_to_event, + set_server_address_and_port +) + + +def client_chat( + tracer: Tracer, event_logger: EventLogger, capture_content: bool +): + """Wrap the `chat` method of the `ClientV2` class to trace it.""" + + def traced_method(wrapped, instance, args, kwargs): + if not is_instrumentation_enabled(): + return wrapped(*args, **kwargs) + + span_attributes = {**get_llm_request_attributes(kwargs, instance)} + set_server_address_and_port(instance, span_attributes) + span_name = get_span_name(span_attributes) + + with tracer.start_as_current_span( + name=span_name, + kind=SpanKind.CLIENT, + attributes=span_attributes, + ) as span: + if span.is_recording(): + for message in kwargs.get("messages", []): + event_logger.emit( + message_to_event(message, capture_content) + ) + + try: + result = wrapped(*args, **kwargs) + # if span.is_recording(): + # _set_response_attributes( + # span, result, event_logger, capture_content + # ) + span.end() + return result + + except Exception as error: + handle_span_exception(span, error) + raise + + return traced_method diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/utils.py b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/utils.py new file mode 100644 index 0000000000..e91711c86e --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/utils.py @@ -0,0 +1,142 @@ +# 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. + +from typing import Optional, Union +from urllib.parse import urlparse + +from opentelemetry._events import Event +from opentelemetry.semconv._incubating.attributes import ( + gen_ai_attributes as GenAIAttributes, +) +from opentelemetry.semconv._incubating.attributes import ( + server_attributes as ServerAttributes, +) + + +def extract_tool_calls(item, capture_content): + tool_calls = get_property_value(item, "tool_calls") + if tool_calls is None: + return None + + calls = [] + for tool_call in tool_calls: + tool_call_dict = {} + call_id = get_property_value(tool_call, "id") + if call_id: + tool_call_dict["id"] = call_id + + tool_type = get_property_value(tool_call, "type") + if tool_type: + tool_call_dict["type"] = tool_type + + func = get_property_value(tool_call, "function") + if func: + tool_call_dict["function"] = {} + + name = get_property_value(func, "name") + if name: + tool_call_dict["function"]["name"] = name + + arguments = get_property_value(func, "arguments") + if capture_content and arguments: + if isinstance(arguments, str): + arguments = arguments.replace("\n", "") + tool_call_dict["function"]["arguments"] = arguments + + calls.append(tool_call_dict) + return calls + + +def get_property_value(obj, property_name): + if isinstance(obj, dict): + return obj.get(property_name, None) + + return getattr(obj, property_name, None) + + +def set_server_address_and_port(client_instance, attributes): + base_client = getattr(client_instance, "_client_wrapper", None) + base_url = getattr(base_client, "base_url", None) + if not base_url: + return + + port = -1 + url = urlparse(base_url) + attributes[ServerAttributes.SERVER_ADDRESS] = url.hostname + port = url.port + + if port and port != 443 and port > 0: + attributes[ServerAttributes.SERVER_PORT] = port + + +def get_llm_request_attributes( + kwargs, + client_instance, + operation_name=GenAIAttributes.GenAiOperationNameValues.CHAT.value, +): + attributes = { + GenAIAttributes.GEN_AI_OPERATION_NAME: operation_name, + GenAIAttributes.GEN_AI_SYSTEM: GenAIAttributes.GenAiSystemValues.COHERE.value, + GenAIAttributes.GEN_AI_REQUEST_MODEL: kwargs.get("model"), + GenAIAttributes.GEN_AI_REQUEST_MAX_TOKENS: kwargs.get("max_tokens"), + GenAIAttributes.GEN_AI_REQUEST_FREQUENCY_PENALTY: kwargs.get( + "stop_sequences" + ), + GenAIAttributes.GEN_AI_REQUEST_TEMPERATURE: kwargs.get("temperature"), + # TODO: Add to sem conv + "gen_ai.cohere.request.seed": kwargs.get("seed"), + GenAIAttributes.GEN_AI_REQUEST_PRESENCE_PENALTY: kwargs.get( + "presence_penalty" + ), + GenAIAttributes.GEN_AI_REQUEST_FREQUENCY_PENALTY: kwargs.get( + "frequency_penalty" + ), + GenAIAttributes.GEN_AI_REQUEST_TOP_K: kwargs.get("k"), + GenAIAttributes.GEN_AI_REQUEST_TOP_P: kwargs.get("p"), + } + response_format = kwargs.get("response_format") + if response_format: + # TODO: Add to sem conv + attributes["gen_ai.cohere.request.response_format"] = response_format.type + + set_server_address_and_port(client_instance, attributes) + + # filter out None values + return {k: v for k, v in attributes.items() if v is not None} + + +def message_to_event(message, capture_content): + attributes = { + GenAIAttributes.GEN_AI_SYSTEM: GenAIAttributes.GenAiSystemValues.COHERE.value + } + role = get_property_value(message, "role") + content = get_property_value(message, "content") + + body = {} + if capture_content and content: + body["content"] = content + if role == "assistant": + tool_calls = extract_tool_calls(message, capture_content) + if tool_calls: + body = {"tool_calls": tool_calls} + elif role == "tool": + tool_call_id = get_property_value(message, "tool_call_id") + if tool_call_id: + body["id"] = tool_call_id + + return Event( + name=f"gen_ai.{role}.message", + attributes=attributes, + body=body if body else None, + ) diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/version.py b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/version.py new file mode 100644 index 0000000000..61ae9b7c25 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/version.py @@ -0,0 +1,15 @@ +# 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. + +__version__ = "2.0b0.dev" diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/__init__.py b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_404.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_404.yaml new file mode 100644 index 0000000000..e055e68f20 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_404.yaml @@ -0,0 +1,89 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "user", + "content": "Say this is a test" + } + ], + "model": "this-model-does-not-exist" + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '103' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - AsyncOpenAI/Python 1.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - async:asyncio + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.26.0 + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.5 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |- + { + "error": { + "message": "The model `this-model-does-not-exist` does not exist or you do not have access to it.", + "type": "invalid_request_error", + "param": null, + "code": "model_not_found" + } + } + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1a80827a861852-MRS + Connection: + - keep-alive + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 13 Nov 2024 00:04:01 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + alt-svc: + - h3=":443"; ma=86400 + content-length: + - '231' + openai-organization: test_openai_org_id + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + vary: + - Origin + x-request-id: + - req_5cf06a7fabd45ebe21ee38c14c5b2f76 + status: + code: 404 + message: Not Found +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_extra_params.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_extra_params.yaml new file mode 100644 index 0000000000..3d13c9344e --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_extra_params.yaml @@ -0,0 +1,137 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "user", + "content": "Say this is a test" + } + ], + "model": "gpt-4o-mini", + "max_tokens": 50, + "seed": 42, + "stream": false, + "temperature": 0.5, + "service_tier": "default" + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '183' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - AsyncOpenAI/Python 1.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - async:asyncio + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.26.0 + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.5 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |- + { + "id": "chatcmpl-ASv9WMTAMZY4O1EImv3csZa6Ch7KI", + "object": "chat.completion", + "created": 1731456242, + "model": "gpt-4o-mini-2024-07-18", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": "This is a test. How can I assist you further?", + "refusal": null + }, + "logprobs": null, + "finish_reason": "stop" + } + ], + "usage": { + "prompt_tokens": 12, + "completion_tokens": 12, + "total_tokens": 24, + "prompt_tokens_details": { + "cached_tokens": 0, + "audio_tokens": 0 + }, + "completion_tokens_details": { + "reasoning_tokens": 0, + "audio_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 + } + }, + "service_tier": "default", + "system_fingerprint": "fp_0ba0d124f1" + } + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1a8088f867e167-MRS + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Wed, 13 Nov 2024 00:04:02 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + content-length: + - '825' + openai-organization: test_openai_org_id + openai-processing-ms: + - '488' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '30000' + x-ratelimit-limit-tokens: + - '150000000' + x-ratelimit-remaining-requests: + - '29999' + x-ratelimit-remaining-tokens: + - '149999943' + x-ratelimit-reset-requests: + - 2ms + x-ratelimit-reset-tokens: + - 0s + x-request-id: + - req_6df08d6267415e8f5db3628a6757edad + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_multiple_choices.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_multiple_choices.yaml new file mode 100644 index 0000000000..1404b8163a --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_multiple_choices.yaml @@ -0,0 +1,143 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "user", + "content": "Say this is a test" + } + ], + "model": "gpt-4o-mini", + "n": 2, + "stream": false + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '114' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - AsyncOpenAI/Python 1.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - async:asyncio + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.26.0 + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.5 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |- + { + "id": "chatcmpl-ASv9XLlMmT7H3cf50dNTesHDBDwX5", + "object": "chat.completion", + "created": 1731456243, + "model": "gpt-4o-mini-2024-07-18", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": "This is a test.", + "refusal": null + }, + "logprobs": null, + "finish_reason": "stop" + }, + { + "index": 1, + "message": { + "role": "assistant", + "content": "This is a test.", + "refusal": null + }, + "logprobs": null, + "finish_reason": "stop" + } + ], + "usage": { + "prompt_tokens": 12, + "completion_tokens": 10, + "total_tokens": 22, + "prompt_tokens_details": { + "cached_tokens": 0, + "audio_tokens": 0 + }, + "completion_tokens_details": { + "reasoning_tokens": 0, + "audio_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 + } + }, + "system_fingerprint": "fp_0ba0d124f1" + } + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1a808f6d8e0d8b-MRS + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Wed, 13 Nov 2024 00:04:04 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + content-length: + - '970' + openai-organization: test_openai_org_id + openai-processing-ms: + - '306' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '30000' + x-ratelimit-limit-tokens: + - '150000000' + x-ratelimit-remaining-requests: + - '29999' + x-ratelimit-remaining-tokens: + - '149999962' + x-ratelimit-reset-requests: + - 2ms + x-ratelimit-reset-tokens: + - 0s + x-request-id: + - req_1317908e0f9b73276b57d4e171c533ea + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_multiple_choices_streaming.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_multiple_choices_streaming.yaml new file mode 100644 index 0000000000..4bca03a9e8 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_multiple_choices_streaming.yaml @@ -0,0 +1,382 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "system", + "content": "You're a helpful assistant." + }, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?" + } + ], + "model": "gpt-4o-mini", + "n": 2, + "stream": true, + "stream_options": { + "include_usage": true + } + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '254' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - AsyncOpenAI/Python 1.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - async:asyncio + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.26.0 + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.5 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |+ + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"I'm"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"I'm"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" unable"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" unable"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" provide"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" provide"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" real"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" real"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"-time"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"-time"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" updates"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" updates"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" as"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" as"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" my"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" my"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" knowledge"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" knowledge"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" was"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" only"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" last"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" extends"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" until"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" updated"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" in"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" October"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" October"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" "},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" "},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"202"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"202"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"3"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"1"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" I"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" I"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" don't"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" have"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" access"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" don't"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" have"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" access"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" live"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" live"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" data"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" data"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" However"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" However"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" you"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" you"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" can"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" can"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" easily"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" easily"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" check"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" check"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" current"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" current"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" in"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" for"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" Seattle"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" Seattle"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" San"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" San"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" Francisco"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" Francisco"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" by"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" using"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" visiting"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" website"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" website"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" or"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" or"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" using"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" mobile"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" app"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" for"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" app"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" most"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" If"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" accurate"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" you"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" need"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" up"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" historical"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" information"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" or"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" general"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" climate"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" data"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" for"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" those"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" cities"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" feel"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" free"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" ask"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"!"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"-to"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"-date"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" information"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null} + + data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[],"usage":{"prompt_tokens":26,"completion_tokens":133,"total_tokens":159,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}}} + + data: [DONE] + + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1a80ceac3ce19a-MRS + Connection: + - keep-alive + Content-Type: + - text/event-stream; charset=utf-8 + Date: + - Wed, 13 Nov 2024 00:04:13 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + openai-organization: test_openai_org_id + openai-processing-ms: + - '126' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '30000' + x-ratelimit-limit-tokens: + - '150000000' + x-ratelimit-remaining-requests: + - '29999' + x-ratelimit-remaining-tokens: + - '149999945' + x-ratelimit-reset-requests: + - 2ms + x-ratelimit-reset-tokens: + - 0s + x-request-id: + - req_5dd8b6845db59fa55cf226eda1f5a2c6 + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_multiple_tools_streaming_no_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_multiple_tools_streaming_no_content.yaml new file mode 100644 index 0000000000..19319de476 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_multiple_tools_streaming_no_content.yaml @@ -0,0 +1,164 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "system", + "content": "You're a helpful assistant." + }, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?" + } + ], + "model": "gpt-4o-mini", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "function": { + "name": "get_current_weather", + "description": "Get the current weather in a given location", + "parameters": { + "type": "object", + "properties": { + "location": { + "type": "string", + "description": "The city and state, e.g. Boston, MA" + } + }, + "required": [ + "location" + ], + "additionalProperties": false + } + } + } + ] + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '602' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - AsyncOpenAI/Python 1.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - async:asyncio + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.26.0 + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.5 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |+ + data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"role":"assistant","content":null},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_hqkL24CLEwnniv4GDrjk14Iu","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n\": \"S"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"eatt"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"le, W"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"id":"call_0s1enkFttXjIR7ozHoGMcnUu","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"n\": \"S"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"an F"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"ranci"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"sco, C"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"tool_calls"}],"usage":null} + + data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[],"usage":{"prompt_tokens":75,"completion_tokens":51,"total_tokens":126,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}}} + + data: [DONE] + + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1a80e4cfb00d86-MRS + Connection: + - keep-alive + Content-Type: + - text/event-stream; charset=utf-8 + Date: + - Wed, 13 Nov 2024 00:04:19 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + openai-organization: test_openai_org_id + openai-processing-ms: + - '1597' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '30000' + x-ratelimit-limit-tokens: + - '150000000' + x-ratelimit-remaining-requests: + - '29999' + x-ratelimit-remaining-tokens: + - '149999960' + x-ratelimit-reset-requests: + - 2ms + x-ratelimit-reset-tokens: + - 0s + x-request-id: + - req_487aef2347cb4d1f97077c488dd93628 + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_multiple_tools_streaming_with_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_multiple_tools_streaming_with_content.yaml new file mode 100644 index 0000000000..a026912ee1 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_multiple_tools_streaming_with_content.yaml @@ -0,0 +1,164 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "system", + "content": "You're a helpful assistant." + }, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?" + } + ], + "model": "gpt-4o-mini", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "function": { + "name": "get_current_weather", + "description": "Get the current weather in a given location", + "parameters": { + "type": "object", + "properties": { + "location": { + "type": "string", + "description": "The city and state, e.g. Boston, MA" + } + }, + "required": [ + "location" + ], + "additionalProperties": false + } + } + } + ] + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '602' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - AsyncOpenAI/Python 1.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - async:asyncio + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.26.0 + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.5 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |+ + data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"role":"assistant","content":null},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_oJL2dc4GjWVxqBtWlGLwjbsR","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n\": \"S"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"eatt"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"le, W"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"id":"call_ON3lp1OWsbw2obNRD43KVDp6","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"n\": \"S"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"an F"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"ranci"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"sco, C"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"tool_calls"}],"usage":null} + + data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[],"usage":{"prompt_tokens":75,"completion_tokens":51,"total_tokens":126,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}}} + + data: [DONE] + + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1a80d8efb9e1c8-MRS + Connection: + - keep-alive + Content-Type: + - text/event-stream; charset=utf-8 + Date: + - Wed, 13 Nov 2024 00:04:16 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + openai-organization: test_openai_org_id + openai-processing-ms: + - '1162' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '30000' + x-ratelimit-limit-tokens: + - '150000000' + x-ratelimit-remaining-requests: + - '29999' + x-ratelimit-remaining-tokens: + - '149999960' + x-ratelimit-reset-requests: + - 2ms + x-ratelimit-reset-tokens: + - 0s + x-request-id: + - req_0b6729aef347cecd61ba3b7b7a8d4719 + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_streaming.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_streaming.yaml new file mode 100644 index 0000000000..efffcd7423 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_streaming.yaml @@ -0,0 +1,117 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "user", + "content": "Say this is a test" + } + ], + "model": "gpt-4", + "stream": true, + "stream_options": { + "include_usage": true + } + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '142' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - AsyncOpenAI/Python 1.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - async:asyncio + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.26.0 + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.5 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |+ + data: {"id":"chatcmpl-ASv9ejXDUtAhGOJJxWuw026zdinc4","object":"chat.completion.chunk","created":1731456250,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9ejXDUtAhGOJJxWuw026zdinc4","object":"chat.completion.chunk","created":1731456250,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"This"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9ejXDUtAhGOJJxWuw026zdinc4","object":"chat.completion.chunk","created":1731456250,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" is"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9ejXDUtAhGOJJxWuw026zdinc4","object":"chat.completion.chunk","created":1731456250,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9ejXDUtAhGOJJxWuw026zdinc4","object":"chat.completion.chunk","created":1731456250,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" test"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9ejXDUtAhGOJJxWuw026zdinc4","object":"chat.completion.chunk","created":1731456250,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASv9ejXDUtAhGOJJxWuw026zdinc4","object":"chat.completion.chunk","created":1731456250,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null} + + data: {"id":"chatcmpl-ASv9ejXDUtAhGOJJxWuw026zdinc4","object":"chat.completion.chunk","created":1731456250,"model":"gpt-4-0613","system_fingerprint":null,"choices":[],"usage":{"prompt_tokens":12,"completion_tokens":5,"total_tokens":17,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}}} + + data: [DONE] + + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1a80bd2f31e1e5-MRS + Connection: + - keep-alive + Content-Type: + - text/event-stream; charset=utf-8 + Date: + - Wed, 13 Nov 2024 00:04:11 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + openai-organization: test_openai_org_id + openai-processing-ms: + - '196' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '10000' + x-ratelimit-limit-tokens: + - '1000000' + x-ratelimit-remaining-requests: + - '9999' + x-ratelimit-remaining-tokens: + - '999977' + x-ratelimit-reset-requests: + - 6ms + x-ratelimit-reset-tokens: + - 1ms + x-request-id: + - req_cc9204ae23338b130df11c8c5b5f31af + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_streaming_not_complete.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_streaming_not_complete.yaml new file mode 100644 index 0000000000..9ef5613d17 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_streaming_not_complete.yaml @@ -0,0 +1,112 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "user", + "content": "Say this is a test" + } + ], + "model": "gpt-4", + "stream": true + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '99' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - AsyncOpenAI/Python 1.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - async:asyncio + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.26.0 + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.5 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |+ + data: {"id":"chatcmpl-ASv9gROIIAvRs9QnmLP8Nzs3PGMCX","object":"chat.completion.chunk","created":1731456252,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9gROIIAvRs9QnmLP8Nzs3PGMCX","object":"chat.completion.chunk","created":1731456252,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"This"},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9gROIIAvRs9QnmLP8Nzs3PGMCX","object":"chat.completion.chunk","created":1731456252,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" is"},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9gROIIAvRs9QnmLP8Nzs3PGMCX","object":"chat.completion.chunk","created":1731456252,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9gROIIAvRs9QnmLP8Nzs3PGMCX","object":"chat.completion.chunk","created":1731456252,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" test"},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9gROIIAvRs9QnmLP8Nzs3PGMCX","object":"chat.completion.chunk","created":1731456252,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASv9gROIIAvRs9QnmLP8Nzs3PGMCX","object":"chat.completion.chunk","created":1731456252,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]} + + data: [DONE] + + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1a80c54d00e288-MRS + Connection: + - keep-alive + Content-Type: + - text/event-stream; charset=utf-8 + Date: + - Wed, 13 Nov 2024 00:04:12 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + openai-organization: test_openai_org_id + openai-processing-ms: + - '283' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '10000' + x-ratelimit-limit-tokens: + - '1000000' + x-ratelimit-remaining-requests: + - '9999' + x-ratelimit-remaining-tokens: + - '999977' + x-ratelimit-reset-requests: + - 6ms + x-ratelimit-reset-tokens: + - 1ms + x-request-id: + - req_e9e4ea6fd060391e8cc8cfea78ad9a15 + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_tool_calls_no_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_tool_calls_no_content.yaml new file mode 100644 index 0000000000..053e271d45 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_tool_calls_no_content.yaml @@ -0,0 +1,342 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "system", + "content": "You're a helpful assistant." + }, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?" + } + ], + "model": "gpt-4o-mini", + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "function": { + "name": "get_current_weather", + "description": "Get the current weather in a given location", + "parameters": { + "type": "object", + "properties": { + "location": { + "type": "string", + "description": "The city and state, e.g. Boston, MA" + } + }, + "required": [ + "location" + ], + "additionalProperties": false + } + } + } + ] + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '543' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - AsyncOpenAI/Python 1.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - async:asyncio + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.26.0 + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.5 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |- + { + "id": "chatcmpl-ASv9bJqWatpvCC0YMsYRcTSIiXoxk", + "object": "chat.completion", + "created": 1731456247, + "model": "gpt-4o-mini-2024-07-18", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": null, + "tool_calls": [ + { + "id": "call_vwOezSsB5j9ei1SSMlZjqx7g", + "type": "function", + "function": { + "name": "get_current_weather", + "arguments": "{\"location\": \"Seattle, WA\"}" + } + }, + { + "id": "call_LzeIYcKhHnVF60u4LmBpT1tv", + "type": "function", + "function": { + "name": "get_current_weather", + "arguments": "{\"location\": \"San Francisco, CA\"}" + } + } + ], + "refusal": null + }, + "logprobs": null, + "finish_reason": "tool_calls" + } + ], + "usage": { + "prompt_tokens": 75, + "completion_tokens": 51, + "total_tokens": 126, + "prompt_tokens_details": { + "cached_tokens": 0, + "audio_tokens": 0 + }, + "completion_tokens_details": { + "reasoning_tokens": 0, + "audio_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 + } + }, + "system_fingerprint": "fp_0ba0d124f1" + } + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1a80a9f8fbe1c9-MRS + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Wed, 13 Nov 2024 00:04:08 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + content-length: + - '1308' + openai-organization: test_openai_org_id + openai-processing-ms: + - '808' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '30000' + x-ratelimit-limit-tokens: + - '150000000' + x-ratelimit-remaining-requests: + - '29999' + x-ratelimit-remaining-tokens: + - '149999960' + x-ratelimit-reset-requests: + - 2ms + x-ratelimit-reset-tokens: + - 0s + x-request-id: + - req_f1b9b75e4a73b542c9b1b992cd52c66f + status: + code: 200 + message: OK +- request: + body: |- + { + "messages": [ + { + "role": "system", + "content": "You're a helpful assistant." + }, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?" + }, + { + "role": "assistant", + "tool_calls": [ + { + "id": "call_vwOezSsB5j9ei1SSMlZjqx7g", + "function": { + "arguments": "{\"location\": \"Seattle, WA\"}", + "name": "get_current_weather" + }, + "type": "function" + }, + { + "id": "call_LzeIYcKhHnVF60u4LmBpT1tv", + "function": { + "arguments": "{\"location\": \"San Francisco, CA\"}", + "name": "get_current_weather" + }, + "type": "function" + } + ] + }, + { + "role": "tool", + "content": "50 degrees and raining", + "tool_call_id": "call_vwOezSsB5j9ei1SSMlZjqx7g" + }, + { + "role": "tool", + "content": "70 degrees and sunny", + "tool_call_id": "call_LzeIYcKhHnVF60u4LmBpT1tv" + } + ], + "model": "gpt-4o-mini" + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '746' + content-type: + - application/json + cookie: + - test_cookie + host: + - api.openai.com + user-agent: + - AsyncOpenAI/Python 1.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - async:asyncio + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.26.0 + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.5 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |- + { + "id": "chatcmpl-ASv9dfXfIwGCZgeWzDTbCh0FuU9kh", + "object": "chat.completion", + "created": 1731456249, + "model": "gpt-4o-mini-2024-07-18", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": "Today, the weather in Seattle is 50 degrees and raining, while in San Francisco, it's 70 degrees and sunny.", + "refusal": null + }, + "logprobs": null, + "finish_reason": "stop" + } + ], + "usage": { + "prompt_tokens": 99, + "completion_tokens": 25, + "total_tokens": 124, + "prompt_tokens_details": { + "cached_tokens": 0, + "audio_tokens": 0 + }, + "completion_tokens_details": { + "reasoning_tokens": 0, + "audio_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 + } + }, + "system_fingerprint": "fp_0ba0d124f1" + } + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1a80b3baade1c9-MRS + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Wed, 13 Nov 2024 00:04:10 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + content-length: + - '859' + openai-organization: test_openai_org_id + openai-processing-ms: + - '972' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '30000' + x-ratelimit-limit-tokens: + - '150000000' + x-ratelimit-remaining-requests: + - '29999' + x-ratelimit-remaining-tokens: + - '149999948' + x-ratelimit-reset-requests: + - 2ms + x-ratelimit-reset-tokens: + - 0s + x-request-id: + - req_754e6b59f1d3da727e2210e3d8c56243 + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_tool_calls_with_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_tool_calls_with_content.yaml new file mode 100644 index 0000000000..ebebb20603 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_tool_calls_with_content.yaml @@ -0,0 +1,342 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "system", + "content": "You're a helpful assistant." + }, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?" + } + ], + "model": "gpt-4o-mini", + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "function": { + "name": "get_current_weather", + "description": "Get the current weather in a given location", + "parameters": { + "type": "object", + "properties": { + "location": { + "type": "string", + "description": "The city and state, e.g. Boston, MA" + } + }, + "required": [ + "location" + ], + "additionalProperties": false + } + } + } + ] + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '543' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - AsyncOpenAI/Python 1.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - async:asyncio + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.26.0 + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.5 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |- + { + "id": "chatcmpl-ASv9ZqgNAOJAOLYMgdmxouatKXJlk", + "object": "chat.completion", + "created": 1731456245, + "model": "gpt-4o-mini-2024-07-18", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": null, + "tool_calls": [ + { + "id": "call_O8NOz8VlxosSASEsOY7LDUcP", + "type": "function", + "function": { + "name": "get_current_weather", + "arguments": "{\"location\": \"Seattle, WA\"}" + } + }, + { + "id": "call_3m7cyuckijnpiWr6tq0Tl8Mg", + "type": "function", + "function": { + "name": "get_current_weather", + "arguments": "{\"location\": \"San Francisco, CA\"}" + } + } + ], + "refusal": null + }, + "logprobs": null, + "finish_reason": "tool_calls" + } + ], + "usage": { + "prompt_tokens": 75, + "completion_tokens": 51, + "total_tokens": 126, + "prompt_tokens_details": { + "cached_tokens": 0, + "audio_tokens": 0 + }, + "completion_tokens_details": { + "reasoning_tokens": 0, + "audio_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 + } + }, + "system_fingerprint": "fp_0ba0d124f1" + } + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1a8098ac5ae167-MRS + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Wed, 13 Nov 2024 00:04:06 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + content-length: + - '1308' + openai-organization: test_openai_org_id + openai-processing-ms: + - '937' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '30000' + x-ratelimit-limit-tokens: + - '150000000' + x-ratelimit-remaining-requests: + - '29999' + x-ratelimit-remaining-tokens: + - '149999960' + x-ratelimit-reset-requests: + - 2ms + x-ratelimit-reset-tokens: + - 0s + x-request-id: + - req_3cd7152d2c8c10b4f354b27165f6c2b5 + status: + code: 200 + message: OK +- request: + body: |- + { + "messages": [ + { + "role": "system", + "content": "You're a helpful assistant." + }, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?" + }, + { + "role": "assistant", + "tool_calls": [ + { + "id": "call_O8NOz8VlxosSASEsOY7LDUcP", + "function": { + "arguments": "{\"location\": \"Seattle, WA\"}", + "name": "get_current_weather" + }, + "type": "function" + }, + { + "id": "call_3m7cyuckijnpiWr6tq0Tl8Mg", + "function": { + "arguments": "{\"location\": \"San Francisco, CA\"}", + "name": "get_current_weather" + }, + "type": "function" + } + ] + }, + { + "role": "tool", + "content": "50 degrees and raining", + "tool_call_id": "call_O8NOz8VlxosSASEsOY7LDUcP" + }, + { + "role": "tool", + "content": "70 degrees and sunny", + "tool_call_id": "call_3m7cyuckijnpiWr6tq0Tl8Mg" + } + ], + "model": "gpt-4o-mini" + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '746' + content-type: + - application/json + cookie: + - test_cookie + host: + - api.openai.com + user-agent: + - AsyncOpenAI/Python 1.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - async:asyncio + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.26.0 + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.5 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |- + { + "id": "chatcmpl-ASv9aQnGndy04lqKoPRagym1eEaQK", + "object": "chat.completion", + "created": 1731456246, + "model": "gpt-4o-mini-2024-07-18", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": "Today, Seattle is experiencing 50 degrees and raining, while San Francisco has a pleasant 70 degrees and sunny weather.", + "refusal": null + }, + "logprobs": null, + "finish_reason": "stop" + } + ], + "usage": { + "prompt_tokens": 99, + "completion_tokens": 24, + "total_tokens": 123, + "prompt_tokens_details": { + "cached_tokens": 0, + "audio_tokens": 0 + }, + "completion_tokens_details": { + "reasoning_tokens": 0, + "audio_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 + } + }, + "system_fingerprint": "fp_f59a81427f" + } + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1a80a39c71e167-MRS + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Wed, 13 Nov 2024 00:04:07 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + content-length: + - '871' + openai-organization: test_openai_org_id + openai-processing-ms: + - '477' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '30000' + x-ratelimit-limit-tokens: + - '150000000' + x-ratelimit-remaining-requests: + - '29999' + x-ratelimit-remaining-tokens: + - '149999948' + x-ratelimit-reset-requests: + - 2ms + x-ratelimit-reset-tokens: + - 0s + x-request-id: + - req_193c74758ea30e77e55afe931e89fd6c + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_with_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_with_content.yaml new file mode 100644 index 0000000000..61ec4a646e --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_with_content.yaml @@ -0,0 +1,132 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "user", + "content": "Say this is a test" + } + ], + "model": "gpt-4o-mini", + "stream": false + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '106' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - AsyncOpenAI/Python 1.26.0 + x-stainless-arch: + - arm64 + x-stainless-async: + - async:asyncio + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.26.0 + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.5 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |- + { + "id": "chatcmpl-ASv9R2E7Yhb2e7bj4Xl0qm9s3J42Y", + "object": "chat.completion", + "created": 1731456237, + "model": "gpt-4o-mini-2024-07-18", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": "This is a test. How can I assist you further?", + "refusal": null + }, + "logprobs": null, + "finish_reason": "stop" + } + ], + "usage": { + "prompt_tokens": 12, + "completion_tokens": 12, + "total_tokens": 24, + "prompt_tokens_details": { + "cached_tokens": 0, + "audio_tokens": 0 + }, + "completion_tokens_details": { + "reasoning_tokens": 0, + "audio_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 + } + }, + "system_fingerprint": "fp_0ba0d124f1" + } + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1a80679a8311a6-MRS + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Wed, 13 Nov 2024 00:03:58 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + content-length: + - '796' + openai-organization: test_openai_org_id + openai-processing-ms: + - '359' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '30000' + x-ratelimit-limit-tokens: + - '150000000' + x-ratelimit-remaining-requests: + - '29999' + x-ratelimit-remaining-tokens: + - '149999978' + x-ratelimit-reset-requests: + - 2ms + x-ratelimit-reset-tokens: + - 0s + x-request-id: + - req_41ea134c1fc450d4ca4cf8d0c6a7c53a + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_404.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_404.yaml new file mode 100644 index 0000000000..fb713363d5 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_404.yaml @@ -0,0 +1,91 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "user", + "content": "Say this is a test" + } + ], + "model": "this-model-does-not-exist" + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '103' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.54.3 + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.54.3 + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.6 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |- + { + "error": { + "message": "The model `this-model-does-not-exist` does not exist or you do not have access to it.", + "type": "invalid_request_error", + "param": null, + "code": "model_not_found" + } + } + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1225a16c283d93-SIN + Connection: + - keep-alive + Content-Type: + - application/json; charset=utf-8 + Date: + - Mon, 11 Nov 2024 23:43:52 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + alt-svc: + - h3=":443"; ma=86400 + content-length: + - '231' + openai-organization: test_openai_org_id + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + vary: + - Origin + x-request-id: + - req_c3e0f92d7b5426d1a4a17bb3d39953ea + status: + code: 404 + message: Not Found +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_extra_params.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_extra_params.yaml new file mode 100644 index 0000000000..7cc89ad9b8 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_extra_params.yaml @@ -0,0 +1,139 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "user", + "content": "Say this is a test" + } + ], + "model": "gpt-4o-mini", + "max_tokens": 50, + "seed": 42, + "stream": false, + "temperature": 0.5, + "service_tier": "default" + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '183' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.54.3 + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.54.3 + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.6 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |- + { + "id": "chatcmpl-ASYMT7913Sp58qhZqQgY7g7Ia2J4M", + "object": "chat.completion", + "created": 1731368633, + "model": "gpt-4o-mini-2024-07-18", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": "This is a test. How can I assist you further?", + "refusal": null + }, + "logprobs": null, + "finish_reason": "stop" + } + ], + "usage": { + "prompt_tokens": 12, + "completion_tokens": 12, + "total_tokens": 24, + "prompt_tokens_details": { + "cached_tokens": 0, + "audio_tokens": 0 + }, + "completion_tokens_details": { + "reasoning_tokens": 0, + "audio_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 + } + }, + "service_tier": "default", + "system_fingerprint": "fp_0ba0d124f1" + } + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1225a3f8e9ce65-SIN + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Mon, 11 Nov 2024 23:43:53 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + content-length: + - '825' + openai-organization: test_openai_org_id + openai-processing-ms: + - '431' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '10000' + x-ratelimit-limit-tokens: + - '200000' + x-ratelimit-remaining-requests: + - '9998' + x-ratelimit-remaining-tokens: + - '199943' + x-ratelimit-reset-requests: + - 14.746s + x-ratelimit-reset-tokens: + - 16ms + x-request-id: + - req_81e29a8992ea8001c0240bd990acf0ab + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_multiple_choices.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_multiple_choices.yaml new file mode 100644 index 0000000000..23828e98f4 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_multiple_choices.yaml @@ -0,0 +1,145 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "user", + "content": "Say this is a test" + } + ], + "model": "gpt-4o-mini", + "n": 2, + "stream": false + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '114' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.54.3 + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.54.3 + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.6 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |- + { + "id": "chatcmpl-ASYMUBq69UHDarAz2fsd0O50rv0r1", + "object": "chat.completion", + "created": 1731368634, + "model": "gpt-4o-mini-2024-07-18", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": "This is a test. How can I assist you further?", + "refusal": null + }, + "logprobs": null, + "finish_reason": "stop" + }, + { + "index": 1, + "message": { + "role": "assistant", + "content": "This is a test. How can I assist you further?", + "refusal": null + }, + "logprobs": null, + "finish_reason": "stop" + } + ], + "usage": { + "prompt_tokens": 12, + "completion_tokens": 24, + "total_tokens": 36, + "prompt_tokens_details": { + "cached_tokens": 0, + "audio_tokens": 0 + }, + "completion_tokens_details": { + "reasoning_tokens": 0, + "audio_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 + } + }, + "system_fingerprint": "fp_0ba0d124f1" + } + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1225a91a253e53-SIN + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Mon, 11 Nov 2024 23:43:54 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + content-length: + - '1030' + openai-organization: test_openai_org_id + openai-processing-ms: + - '399' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '10000' + x-ratelimit-limit-tokens: + - '200000' + x-ratelimit-remaining-requests: + - '9997' + x-ratelimit-remaining-tokens: + - '199962' + x-ratelimit-reset-requests: + - 22.564s + x-ratelimit-reset-tokens: + - 11ms + x-request-id: + - req_01290a92a1a3d787c7a00bb3836da597 + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_multiple_choices_streaming.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_multiple_choices_streaming.yaml new file mode 100644 index 0000000000..ea06ca5984 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_multiple_choices_streaming.yaml @@ -0,0 +1,326 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "system", + "content": "You're a helpful assistant." + }, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?" + } + ], + "model": "gpt-4o-mini", + "n": 2, + "stream": true, + "stream_options": { + "include_usage": true + } + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '254' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.54.3 + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.54.3 + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.6 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |+ + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"I'm"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"I'm"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" unable"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" unable"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" provide"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" provide"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" real"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" real"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"-time"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"-time"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" updates"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" updates"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" as"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" To"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" my"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" get"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" capabilities"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" do"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" latest"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" not"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" include"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" information"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" accessing"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" for"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" live"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" Seattle"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" data"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" San"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" However"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" Francisco"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" you"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" I"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" can"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" recommend"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" easily"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" checking"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" check"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" reliable"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" current"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" website"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" in"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" or"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" Seattle"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" using"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" San"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" Francisco"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" app"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" using"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" You"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" can"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" also"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" website"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" ask"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" app"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" voice"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" or"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" assistant"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" service"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" or"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" search"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" Would"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" online"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" you"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" for"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" like"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" some"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" current"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" tips"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" on"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" conditions"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" where"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" find"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" this"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" information"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"?"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null} + + data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[],"usage":{"prompt_tokens":26,"completion_tokens":104,"total_tokens":130,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}}} + + data: [DONE] + + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1225d0fa1481e4-SIN + Connection: + - keep-alive + Content-Type: + - text/event-stream; charset=utf-8 + Date: + - Mon, 11 Nov 2024 23:44:00 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + openai-organization: test_openai_org_id + openai-processing-ms: + - '176' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '10000' + x-ratelimit-limit-tokens: + - '200000' + x-ratelimit-remaining-requests: + - '9993' + x-ratelimit-remaining-tokens: + - '199945' + x-ratelimit-reset-requests: + - 59.369s + x-ratelimit-reset-tokens: + - 16ms + x-request-id: + - req_892a6021b1acc00254d8ff80adcd82fb + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_no_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_no_content.yaml new file mode 100644 index 0000000000..951aa52259 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_no_content.yaml @@ -0,0 +1,166 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "system", + "content": "You're a helpful assistant." + }, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?" + } + ], + "model": "gpt-4o-mini", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "function": { + "name": "get_current_weather", + "description": "Get the current weather in a given location", + "parameters": { + "type": "object", + "properties": { + "location": { + "type": "string", + "description": "The city and state, e.g. Boston, MA" + } + }, + "required": [ + "location" + ], + "additionalProperties": false + } + } + } + ] + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '602' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.54.3 + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.54.3 + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.6 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |+ + data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"role":"assistant","content":null},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_j7L00WV19wwQCvKOIVZewXZm","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n\": \"S"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"eatt"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"le, W"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"id":"call_sAIOI3dvcd1YMsEqD8DI3l8B","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"n\": \"S"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"an F"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"ranci"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"sco, C"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"tool_calls"}],"usage":null} + + data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","choices":[],"usage":{"prompt_tokens":75,"completion_tokens":51,"total_tokens":126,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}}} + + data: [DONE] + + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1225e40bed40c8-SIN + Connection: + - keep-alive + Content-Type: + - text/event-stream; charset=utf-8 + Date: + - Mon, 11 Nov 2024 23:44:04 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + openai-organization: test_openai_org_id + openai-processing-ms: + - '1225' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '10000' + x-ratelimit-limit-tokens: + - '200000' + x-ratelimit-remaining-requests: + - '9991' + x-ratelimit-remaining-tokens: + - '199961' + x-ratelimit-reset-requests: + - 1m13.588s + x-ratelimit-reset-tokens: + - 11ms + x-request-id: + - req_102cd878d03c1cec0c12b95f928d03ee + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_with_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_with_content.yaml new file mode 100644 index 0000000000..d42ac86e37 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_with_content.yaml @@ -0,0 +1,166 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "system", + "content": "You're a helpful assistant." + }, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?" + } + ], + "model": "gpt-4o-mini", + "stream": true, + "stream_options": { + "include_usage": true + }, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "function": { + "name": "get_current_weather", + "description": "Get the current weather in a given location", + "parameters": { + "type": "object", + "properties": { + "location": { + "type": "string", + "description": "The city and state, e.g. Boston, MA" + } + }, + "required": [ + "location" + ], + "additionalProperties": false + } + } + } + ] + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '602' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.54.3 + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.54.3 + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.6 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |+ + data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"role":"assistant","content":null},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_fHCjJqt9Pysde6vcJcvbXGBx","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n\": \"S"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"eatt"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"le, W"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"id":"call_3J9foSw3CUb48lrqIXoTky6U","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"n\": \"S"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"an F"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"ranci"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"sco, C"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"tool_calls"}],"usage":null} + + data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","choices":[],"usage":{"prompt_tokens":75,"completion_tokens":51,"total_tokens":126,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}}} + + data: [DONE] + + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1225d8af0c3d93-SIN + Connection: + - keep-alive + Content-Type: + - text/event-stream; charset=utf-8 + Date: + - Mon, 11 Nov 2024 23:44:03 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + openai-organization: test_openai_org_id + openai-processing-ms: + - '1399' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '10000' + x-ratelimit-limit-tokens: + - '200000' + x-ratelimit-remaining-requests: + - '9992' + x-ratelimit-remaining-tokens: + - '199961' + x-ratelimit-reset-requests: + - 1m6.779s + x-ratelimit-reset-tokens: + - 11ms + x-request-id: + - req_d745d48bf030ac78e4790ee49848d05f + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_streaming.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_streaming.yaml new file mode 100644 index 0000000000..db482a440c --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_streaming.yaml @@ -0,0 +1,119 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "user", + "content": "Say this is a test" + } + ], + "model": "gpt-4", + "stream": true, + "stream_options": { + "include_usage": true + } + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '142' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.54.3 + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.54.3 + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.6 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |+ + data: {"id":"chatcmpl-ASYMZ4oSykiIFK4lXLReDiKyAjsQl","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMZ4oSykiIFK4lXLReDiKyAjsQl","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\"This"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMZ4oSykiIFK4lXLReDiKyAjsQl","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" is"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMZ4oSykiIFK4lXLReDiKyAjsQl","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMZ4oSykiIFK4lXLReDiKyAjsQl","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" test"},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMZ4oSykiIFK4lXLReDiKyAjsQl","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":".\""},"logprobs":null,"finish_reason":null}],"usage":null} + + data: {"id":"chatcmpl-ASYMZ4oSykiIFK4lXLReDiKyAjsQl","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null} + + data: {"id":"chatcmpl-ASYMZ4oSykiIFK4lXLReDiKyAjsQl","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[],"usage":{"prompt_tokens":12,"completion_tokens":5,"total_tokens":17,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}}} + + data: [DONE] + + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1225c87b273e53-SIN + Connection: + - keep-alive + Content-Type: + - text/event-stream; charset=utf-8 + Date: + - Mon, 11 Nov 2024 23:43:59 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + openai-organization: test_openai_org_id + openai-processing-ms: + - '207' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '10000' + x-ratelimit-limit-tokens: + - '10000' + x-ratelimit-remaining-requests: + - '9999' + x-ratelimit-remaining-tokens: + - '9978' + x-ratelimit-reset-requests: + - 8.64s + x-ratelimit-reset-tokens: + - 132ms + x-request-id: + - req_c367cf360ee88481fb7cd6c5d45bf9dc + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_streaming_not_complete.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_streaming_not_complete.yaml new file mode 100644 index 0000000000..4d56e51a06 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_streaming_not_complete.yaml @@ -0,0 +1,114 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "user", + "content": "Say this is a test" + } + ], + "model": "gpt-4", + "stream": true + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '99' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.54.3 + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.54.3 + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.6 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |+ + data: {"id":"chatcmpl-ASYMZbRqo8Bkz53FVzaTj7W7feOn4","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASYMZbRqo8Bkz53FVzaTj7W7feOn4","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"This"},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASYMZbRqo8Bkz53FVzaTj7W7feOn4","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" is"},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASYMZbRqo8Bkz53FVzaTj7W7feOn4","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASYMZbRqo8Bkz53FVzaTj7W7feOn4","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" test"},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASYMZbRqo8Bkz53FVzaTj7W7feOn4","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}]} + + data: {"id":"chatcmpl-ASYMZbRqo8Bkz53FVzaTj7W7feOn4","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]} + + data: [DONE] + + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1225ccb98e823b-SIN + Connection: + - keep-alive + Content-Type: + - text/event-stream; charset=utf-8 + Date: + - Mon, 11 Nov 2024 23:43:59 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + openai-organization: test_openai_org_id + openai-processing-ms: + - '205' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '10000' + x-ratelimit-limit-tokens: + - '10000' + x-ratelimit-remaining-requests: + - '9998' + x-ratelimit-remaining-tokens: + - '9978' + x-ratelimit-reset-requests: + - 16.601s + x-ratelimit-reset-tokens: + - 132ms + x-request-id: + - req_d13225164a822ec3ebab5591ed0b6d6a + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_tool_calls_no_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_tool_calls_no_content.yaml new file mode 100644 index 0000000000..4731f202c3 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_tool_calls_no_content.yaml @@ -0,0 +1,346 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "system", + "content": "You're a helpful assistant." + }, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?" + } + ], + "model": "gpt-4o-mini", + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "function": { + "name": "get_current_weather", + "description": "Get the current weather in a given location", + "parameters": { + "type": "object", + "properties": { + "location": { + "type": "string", + "description": "The city and state, e.g. Boston, MA" + } + }, + "required": [ + "location" + ], + "additionalProperties": false + } + } + } + ] + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '543' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.54.3 + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.54.3 + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.6 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |- + { + "id": "chatcmpl-ASYMW6w3m9qqpHUVhYTbQbw61zMqA", + "object": "chat.completion", + "created": 1731368636, + "model": "gpt-4o-mini-2024-07-18", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": null, + "tool_calls": [ + { + "id": "call_eqbDFUdPqay2WjsSzZEiAn0U", + "type": "function", + "function": { + "name": "get_current_weather", + "arguments": "{\"location\": \"Seattle, WA\"}" + } + }, + { + "id": "call_tn3sgasg6GaftTdancBYJNJN", + "type": "function", + "function": { + "name": "get_current_weather", + "arguments": "{\"location\": \"San Francisco, CA\"}" + } + } + ], + "refusal": null + }, + "logprobs": null, + "finish_reason": "tool_calls" + } + ], + "usage": { + "prompt_tokens": 75, + "completion_tokens": 51, + "total_tokens": 126, + "prompt_tokens_details": { + "cached_tokens": 0, + "audio_tokens": 0 + }, + "completion_tokens_details": { + "reasoning_tokens": 0, + "audio_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 + } + }, + "system_fingerprint": "fp_0ba0d124f1" + } + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1225ba6a3440b0-SIN + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Mon, 11 Nov 2024 23:43:57 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + content-length: + - '1308' + openai-organization: test_openai_org_id + openai-processing-ms: + - '761' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '10000' + x-ratelimit-limit-tokens: + - '200000' + x-ratelimit-remaining-requests: + - '9994' + x-ratelimit-remaining-tokens: + - '199961' + x-ratelimit-reset-requests: + - 45.694s + x-ratelimit-reset-tokens: + - 11ms + x-request-id: + - req_f98710550c77b43865572fc1a7a0bc53 + status: + code: 200 + message: OK +- request: + body: |- + { + "messages": [ + { + "role": "system", + "content": "You're a helpful assistant." + }, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?" + }, + { + "role": "assistant", + "tool_calls": [ + { + "id": "call_eqbDFUdPqay2WjsSzZEiAn0U", + "function": { + "arguments": "{\"location\": \"Seattle, WA\"}", + "name": "get_current_weather" + }, + "type": "function" + }, + { + "id": "call_tn3sgasg6GaftTdancBYJNJN", + "function": { + "arguments": "{\"location\": \"San Francisco, CA\"}", + "name": "get_current_weather" + }, + "type": "function" + } + ] + }, + { + "role": "tool", + "content": "50 degrees and raining", + "tool_call_id": "call_eqbDFUdPqay2WjsSzZEiAn0U" + }, + { + "role": "tool", + "content": "70 degrees and sunny", + "tool_call_id": "call_tn3sgasg6GaftTdancBYJNJN" + } + ], + "model": "gpt-4o-mini" + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '746' + content-type: + - application/json + cookie: + - test_cookie + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.54.3 + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.54.3 + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.6 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |- + { + "id": "chatcmpl-ASYMYObbcUyZ77rbvypWmcZPIVSf1", + "object": "chat.completion", + "created": 1731368638, + "model": "gpt-4o-mini-2024-07-18", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": "Today, the weather in Seattle is 50 degrees and raining, while San Francisco is enjoying 70 degrees and sunny weather.", + "refusal": null + }, + "logprobs": null, + "finish_reason": "stop" + } + ], + "usage": { + "prompt_tokens": 99, + "completion_tokens": 25, + "total_tokens": 124, + "prompt_tokens_details": { + "cached_tokens": 0, + "audio_tokens": 0 + }, + "completion_tokens_details": { + "reasoning_tokens": 0, + "audio_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 + } + }, + "system_fingerprint": "fp_0ba0d124f1" + } + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1225c12f6340b0-SIN + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Mon, 11 Nov 2024 23:43:58 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + content-length: + - '870' + openai-organization: test_openai_org_id + openai-processing-ms: + - '722' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '10000' + x-ratelimit-limit-tokens: + - '200000' + x-ratelimit-remaining-requests: + - '9993' + x-ratelimit-remaining-tokens: + - '199948' + x-ratelimit-reset-requests: + - 53.254s + x-ratelimit-reset-tokens: + - 15ms + x-request-id: + - req_2bb3d10a2a75f5d64a24aef595a0d8dd + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_tool_calls_with_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_tool_calls_with_content.yaml new file mode 100644 index 0000000000..6ceb618d24 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_tool_calls_with_content.yaml @@ -0,0 +1,346 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "system", + "content": "You're a helpful assistant." + }, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?" + } + ], + "model": "gpt-4o-mini", + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "function": { + "name": "get_current_weather", + "description": "Get the current weather in a given location", + "parameters": { + "type": "object", + "properties": { + "location": { + "type": "string", + "description": "The city and state, e.g. Boston, MA" + } + }, + "required": [ + "location" + ], + "additionalProperties": false + } + } + } + ] + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '543' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.54.3 + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.54.3 + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.6 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |- + { + "id": "chatcmpl-ASYMU9Ntix7ePttk0MSuerJstef6U", + "object": "chat.completion", + "created": 1731368634, + "model": "gpt-4o-mini-2024-07-18", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": null, + "tool_calls": [ + { + "id": "call_JpNb8OiAkbIbHzDggfpdDHpi", + "type": "function", + "function": { + "name": "get_current_weather", + "arguments": "{\"location\": \"Seattle, WA\"}" + } + }, + { + "id": "call_vaFQc3zK6hHTRZKXRI5Eo2cJ", + "type": "function", + "function": { + "name": "get_current_weather", + "arguments": "{\"location\": \"San Francisco, CA\"}" + } + } + ], + "refusal": null + }, + "logprobs": null, + "finish_reason": "tool_calls" + } + ], + "usage": { + "prompt_tokens": 75, + "completion_tokens": 51, + "total_tokens": 126, + "prompt_tokens_details": { + "cached_tokens": 0, + "audio_tokens": 0 + }, + "completion_tokens_details": { + "reasoning_tokens": 0, + "audio_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 + } + }, + "system_fingerprint": "fp_0ba0d124f1" + } + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1225ae3ea281e4-SIN + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Mon, 11 Nov 2024 23:43:55 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + content-length: + - '1308' + openai-organization: test_openai_org_id + openai-processing-ms: + - '748' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '10000' + x-ratelimit-limit-tokens: + - '200000' + x-ratelimit-remaining-requests: + - '9996' + x-ratelimit-remaining-tokens: + - '199961' + x-ratelimit-reset-requests: + - 30.375s + x-ratelimit-reset-tokens: + - 11ms + x-request-id: + - req_a0c3b432eb349a35b6d8dde6e01451e4 + status: + code: 200 + message: OK +- request: + body: |- + { + "messages": [ + { + "role": "system", + "content": "You're a helpful assistant." + }, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?" + }, + { + "role": "assistant", + "tool_calls": [ + { + "id": "call_JpNb8OiAkbIbHzDggfpdDHpi", + "function": { + "arguments": "{\"location\": \"Seattle, WA\"}", + "name": "get_current_weather" + }, + "type": "function" + }, + { + "id": "call_vaFQc3zK6hHTRZKXRI5Eo2cJ", + "function": { + "arguments": "{\"location\": \"San Francisco, CA\"}", + "name": "get_current_weather" + }, + "type": "function" + } + ] + }, + { + "role": "tool", + "content": "50 degrees and raining", + "tool_call_id": "call_JpNb8OiAkbIbHzDggfpdDHpi" + }, + { + "role": "tool", + "content": "70 degrees and sunny", + "tool_call_id": "call_vaFQc3zK6hHTRZKXRI5Eo2cJ" + } + ], + "model": "gpt-4o-mini" + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '746' + content-type: + - application/json + cookie: + - test_cookie + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.54.3 + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.54.3 + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.6 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |- + { + "id": "chatcmpl-ASYMVzdmBGDbUoHFmt6R16tdtZUzR", + "object": "chat.completion", + "created": 1731368635, + "model": "gpt-4o-mini-2024-07-18", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": "Today, the weather in Seattle is 50 degrees and raining, while in San Francisco, it's 70 degrees and sunny.", + "refusal": null + }, + "logprobs": null, + "finish_reason": "stop" + } + ], + "usage": { + "prompt_tokens": 99, + "completion_tokens": 25, + "total_tokens": 124, + "prompt_tokens_details": { + "cached_tokens": 0, + "audio_tokens": 0 + }, + "completion_tokens_details": { + "reasoning_tokens": 0, + "audio_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 + } + }, + "system_fingerprint": "fp_9b78b61c52" + } + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e1225b4cbf581e4-SIN + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Mon, 11 Nov 2024 23:43:56 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + content-length: + - '859' + openai-organization: test_openai_org_id + openai-processing-ms: + - '531' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '10000' + x-ratelimit-limit-tokens: + - '200000' + x-ratelimit-remaining-requests: + - '9995' + x-ratelimit-remaining-tokens: + - '199947' + x-ratelimit-reset-requests: + - 37.973s + x-ratelimit-reset-tokens: + - 15ms + x-request-id: + - req_22b79d2dddb920f55e33727d06724978 + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_with_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_with_content.yaml new file mode 100644 index 0000000000..2abb443fe3 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_with_content.yaml @@ -0,0 +1,134 @@ +interactions: +- request: + body: |- + { + "messages": [ + { + "role": "user", + "content": "Say this is a test" + } + ], + "model": "gpt-4o-mini", + "stream": false + } + headers: + accept: + - application/json + accept-encoding: + - gzip, deflate + authorization: + - Bearer test_openai_api_key + connection: + - keep-alive + content-length: + - '106' + content-type: + - application/json + host: + - api.openai.com + user-agent: + - OpenAI/Python 1.54.3 + x-stainless-arch: + - arm64 + x-stainless-async: + - 'false' + x-stainless-lang: + - python + x-stainless-os: + - MacOS + x-stainless-package-version: + - 1.54.3 + x-stainless-retry-count: + - '0' + x-stainless-runtime: + - CPython + x-stainless-runtime-version: + - 3.12.6 + method: POST + uri: https://api.openai.com/v1/chat/completions + response: + body: + string: |- + { + "id": "chatcmpl-ASYMQRl3A3DXL9FWCK9tnGRcKIO7q", + "object": "chat.completion", + "created": 1731368630, + "model": "gpt-4o-mini-2024-07-18", + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": "This is a test.", + "refusal": null + }, + "logprobs": null, + "finish_reason": "stop" + } + ], + "usage": { + "prompt_tokens": 12, + "completion_tokens": 5, + "total_tokens": 17, + "prompt_tokens_details": { + "cached_tokens": 0, + "audio_tokens": 0 + }, + "completion_tokens_details": { + "reasoning_tokens": 0, + "audio_tokens": 0, + "accepted_prediction_tokens": 0, + "rejected_prediction_tokens": 0 + } + }, + "system_fingerprint": "fp_0ba0d124f1" + } + headers: + CF-Cache-Status: + - DYNAMIC + CF-RAY: + - 8e122593ff368bc8-SIN + Connection: + - keep-alive + Content-Type: + - application/json + Date: + - Mon, 11 Nov 2024 23:43:50 GMT + Server: + - cloudflare + Set-Cookie: test_set_cookie + Transfer-Encoding: + - chunked + X-Content-Type-Options: + - nosniff + access-control-expose-headers: + - X-Request-ID + alt-svc: + - h3=":443"; ma=86400 + content-length: + - '765' + openai-organization: test_openai_org_id + openai-processing-ms: + - '287' + openai-version: + - '2020-10-01' + strict-transport-security: + - max-age=31536000; includeSubDomains; preload + x-ratelimit-limit-requests: + - '10000' + x-ratelimit-limit-tokens: + - '200000' + x-ratelimit-remaining-requests: + - '9999' + x-ratelimit-remaining-tokens: + - '199977' + x-ratelimit-reset-requests: + - 8.64s + x-ratelimit-reset-tokens: + - 6ms + x-request-id: + - req_58cff97afd0e7c0bba910ccf0b044a6f + status: + code: 200 + message: OK +version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/conftest.py b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/conftest.py new file mode 100644 index 0000000000..7ff7e46777 --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/conftest.py @@ -0,0 +1,186 @@ +"""Unit tests configuration module.""" + +import json +import os + +import pytest +import yaml +from openai import AsyncOpenAI, OpenAI + +from opentelemetry.instrumentation.openai_v2 import OpenAIInstrumentor +from opentelemetry.instrumentation.openai_v2.utils import ( + OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT, +) +from opentelemetry.sdk._events import EventLoggerProvider +from opentelemetry.sdk._logs import LoggerProvider +from opentelemetry.sdk._logs.export import ( + InMemoryLogExporter, + SimpleLogRecordProcessor, +) +from opentelemetry.sdk.trace import TracerProvider +from opentelemetry.sdk.trace.export import SimpleSpanProcessor +from opentelemetry.sdk.trace.export.in_memory_span_exporter import ( + InMemorySpanExporter, +) + + +@pytest.fixture(scope="function", name="span_exporter") +def fixture_span_exporter(): + exporter = InMemorySpanExporter() + yield exporter + + +@pytest.fixture(scope="function", name="log_exporter") +def fixture_log_exporter(): + exporter = InMemoryLogExporter() + yield exporter + + +@pytest.fixture(scope="function", name="tracer_provider") +def fixture_tracer_provider(span_exporter): + provider = TracerProvider() + provider.add_span_processor(SimpleSpanProcessor(span_exporter)) + return provider + + +@pytest.fixture(scope="function", name="event_logger_provider") +def fixture_event_logger_provider(log_exporter): + provider = LoggerProvider() + provider.add_log_record_processor(SimpleLogRecordProcessor(log_exporter)) + event_logger_provider = EventLoggerProvider(provider) + + return event_logger_provider + + +@pytest.fixture(autouse=True) +def environment(): + if not os.getenv("OPENAI_API_KEY"): + os.environ["OPENAI_API_KEY"] = "test_openai_api_key" + + +@pytest.fixture +def openai_client(): + return OpenAI() + + +@pytest.fixture +def async_openai_client(): + return AsyncOpenAI() + + +@pytest.fixture(scope="module") +def vcr_config(): + return { + "filter_headers": [ + ("cookie", "test_cookie"), + ("authorization", "Bearer test_openai_api_key"), + ("openai-organization", "test_openai_org_id"), + ("openai-project", "test_openai_project_id"), + ], + "decode_compressed_response": True, + "before_record_response": scrub_response_headers, + } + + +@pytest.fixture(scope="function") +def instrument_no_content(tracer_provider, event_logger_provider): + instrumentor = OpenAIInstrumentor() + instrumentor.instrument( + tracer_provider=tracer_provider, + event_logger_provider=event_logger_provider, + ) + + yield instrumentor + instrumentor.uninstrument() + + +@pytest.fixture(scope="function") +def instrument_with_content(tracer_provider, event_logger_provider): + os.environ.update( + {OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT: "True"} + ) + instrumentor = OpenAIInstrumentor() + instrumentor.instrument( + tracer_provider=tracer_provider, + event_logger_provider=event_logger_provider, + ) + + yield instrumentor + os.environ.pop(OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT, None) + instrumentor.uninstrument() + + +class LiteralBlockScalar(str): + """Formats the string as a literal block scalar, preserving whitespace and + without interpreting escape characters""" + + +def literal_block_scalar_presenter(dumper, data): + """Represents a scalar string as a literal block, via '|' syntax""" + return dumper.represent_scalar("tag:yaml.org,2002:str", data, style="|") + + +yaml.add_representer(LiteralBlockScalar, literal_block_scalar_presenter) + + +def process_string_value(string_value): + """Pretty-prints JSON or returns long strings as a LiteralBlockScalar""" + try: + json_data = json.loads(string_value) + return LiteralBlockScalar(json.dumps(json_data, indent=2)) + except (ValueError, TypeError): + if len(string_value) > 80: + return LiteralBlockScalar(string_value) + return string_value + + +def convert_body_to_literal(data): + """Searches the data for body strings, attempting to pretty-print JSON""" + if isinstance(data, dict): + for key, value in data.items(): + # Handle response body case (e.g., response.body.string) + if key == "body" and isinstance(value, dict) and "string" in value: + value["string"] = process_string_value(value["string"]) + + # Handle request body case (e.g., request.body) + elif key == "body" and isinstance(value, str): + data[key] = process_string_value(value) + + else: + convert_body_to_literal(value) + + elif isinstance(data, list): + for idx, choice in enumerate(data): + data[idx] = convert_body_to_literal(choice) + + return data + + +class PrettyPrintJSONBody: + """This makes request and response body recordings more readable.""" + + @staticmethod + def serialize(cassette_dict): + cassette_dict = convert_body_to_literal(cassette_dict) + return yaml.dump( + cassette_dict, default_flow_style=False, allow_unicode=True + ) + + @staticmethod + def deserialize(cassette_string): + return yaml.load(cassette_string, Loader=yaml.Loader) + + +@pytest.fixture(scope="module", autouse=True) +def fixture_vcr(vcr): + vcr.register_serializer("yaml", PrettyPrintJSONBody) + return vcr + + +def scrub_response_headers(response): + """ + This scrubs sensitive response headers. Note they are case-sensitive! + """ + response["headers"]["openai-organization"] = "test_openai_org_id" + response["headers"]["Set-Cookie"] = "test_set_cookie" + return response diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/test_async_chat_completions.py b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/test_async_chat_completions.py new file mode 100644 index 0000000000..1c4b3cb7dd --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/test_async_chat_completions.py @@ -0,0 +1,847 @@ +# 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. +# pylint: disable=too-many-locals + +from typing import Optional + +import pytest +from openai import APIConnectionError, AsyncOpenAI, NotFoundError +from openai.resources.chat.completions import ChatCompletion + +from opentelemetry.sdk.trace import ReadableSpan +from opentelemetry.semconv._incubating.attributes import ( + error_attributes as ErrorAttributes, +) +from opentelemetry.semconv._incubating.attributes import ( + event_attributes as EventAttributes, +) +from opentelemetry.semconv._incubating.attributes import ( + gen_ai_attributes as GenAIAttributes, +) +from opentelemetry.semconv._incubating.attributes import ( + server_attributes as ServerAttributes, +) + + +@pytest.mark.vcr() +@pytest.mark.asyncio() +async def test_async_chat_completion_with_content( + span_exporter, log_exporter, async_openai_client, instrument_with_content +): + llm_model_value = "gpt-4o-mini" + messages_value = [{"role": "user", "content": "Say this is a test"}] + + response = await async_openai_client.chat.completions.create( + messages=messages_value, model=llm_model_value, stream=False + ) + + spans = span_exporter.get_finished_spans() + assert_completion_attributes(spans[0], llm_model_value, response) + + logs = log_exporter.get_finished_logs() + assert len(logs) == 2 + + user_message = {"content": messages_value[0]["content"]} + assert_message_in_logs( + logs[0], "gen_ai.user.message", user_message, spans[0] + ) + + choice_event = { + "index": 0, + "finish_reason": "stop", + "message": { + "role": "assistant", + "content": response.choices[0].message.content, + }, + } + assert_message_in_logs(logs[1], "gen_ai.choice", choice_event, spans[0]) + + +@pytest.mark.asyncio() +async def test_async_chat_completion_bad_endpoint( + span_exporter, instrument_no_content +): + llm_model_value = "gpt-4o-mini" + messages_value = [{"role": "user", "content": "Say this is a test"}] + + client = AsyncOpenAI(base_url="http://localhost:4242") + + with pytest.raises(APIConnectionError): + await client.chat.completions.create( + messages=messages_value, + model=llm_model_value, + timeout=0.1, + ) + + spans = span_exporter.get_finished_spans() + assert_all_attributes( + spans[0], llm_model_value, server_address="localhost" + ) + assert 4242 == spans[0].attributes[ServerAttributes.SERVER_PORT] + assert ( + "APIConnectionError" == spans[0].attributes[ErrorAttributes.ERROR_TYPE] + ) + + +@pytest.mark.vcr() +@pytest.mark.asyncio() +async def test_async_chat_completion_404( + span_exporter, async_openai_client, instrument_no_content +): + llm_model_value = "this-model-does-not-exist" + messages_value = [{"role": "user", "content": "Say this is a test"}] + + with pytest.raises(NotFoundError): + await async_openai_client.chat.completions.create( + messages=messages_value, + model=llm_model_value, + ) + + spans = span_exporter.get_finished_spans() + + assert_all_attributes(spans[0], llm_model_value) + assert "NotFoundError" == spans[0].attributes[ErrorAttributes.ERROR_TYPE] + + +@pytest.mark.vcr() +@pytest.mark.asyncio() +async def test_async_chat_completion_extra_params( + span_exporter, async_openai_client, instrument_no_content +): + llm_model_value = "gpt-4o-mini" + messages_value = [{"role": "user", "content": "Say this is a test"}] + + response = await async_openai_client.chat.completions.create( + messages=messages_value, + model=llm_model_value, + seed=42, + temperature=0.5, + max_tokens=50, + stream=False, + extra_body={"service_tier": "default"}, + ) + + spans = span_exporter.get_finished_spans() + assert_completion_attributes(spans[0], llm_model_value, response) + assert ( + spans[0].attributes[GenAIAttributes.GEN_AI_OPENAI_REQUEST_SEED] == 42 + ) + assert ( + spans[0].attributes[GenAIAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.5 + ) + assert spans[0].attributes[GenAIAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 50 + assert ( + spans[0].attributes[GenAIAttributes.GEN_AI_OPENAI_REQUEST_SERVICE_TIER] + == "default" + ) + + +@pytest.mark.vcr() +@pytest.mark.asyncio() +async def test_async_chat_completion_multiple_choices( + span_exporter, log_exporter, async_openai_client, instrument_with_content +): + llm_model_value = "gpt-4o-mini" + messages_value = [{"role": "user", "content": "Say this is a test"}] + + response = await async_openai_client.chat.completions.create( + messages=messages_value, model=llm_model_value, n=2, stream=False + ) + + spans = span_exporter.get_finished_spans() + assert_completion_attributes(spans[0], llm_model_value, response) + + logs = log_exporter.get_finished_logs() + assert len(logs) == 3 # 1 user message + 2 choice messages + + user_message = {"content": messages_value[0]["content"]} + assert_message_in_logs( + logs[0], "gen_ai.user.message", user_message, spans[0] + ) + + choice_event_0 = { + "index": 0, + "finish_reason": "stop", + "message": { + "role": "assistant", + "content": response.choices[0].message.content, + }, + } + assert_message_in_logs(logs[1], "gen_ai.choice", choice_event_0, spans[0]) + + choice_event_1 = { + "index": 1, + "finish_reason": "stop", + "message": { + "role": "assistant", + "content": response.choices[1].message.content, + }, + } + assert_message_in_logs(logs[2], "gen_ai.choice", choice_event_1, spans[0]) + + +@pytest.mark.vcr() +@pytest.mark.asyncio() +async def test_async_chat_completion_tool_calls_with_content( + span_exporter, log_exporter, async_openai_client, instrument_with_content +): + await chat_completion_tool_call( + span_exporter, log_exporter, async_openai_client, True + ) + + +@pytest.mark.vcr() +@pytest.mark.asyncio() +async def test_async_chat_completion_tool_calls_no_content( + span_exporter, log_exporter, async_openai_client, instrument_no_content +): + await chat_completion_tool_call( + span_exporter, log_exporter, async_openai_client, False + ) + + +async def chat_completion_tool_call( + span_exporter, log_exporter, async_openai_client, expect_content +): + llm_model_value = "gpt-4o-mini" + messages_value = [ + {"role": "system", "content": "You're a helpful assistant."}, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?", + }, + ] + + response_0 = await async_openai_client.chat.completions.create( + messages=messages_value, + model=llm_model_value, + tool_choice="auto", + tools=[get_current_weather_tool_definition()], + ) + + # sanity check + assert "tool_calls" in response_0.choices[0].finish_reason + + # final request + messages_value.append( + { + "role": "assistant", + "tool_calls": response_0.choices[0].message.to_dict()[ + "tool_calls" + ], + } + ) + + tool_call_result_0 = { + "role": "tool", + "content": "50 degrees and raining", + "tool_call_id": response_0.choices[0].message.tool_calls[0].id, + } + tool_call_result_1 = { + "role": "tool", + "content": "70 degrees and sunny", + "tool_call_id": response_0.choices[0].message.tool_calls[1].id, + } + + messages_value.append(tool_call_result_0) + messages_value.append(tool_call_result_1) + + response_1 = await async_openai_client.chat.completions.create( + messages=messages_value, model=llm_model_value + ) + + # sanity check + assert "stop" in response_1.choices[0].finish_reason + + # validate both calls + spans = span_exporter.get_finished_spans() + assert len(spans) == 2 + assert_completion_attributes(spans[0], llm_model_value, response_0) + assert_completion_attributes(spans[1], llm_model_value, response_1) + + logs = log_exporter.get_finished_logs() + assert len(logs) == 9 # 3 logs for first completion, 6 for second + + # call one + system_message = ( + {"content": messages_value[0]["content"]} if expect_content else None + ) + assert_message_in_logs( + logs[0], "gen_ai.system.message", system_message, spans[0] + ) + + user_message = ( + {"content": messages_value[1]["content"]} if expect_content else None + ) + assert_message_in_logs( + logs[1], "gen_ai.user.message", user_message, spans[0] + ) + + function_call_0 = {"name": "get_current_weather"} + function_call_1 = {"name": "get_current_weather"} + if expect_content: + function_call_0["arguments"] = ( + response_0.choices[0] + .message.tool_calls[0] + .function.arguments.replace("\n", "") + ) + function_call_1["arguments"] = ( + response_0.choices[0] + .message.tool_calls[1] + .function.arguments.replace("\n", "") + ) + + choice_event = { + "index": 0, + "finish_reason": "tool_calls", + "message": { + "role": "assistant", + "tool_calls": [ + { + "id": response_0.choices[0].message.tool_calls[0].id, + "type": "function", + "function": function_call_0, + }, + { + "id": response_0.choices[0].message.tool_calls[1].id, + "type": "function", + "function": function_call_1, + }, + ], + }, + } + assert_message_in_logs(logs[2], "gen_ai.choice", choice_event, spans[0]) + + # call two + system_message = ( + {"content": messages_value[0]["content"]} if expect_content else None + ) + assert_message_in_logs( + logs[3], "gen_ai.system.message", system_message, spans[1] + ) + + user_message = ( + {"content": messages_value[1]["content"]} if expect_content else None + ) + assert_message_in_logs( + logs[4], "gen_ai.user.message", user_message, spans[1] + ) + + assistant_tool_call = {"tool_calls": messages_value[2]["tool_calls"]} + if not expect_content: + assistant_tool_call["tool_calls"][0]["function"]["arguments"] = None + assistant_tool_call["tool_calls"][1]["function"]["arguments"] = None + + assert_message_in_logs( + logs[5], "gen_ai.assistant.message", assistant_tool_call, spans[1] + ) + + tool_message_0 = { + "id": tool_call_result_0["tool_call_id"], + "content": tool_call_result_0["content"] if expect_content else None, + } + + assert_message_in_logs( + logs[6], "gen_ai.tool.message", tool_message_0, spans[1] + ) + + tool_message_1 = { + "id": tool_call_result_1["tool_call_id"], + "content": tool_call_result_1["content"] if expect_content else None, + } + + assert_message_in_logs( + logs[7], "gen_ai.tool.message", tool_message_1, spans[1] + ) + + message = { + "role": "assistant", + "content": response_1.choices[0].message.content + if expect_content + else None, + } + choice = { + "index": 0, + "finish_reason": "stop", + "message": message, + } + assert_message_in_logs(logs[8], "gen_ai.choice", choice, spans[1]) + + +@pytest.mark.vcr() +@pytest.mark.asyncio() +async def test_async_chat_completion_streaming( + span_exporter, log_exporter, async_openai_client, instrument_with_content +): + llm_model_value = "gpt-4" + messages_value = [{"role": "user", "content": "Say this is a test"}] + + kwargs = { + "model": llm_model_value, + "messages": messages_value, + "stream": True, + "stream_options": {"include_usage": True}, + } + + response_stream_usage = None + response_stream_model = None + response_stream_id = None + response_stream_result = "" + response = await async_openai_client.chat.completions.create(**kwargs) + async for chunk in response: + if chunk.choices: + response_stream_result += chunk.choices[0].delta.content or "" + + # get the last chunk + if getattr(chunk, "usage", None): + response_stream_usage = chunk.usage + response_stream_model = chunk.model + response_stream_id = chunk.id + + spans = span_exporter.get_finished_spans() + assert_all_attributes( + spans[0], + llm_model_value, + response_stream_id, + response_stream_model, + response_stream_usage.prompt_tokens, + response_stream_usage.completion_tokens, + ) + + logs = log_exporter.get_finished_logs() + assert len(logs) == 2 + + user_message = {"content": "Say this is a test"} + assert_message_in_logs( + logs[0], "gen_ai.user.message", user_message, spans[0] + ) + + choice_event = { + "index": 0, + "finish_reason": "stop", + "message": {"role": "assistant", "content": response_stream_result}, + } + assert_message_in_logs(logs[1], "gen_ai.choice", choice_event, spans[0]) + + +@pytest.mark.vcr() +@pytest.mark.asyncio() +async def test_async_chat_completion_streaming_not_complete( + span_exporter, log_exporter, async_openai_client, instrument_with_content +): + llm_model_value = "gpt-4" + messages_value = [{"role": "user", "content": "Say this is a test"}] + + kwargs = { + "model": llm_model_value, + "messages": messages_value, + "stream": True, + } + + response_stream_model = None + response_stream_id = None + response_stream_result = "" + response = await async_openai_client.chat.completions.create(**kwargs) + idx = 0 + async for chunk in response: + if chunk.choices: + response_stream_result += chunk.choices[0].delta.content or "" + if idx == 1: + # fake a stop + break + + if chunk.model: + response_stream_model = chunk.model + if chunk.id: + response_stream_id = chunk.id + idx += 1 + + response.close() + spans = span_exporter.get_finished_spans() + assert_all_attributes( + spans[0], llm_model_value, response_stream_id, response_stream_model + ) + + logs = log_exporter.get_finished_logs() + assert len(logs) == 2 + + user_message = {"content": "Say this is a test"} + assert_message_in_logs( + logs[0], "gen_ai.user.message", user_message, spans[0] + ) + + choice_event = { + "index": 0, + "finish_reason": "error", + "message": {"role": "assistant", "content": response_stream_result}, + } + assert_message_in_logs(logs[1], "gen_ai.choice", choice_event, spans[0]) + + +@pytest.mark.vcr() +@pytest.mark.asyncio() +async def test_async_chat_completion_multiple_choices_streaming( + span_exporter, log_exporter, async_openai_client, instrument_with_content +): + llm_model_value = "gpt-4o-mini" + messages_value = [ + {"role": "system", "content": "You're a helpful assistant."}, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?", + }, + ] + + response_0 = await async_openai_client.chat.completions.create( + messages=messages_value, + model=llm_model_value, + n=2, + stream=True, + stream_options={"include_usage": True}, + ) + + # two strings for each choice + response_stream_result = ["", ""] + finish_reasons = ["", ""] + async for chunk in response_0: + if chunk.choices: + for choice in chunk.choices: + response_stream_result[choice.index] += ( + choice.delta.content or "" + ) + if choice.finish_reason: + finish_reasons[choice.index] = choice.finish_reason + + # get the last chunk + if getattr(chunk, "usage", None): + response_stream_usage = chunk.usage + response_stream_model = chunk.model + response_stream_id = chunk.id + + # sanity check + assert "stop" == finish_reasons[0] + + spans = span_exporter.get_finished_spans() + assert_all_attributes( + spans[0], + llm_model_value, + response_stream_id, + response_stream_model, + response_stream_usage.prompt_tokens, + response_stream_usage.completion_tokens, + ) + + logs = log_exporter.get_finished_logs() + assert len(logs) == 4 + + system_message = {"content": messages_value[0]["content"]} + assert_message_in_logs( + logs[0], "gen_ai.system.message", system_message, spans[0] + ) + + user_message = { + "content": "What's the weather in Seattle and San Francisco today?" + } + assert_message_in_logs( + logs[1], "gen_ai.user.message", user_message, spans[0] + ) + + choice_event_0 = { + "index": 0, + "finish_reason": "stop", + "message": { + "role": "assistant", + "content": "".join(response_stream_result[0]), + }, + } + assert_message_in_logs(logs[2], "gen_ai.choice", choice_event_0, spans[0]) + + choice_event_1 = { + "index": 1, + "finish_reason": "stop", + "message": { + "role": "assistant", + "content": "".join(response_stream_result[1]), + }, + } + assert_message_in_logs(logs[3], "gen_ai.choice", choice_event_1, spans[0]) + + +@pytest.mark.vcr() +@pytest.mark.asyncio() +async def test_async_chat_completion_multiple_tools_streaming_with_content( + span_exporter, log_exporter, async_openai_client, instrument_with_content +): + await async_chat_completion_multiple_tools_streaming( + span_exporter, log_exporter, async_openai_client, True + ) + + +@pytest.mark.vcr() +@pytest.mark.asyncio() +async def test_async_chat_completion_multiple_tools_streaming_no_content( + span_exporter, log_exporter, async_openai_client, instrument_no_content +): + await async_chat_completion_multiple_tools_streaming( + span_exporter, log_exporter, async_openai_client, False + ) + + +async def async_chat_completion_multiple_tools_streaming( + span_exporter, log_exporter, async_openai_client, expect_content +): + llm_model_value = "gpt-4o-mini" + messages_value = [ + {"role": "system", "content": "You're a helpful assistant."}, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?", + }, + ] + + response = await async_openai_client.chat.completions.create( + messages=messages_value, + model=llm_model_value, + tool_choice="auto", + tools=[get_current_weather_tool_definition()], + stream=True, + stream_options={"include_usage": True}, + ) + + finish_reason = None + # two tools + tool_names = ["", ""] + tool_call_ids = ["", ""] + tool_args = ["", ""] + async for chunk in response: + if chunk.choices: + if chunk.choices[0].finish_reason: + finish_reason = chunk.choices[0].finish_reason + for tool_call in chunk.choices[0].delta.tool_calls or []: + t_idx = tool_call.index + if tool_call.id: + tool_call_ids[t_idx] = tool_call.id + if tool_call.function: + if tool_call.function.arguments: + tool_args[t_idx] += tool_call.function.arguments + if tool_call.function.name: + tool_names[t_idx] = tool_call.function.name + + # get the last chunk + if getattr(chunk, "usage", None): + response_stream_usage = chunk.usage + response_stream_model = chunk.model + response_stream_id = chunk.id + + # sanity check + assert "tool_calls" == finish_reason + + spans = span_exporter.get_finished_spans() + assert_all_attributes( + spans[0], + llm_model_value, + response_stream_id, + response_stream_model, + response_stream_usage.prompt_tokens, + response_stream_usage.completion_tokens, + ) + + logs = log_exporter.get_finished_logs() + assert len(logs) == 3 + + system_message = ( + {"content": messages_value[0]["content"]} if expect_content else None + ) + assert_message_in_logs( + logs[0], "gen_ai.system.message", system_message, spans[0] + ) + + user_message = ( + {"content": "What's the weather in Seattle and San Francisco today?"} + if expect_content + else None + ) + assert_message_in_logs( + logs[1], "gen_ai.user.message", user_message, spans[0] + ) + + choice_event = { + "index": 0, + "finish_reason": "tool_calls", + "message": { + "role": "assistant", + "tool_calls": [ + { + "id": tool_call_ids[0], + "type": "function", + "function": { + "name": tool_names[0], + "arguments": ( + tool_args[0].replace("\n", "") + if expect_content + else None + ), + }, + }, + { + "id": tool_call_ids[1], + "type": "function", + "function": { + "name": tool_names[1], + "arguments": ( + tool_args[1].replace("\n", "") + if expect_content + else None + ), + }, + }, + ], + }, + } + assert_message_in_logs(logs[2], "gen_ai.choice", choice_event, spans[0]) + + +def assert_message_in_logs(log, event_name, expected_content, parent_span): + assert log.log_record.attributes[EventAttributes.EVENT_NAME] == event_name + assert ( + log.log_record.attributes[GenAIAttributes.GEN_AI_SYSTEM] + == GenAIAttributes.GenAiSystemValues.OPENAI.value + ) + + if not expected_content: + assert not log.log_record.body + else: + assert log.log_record.body + assert dict(log.log_record.body) == remove_none_values( + expected_content + ) + assert_log_parent(log, parent_span) + + +def remove_none_values(body): + result = {} + for key, value in body.items(): + if value is None: + continue + if isinstance(value, dict): + result[key] = remove_none_values(value) + elif isinstance(value, list): + result[key] = [remove_none_values(i) for i in value] + else: + result[key] = value + return result + + +def assert_completion_attributes( + span: ReadableSpan, + request_model: str, + response: ChatCompletion, + operation_name: str = "chat", + server_address: str = "api.openai.com", +): + return assert_all_attributes( + span, + request_model, + response.id, + response.model, + response.usage.prompt_tokens, + response.usage.completion_tokens, + operation_name, + server_address, + ) + + +def assert_all_attributes( + span: ReadableSpan, + request_model: str, + response_id: str = None, + response_model: str = None, + input_tokens: Optional[int] = None, + output_tokens: Optional[int] = None, + operation_name: str = "chat", + server_address: str = "api.openai.com", +): + assert span.name == f"{operation_name} {request_model}" + assert ( + operation_name + == span.attributes[GenAIAttributes.GEN_AI_OPERATION_NAME] + ) + assert ( + GenAIAttributes.GenAiSystemValues.OPENAI.value + == span.attributes[GenAIAttributes.GEN_AI_SYSTEM] + ) + assert ( + request_model == span.attributes[GenAIAttributes.GEN_AI_REQUEST_MODEL] + ) + if response_model: + assert ( + response_model + == span.attributes[GenAIAttributes.GEN_AI_RESPONSE_MODEL] + ) + else: + assert GenAIAttributes.GEN_AI_RESPONSE_MODEL not in span.attributes + + if response_id: + assert ( + response_id == span.attributes[GenAIAttributes.GEN_AI_RESPONSE_ID] + ) + else: + assert GenAIAttributes.GEN_AI_RESPONSE_ID not in span.attributes + + if input_tokens: + assert ( + input_tokens + == span.attributes[GenAIAttributes.GEN_AI_USAGE_INPUT_TOKENS] + ) + else: + assert GenAIAttributes.GEN_AI_USAGE_INPUT_TOKENS not in span.attributes + + if output_tokens: + assert ( + output_tokens + == span.attributes[GenAIAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] + ) + else: + assert ( + GenAIAttributes.GEN_AI_USAGE_OUTPUT_TOKENS not in span.attributes + ) + + assert server_address == span.attributes[ServerAttributes.SERVER_ADDRESS] + + +def assert_log_parent(log, span): + assert log.log_record.trace_id == span.get_span_context().trace_id + assert log.log_record.span_id == span.get_span_context().span_id + assert log.log_record.trace_flags == span.get_span_context().trace_flags + + +def get_current_weather_tool_definition(): + return { + "type": "function", + "function": { + "name": "get_current_weather", + "description": "Get the current weather in a given location", + "parameters": { + "type": "object", + "properties": { + "location": { + "type": "string", + "description": "The city and state, e.g. Boston, MA", + }, + }, + "required": ["location"], + "additionalProperties": False, + }, + }, + } diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/test_chat_completions.py b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/test_chat_completions.py new file mode 100644 index 0000000000..c6cb19aa8d --- /dev/null +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/test_chat_completions.py @@ -0,0 +1,825 @@ +# 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. +# pylint: disable=too-many-locals + +from typing import Optional + +import pytest +from openai import APIConnectionError, NotFoundError, OpenAI +from openai.resources.chat.completions import ChatCompletion + +from opentelemetry.sdk.trace import ReadableSpan +from opentelemetry.semconv._incubating.attributes import ( + error_attributes as ErrorAttributes, +) +from opentelemetry.semconv._incubating.attributes import ( + event_attributes as EventAttributes, +) +from opentelemetry.semconv._incubating.attributes import ( + gen_ai_attributes as GenAIAttributes, +) +from opentelemetry.semconv._incubating.attributes import ( + server_attributes as ServerAttributes, +) + + +@pytest.mark.vcr() +def test_chat_completion_with_content( + span_exporter, log_exporter, openai_client, instrument_with_content +): + llm_model_value = "gpt-4o-mini" + messages_value = [{"role": "user", "content": "Say this is a test"}] + + response = openai_client.chat.completions.create( + messages=messages_value, model=llm_model_value, stream=False + ) + + spans = span_exporter.get_finished_spans() + assert_completion_attributes(spans[0], llm_model_value, response) + + logs = log_exporter.get_finished_logs() + assert len(logs) == 2 + + user_message = {"content": messages_value[0]["content"]} + assert_message_in_logs( + logs[0], "gen_ai.user.message", user_message, spans[0] + ) + + choice_event = { + "index": 0, + "finish_reason": "stop", + "message": { + "role": "assistant", + "content": response.choices[0].message.content, + }, + } + assert_message_in_logs(logs[1], "gen_ai.choice", choice_event, spans[0]) + + +def test_chat_completion_bad_endpoint(span_exporter, instrument_no_content): + llm_model_value = "gpt-4o-mini" + messages_value = [{"role": "user", "content": "Say this is a test"}] + + client = OpenAI(base_url="http://localhost:4242") + + with pytest.raises(APIConnectionError): + client.chat.completions.create( + messages=messages_value, + model=llm_model_value, + timeout=0.1, + ) + + spans = span_exporter.get_finished_spans() + assert_all_attributes( + spans[0], llm_model_value, server_address="localhost" + ) + assert 4242 == spans[0].attributes[ServerAttributes.SERVER_PORT] + assert ( + "APIConnectionError" == spans[0].attributes[ErrorAttributes.ERROR_TYPE] + ) + + +@pytest.mark.vcr() +def test_chat_completion_404( + span_exporter, openai_client, instrument_no_content +): + llm_model_value = "this-model-does-not-exist" + messages_value = [{"role": "user", "content": "Say this is a test"}] + + with pytest.raises(NotFoundError): + openai_client.chat.completions.create( + messages=messages_value, + model=llm_model_value, + ) + + spans = span_exporter.get_finished_spans() + + assert_all_attributes(spans[0], llm_model_value) + assert "NotFoundError" == spans[0].attributes[ErrorAttributes.ERROR_TYPE] + + +@pytest.mark.vcr() +def test_chat_completion_extra_params( + span_exporter, openai_client, instrument_no_content +): + llm_model_value = "gpt-4o-mini" + messages_value = [{"role": "user", "content": "Say this is a test"}] + + response = openai_client.chat.completions.create( + messages=messages_value, + model=llm_model_value, + seed=42, + temperature=0.5, + max_tokens=50, + stream=False, + extra_body={"service_tier": "default"}, + ) + + spans = span_exporter.get_finished_spans() + assert_completion_attributes(spans[0], llm_model_value, response) + assert ( + spans[0].attributes[GenAIAttributes.GEN_AI_OPENAI_REQUEST_SEED] == 42 + ) + assert ( + spans[0].attributes[GenAIAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.5 + ) + assert spans[0].attributes[GenAIAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 50 + assert ( + spans[0].attributes[GenAIAttributes.GEN_AI_OPENAI_REQUEST_SERVICE_TIER] + == "default" + ) + + +@pytest.mark.vcr() +def test_chat_completion_multiple_choices( + span_exporter, log_exporter, openai_client, instrument_with_content +): + llm_model_value = "gpt-4o-mini" + messages_value = [{"role": "user", "content": "Say this is a test"}] + + response = openai_client.chat.completions.create( + messages=messages_value, model=llm_model_value, n=2, stream=False + ) + + spans = span_exporter.get_finished_spans() + assert_completion_attributes(spans[0], llm_model_value, response) + + logs = log_exporter.get_finished_logs() + assert len(logs) == 3 # 1 user message + 2 choice messages + + user_message = {"content": messages_value[0]["content"]} + assert_message_in_logs( + logs[0], "gen_ai.user.message", user_message, spans[0] + ) + + choice_event_0 = { + "index": 0, + "finish_reason": "stop", + "message": { + "role": "assistant", + "content": response.choices[0].message.content, + }, + } + assert_message_in_logs(logs[1], "gen_ai.choice", choice_event_0, spans[0]) + + choice_event_1 = { + "index": 1, + "finish_reason": "stop", + "message": { + "role": "assistant", + "content": response.choices[1].message.content, + }, + } + assert_message_in_logs(logs[2], "gen_ai.choice", choice_event_1, spans[0]) + + +@pytest.mark.vcr() +def test_chat_completion_tool_calls_with_content( + span_exporter, log_exporter, openai_client, instrument_with_content +): + chat_completion_tool_call(span_exporter, log_exporter, openai_client, True) + + +@pytest.mark.vcr() +def test_chat_completion_tool_calls_no_content( + span_exporter, log_exporter, openai_client, instrument_no_content +): + chat_completion_tool_call( + span_exporter, log_exporter, openai_client, False + ) + + +def chat_completion_tool_call( + span_exporter, log_exporter, openai_client, expect_content +): + llm_model_value = "gpt-4o-mini" + messages_value = [ + {"role": "system", "content": "You're a helpful assistant."}, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?", + }, + ] + + response_0 = openai_client.chat.completions.create( + messages=messages_value, + model=llm_model_value, + tool_choice="auto", + tools=[get_current_weather_tool_definition()], + ) + + # sanity check + assert "tool_calls" in response_0.choices[0].finish_reason + + # final request + messages_value.append( + { + "role": "assistant", + "tool_calls": response_0.choices[0].message.to_dict()[ + "tool_calls" + ], + } + ) + + tool_call_result_0 = { + "role": "tool", + "content": "50 degrees and raining", + "tool_call_id": response_0.choices[0].message.tool_calls[0].id, + } + tool_call_result_1 = { + "role": "tool", + "content": "70 degrees and sunny", + "tool_call_id": response_0.choices[0].message.tool_calls[1].id, + } + + messages_value.append(tool_call_result_0) + messages_value.append(tool_call_result_1) + + response_1 = openai_client.chat.completions.create( + messages=messages_value, model=llm_model_value + ) + + # sanity check + assert "stop" in response_1.choices[0].finish_reason + + # validate both calls + spans = span_exporter.get_finished_spans() + assert len(spans) == 2 + assert_completion_attributes(spans[0], llm_model_value, response_0) + assert_completion_attributes(spans[1], llm_model_value, response_1) + + logs = log_exporter.get_finished_logs() + assert len(logs) == 9 # 3 logs for first completion, 6 for second + + # call one + system_message = ( + {"content": messages_value[0]["content"]} if expect_content else None + ) + assert_message_in_logs( + logs[0], "gen_ai.system.message", system_message, spans[0] + ) + + user_message = ( + {"content": messages_value[1]["content"]} if expect_content else None + ) + assert_message_in_logs( + logs[1], "gen_ai.user.message", user_message, spans[0] + ) + + function_call_0 = {"name": "get_current_weather"} + function_call_1 = {"name": "get_current_weather"} + if expect_content: + function_call_0["arguments"] = ( + response_0.choices[0] + .message.tool_calls[0] + .function.arguments.replace("\n", "") + ) + function_call_1["arguments"] = ( + response_0.choices[0] + .message.tool_calls[1] + .function.arguments.replace("\n", "") + ) + + choice_event = { + "index": 0, + "finish_reason": "tool_calls", + "message": { + "role": "assistant", + "tool_calls": [ + { + "id": response_0.choices[0].message.tool_calls[0].id, + "type": "function", + "function": function_call_0, + }, + { + "id": response_0.choices[0].message.tool_calls[1].id, + "type": "function", + "function": function_call_1, + }, + ], + }, + } + assert_message_in_logs(logs[2], "gen_ai.choice", choice_event, spans[0]) + + # call two + system_message = ( + {"content": messages_value[0]["content"]} if expect_content else None + ) + assert_message_in_logs( + logs[3], "gen_ai.system.message", system_message, spans[1] + ) + + user_message = ( + {"content": messages_value[1]["content"]} if expect_content else None + ) + assert_message_in_logs( + logs[4], "gen_ai.user.message", user_message, spans[1] + ) + + assistant_tool_call = {"tool_calls": messages_value[2]["tool_calls"]} + if not expect_content: + assistant_tool_call["tool_calls"][0]["function"]["arguments"] = None + assistant_tool_call["tool_calls"][1]["function"]["arguments"] = None + + assert_message_in_logs( + logs[5], "gen_ai.assistant.message", assistant_tool_call, spans[1] + ) + + tool_message_0 = { + "id": tool_call_result_0["tool_call_id"], + "content": tool_call_result_0["content"] if expect_content else None, + } + + assert_message_in_logs( + logs[6], "gen_ai.tool.message", tool_message_0, spans[1] + ) + + tool_message_1 = { + "id": tool_call_result_1["tool_call_id"], + "content": tool_call_result_1["content"] if expect_content else None, + } + + assert_message_in_logs( + logs[7], "gen_ai.tool.message", tool_message_1, spans[1] + ) + + message = { + "role": "assistant", + "content": response_1.choices[0].message.content + if expect_content + else None, + } + choice = { + "index": 0, + "finish_reason": "stop", + "message": message, + } + assert_message_in_logs(logs[8], "gen_ai.choice", choice, spans[1]) + + +@pytest.mark.vcr() +def test_chat_completion_streaming( + span_exporter, log_exporter, openai_client, instrument_with_content +): + llm_model_value = "gpt-4" + messages_value = [{"role": "user", "content": "Say this is a test"}] + + kwargs = { + "model": llm_model_value, + "messages": messages_value, + "stream": True, + "stream_options": {"include_usage": True}, + } + + response_stream_usage = None + response_stream_model = None + response_stream_id = None + response_stream_result = "" + response = openai_client.chat.completions.create(**kwargs) + for chunk in response: + if chunk.choices: + response_stream_result += chunk.choices[0].delta.content or "" + + # get the last chunk + if getattr(chunk, "usage", None): + response_stream_usage = chunk.usage + response_stream_model = chunk.model + response_stream_id = chunk.id + + spans = span_exporter.get_finished_spans() + assert_all_attributes( + spans[0], + llm_model_value, + response_stream_id, + response_stream_model, + response_stream_usage.prompt_tokens, + response_stream_usage.completion_tokens, + ) + + logs = log_exporter.get_finished_logs() + assert len(logs) == 2 + + user_message = {"content": "Say this is a test"} + assert_message_in_logs( + logs[0], "gen_ai.user.message", user_message, spans[0] + ) + + choice_event = { + "index": 0, + "finish_reason": "stop", + "message": {"role": "assistant", "content": response_stream_result}, + } + assert_message_in_logs(logs[1], "gen_ai.choice", choice_event, spans[0]) + + +@pytest.mark.vcr() +def test_chat_completion_streaming_not_complete( + span_exporter, log_exporter, openai_client, instrument_with_content +): + llm_model_value = "gpt-4" + messages_value = [{"role": "user", "content": "Say this is a test"}] + + kwargs = { + "model": llm_model_value, + "messages": messages_value, + "stream": True, + } + + response_stream_model = None + response_stream_id = None + response_stream_result = "" + response = openai_client.chat.completions.create(**kwargs) + for idx, chunk in enumerate(response): + if chunk.choices: + response_stream_result += chunk.choices[0].delta.content or "" + if idx == 1: + # fake a stop + break + + if chunk.model: + response_stream_model = chunk.model + if chunk.id: + response_stream_id = chunk.id + + response.close() + spans = span_exporter.get_finished_spans() + assert_all_attributes( + spans[0], llm_model_value, response_stream_id, response_stream_model + ) + + logs = log_exporter.get_finished_logs() + assert len(logs) == 2 + + user_message = {"content": "Say this is a test"} + assert_message_in_logs( + logs[0], "gen_ai.user.message", user_message, spans[0] + ) + + choice_event = { + "index": 0, + "finish_reason": "error", + "message": {"role": "assistant", "content": response_stream_result}, + } + assert_message_in_logs(logs[1], "gen_ai.choice", choice_event, spans[0]) + + +@pytest.mark.vcr() +def test_chat_completion_multiple_choices_streaming( + span_exporter, log_exporter, openai_client, instrument_with_content +): + llm_model_value = "gpt-4o-mini" + messages_value = [ + {"role": "system", "content": "You're a helpful assistant."}, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?", + }, + ] + + response_0 = openai_client.chat.completions.create( + messages=messages_value, + model=llm_model_value, + n=2, + stream=True, + stream_options={"include_usage": True}, + ) + + # two strings for each choice + response_stream_result = ["", ""] + finish_reasons = ["", ""] + for chunk in response_0: + if chunk.choices: + for choice in chunk.choices: + response_stream_result[choice.index] += ( + choice.delta.content or "" + ) + if choice.finish_reason: + finish_reasons[choice.index] = choice.finish_reason + + # get the last chunk + if getattr(chunk, "usage", None): + response_stream_usage = chunk.usage + response_stream_model = chunk.model + response_stream_id = chunk.id + + # sanity check + assert "stop" == finish_reasons[0] + + spans = span_exporter.get_finished_spans() + assert_all_attributes( + spans[0], + llm_model_value, + response_stream_id, + response_stream_model, + response_stream_usage.prompt_tokens, + response_stream_usage.completion_tokens, + ) + + logs = log_exporter.get_finished_logs() + assert len(logs) == 4 + + system_message = {"content": messages_value[0]["content"]} + assert_message_in_logs( + logs[0], "gen_ai.system.message", system_message, spans[0] + ) + + user_message = { + "content": "What's the weather in Seattle and San Francisco today?" + } + assert_message_in_logs( + logs[1], "gen_ai.user.message", user_message, spans[0] + ) + + choice_event_0 = { + "index": 0, + "finish_reason": "stop", + "message": { + "role": "assistant", + "content": "".join(response_stream_result[0]), + }, + } + assert_message_in_logs(logs[2], "gen_ai.choice", choice_event_0, spans[0]) + + choice_event_1 = { + "index": 1, + "finish_reason": "stop", + "message": { + "role": "assistant", + "content": "".join(response_stream_result[1]), + }, + } + assert_message_in_logs(logs[3], "gen_ai.choice", choice_event_1, spans[0]) + + +@pytest.mark.vcr() +def test_chat_completion_multiple_tools_streaming_with_content( + span_exporter, log_exporter, openai_client, instrument_with_content +): + chat_completion_multiple_tools_streaming( + span_exporter, log_exporter, openai_client, True + ) + + +@pytest.mark.vcr() +def test_chat_completion_multiple_tools_streaming_no_content( + span_exporter, log_exporter, openai_client, instrument_no_content +): + chat_completion_multiple_tools_streaming( + span_exporter, log_exporter, openai_client, False + ) + + +def chat_completion_multiple_tools_streaming( + span_exporter, log_exporter, openai_client, expect_content +): + llm_model_value = "gpt-4o-mini" + messages_value = [ + {"role": "system", "content": "You're a helpful assistant."}, + { + "role": "user", + "content": "What's the weather in Seattle and San Francisco today?", + }, + ] + + response = openai_client.chat.completions.create( + messages=messages_value, + model=llm_model_value, + tool_choice="auto", + tools=[get_current_weather_tool_definition()], + stream=True, + stream_options={"include_usage": True}, + ) + + finish_reason = None + # two tools + tool_names = ["", ""] + tool_call_ids = ["", ""] + tool_args = ["", ""] + for chunk in response: + if chunk.choices: + if chunk.choices[0].finish_reason: + finish_reason = chunk.choices[0].finish_reason + for tool_call in chunk.choices[0].delta.tool_calls or []: + t_idx = tool_call.index + if tool_call.id: + tool_call_ids[t_idx] = tool_call.id + if tool_call.function: + if tool_call.function.arguments: + tool_args[t_idx] += tool_call.function.arguments + if tool_call.function.name: + tool_names[t_idx] = tool_call.function.name + + # get the last chunk + if getattr(chunk, "usage", None): + response_stream_usage = chunk.usage + response_stream_model = chunk.model + response_stream_id = chunk.id + + # sanity check + assert "tool_calls" == finish_reason + + spans = span_exporter.get_finished_spans() + assert_all_attributes( + spans[0], + llm_model_value, + response_stream_id, + response_stream_model, + response_stream_usage.prompt_tokens, + response_stream_usage.completion_tokens, + ) + + logs = log_exporter.get_finished_logs() + assert len(logs) == 3 + + system_message = ( + {"content": messages_value[0]["content"]} if expect_content else None + ) + assert_message_in_logs( + logs[0], "gen_ai.system.message", system_message, spans[0] + ) + + user_message = ( + {"content": "What's the weather in Seattle and San Francisco today?"} + if expect_content + else None + ) + assert_message_in_logs( + logs[1], "gen_ai.user.message", user_message, spans[0] + ) + + choice_event = { + "index": 0, + "finish_reason": "tool_calls", + "message": { + "role": "assistant", + "tool_calls": [ + { + "id": tool_call_ids[0], + "type": "function", + "function": { + "name": tool_names[0], + "arguments": tool_args[0].replace("\n", "") + if expect_content + else None, + }, + }, + { + "id": tool_call_ids[1], + "type": "function", + "function": { + "name": tool_names[1], + "arguments": tool_args[1].replace("\n", "") + if expect_content + else None, + }, + }, + ], + }, + } + assert_message_in_logs(logs[2], "gen_ai.choice", choice_event, spans[0]) + + +def assert_message_in_logs(log, event_name, expected_content, parent_span): + assert log.log_record.attributes[EventAttributes.EVENT_NAME] == event_name + assert ( + log.log_record.attributes[GenAIAttributes.GEN_AI_SYSTEM] + == GenAIAttributes.GenAiSystemValues.OPENAI.value + ) + + if not expected_content: + assert not log.log_record.body + else: + assert log.log_record.body + assert dict(log.log_record.body) == remove_none_values( + expected_content + ) + assert_log_parent(log, parent_span) + + +def remove_none_values(body): + result = {} + for key, value in body.items(): + if value is None: + continue + if isinstance(value, dict): + result[key] = remove_none_values(value) + elif isinstance(value, list): + result[key] = [remove_none_values(i) for i in value] + else: + result[key] = value + return result + + +def assert_completion_attributes( + span: ReadableSpan, + request_model: str, + response: ChatCompletion, + operation_name: str = "chat", + server_address: str = "api.openai.com", +): + return assert_all_attributes( + span, + request_model, + response.id, + response.model, + response.usage.prompt_tokens, + response.usage.completion_tokens, + operation_name, + server_address, + ) + + +def assert_all_attributes( + span: ReadableSpan, + request_model: str, + response_id: str = None, + response_model: str = None, + input_tokens: Optional[int] = None, + output_tokens: Optional[int] = None, + operation_name: str = "chat", + server_address: str = "api.openai.com", +): + assert span.name == f"{operation_name} {request_model}" + assert ( + operation_name + == span.attributes[GenAIAttributes.GEN_AI_OPERATION_NAME] + ) + assert ( + GenAIAttributes.GenAiSystemValues.OPENAI.value + == span.attributes[GenAIAttributes.GEN_AI_SYSTEM] + ) + assert ( + request_model == span.attributes[GenAIAttributes.GEN_AI_REQUEST_MODEL] + ) + if response_model: + assert ( + response_model + == span.attributes[GenAIAttributes.GEN_AI_RESPONSE_MODEL] + ) + else: + assert GenAIAttributes.GEN_AI_RESPONSE_MODEL not in span.attributes + + if response_id: + assert ( + response_id == span.attributes[GenAIAttributes.GEN_AI_RESPONSE_ID] + ) + else: + assert GenAIAttributes.GEN_AI_RESPONSE_ID not in span.attributes + + if input_tokens: + assert ( + input_tokens + == span.attributes[GenAIAttributes.GEN_AI_USAGE_INPUT_TOKENS] + ) + else: + assert GenAIAttributes.GEN_AI_USAGE_INPUT_TOKENS not in span.attributes + + if output_tokens: + assert ( + output_tokens + == span.attributes[GenAIAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] + ) + else: + assert ( + GenAIAttributes.GEN_AI_USAGE_OUTPUT_TOKENS not in span.attributes + ) + + assert server_address == span.attributes[ServerAttributes.SERVER_ADDRESS] + + +def assert_log_parent(log, span): + assert log.log_record.trace_id == span.get_span_context().trace_id + assert log.log_record.span_id == span.get_span_context().span_id + assert log.log_record.trace_flags == span.get_span_context().trace_flags + + +def get_current_weather_tool_definition(): + return { + "type": "function", + "function": { + "name": "get_current_weather", + "description": "Get the current weather in a given location", + "parameters": { + "type": "object", + "properties": { + "location": { + "type": "string", + "description": "The city and state, e.g. Boston, MA", + }, + }, + "required": ["location"], + "additionalProperties": False, + }, + }, + } diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/README.rst b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/README.rst index bbd142a97e..4e9bb0fdf8 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/README.rst +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/README.rst @@ -24,7 +24,7 @@ which only needs a valid OpenAI API key. References ---------- -* `OpenTelemetry OpenAI Instrumentation `_ +* `OpenTelemetry OpenAI Instrumentation `_ * `OpenTelemetry Project `_ -* `OpenTelemetry Python Examples `_ +* `OpenTelemetry Python Examples `_ diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml index e28611d0c5..f37b6915e3 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml @@ -39,7 +39,7 @@ instruments = [ openai = "opentelemetry.instrumentation.openai_v2:OpenAIInstrumentor" [project.urls] -Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation/opentelemetry-instrumentation-openai-v2" +Homepage = "https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation-genai/opentelemetry-instrumentation-openai-v2" [tool.hatch.version] path = "src/opentelemetry/instrumentation/openai_v2/version.py" diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/__init__.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/__init__.py index ee3bbfdb73..b5673d36d6 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/__init__.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/__init__.py @@ -47,7 +47,7 @@ from opentelemetry._events import get_event_logger from opentelemetry.instrumentation.instrumentor import BaseInstrumentor from opentelemetry.instrumentation.openai_v2.package import _instruments -from opentelemetry.instrumentation.openai_v2.utils import is_content_enabled +from opentelemetry.instrumentation.genai_utils import is_content_enabled from opentelemetry.instrumentation.utils import unwrap from opentelemetry.semconv.schemas import Schemas from opentelemetry.trace import get_tracer diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py index cd284473ce..0f91e4acb7 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py @@ -18,6 +18,10 @@ from openai import Stream from opentelemetry._events import Event, EventLogger +from opentelemetry.instrumentation.genai_utils import ( + get_span_name, + handle_span_exception, +) from opentelemetry.semconv._incubating.attributes import ( gen_ai_attributes as GenAIAttributes, ) @@ -41,7 +45,7 @@ def chat_completions_create( def traced_method(wrapped, instance, args, kwargs): span_attributes = {**get_llm_request_attributes(kwargs, instance)} - span_name = f"{span_attributes[GenAIAttributes.GEN_AI_OPERATION_NAME]} {span_attributes[GenAIAttributes.GEN_AI_REQUEST_MODEL]}" + span_name = get_span_name(span_attributes) with tracer.start_as_current_span( name=span_name, kind=SpanKind.CLIENT, diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py index cf920c17ee..13c1ba78a2 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py @@ -216,12 +216,3 @@ def get_llm_request_attributes( # filter out None values return {k: v for k, v in attributes.items() if v is not None} - - -def handle_span_exception(span, error): - span.set_status(Status(StatusCode.ERROR, str(error))) - if span.is_recording(): - span.set_attribute( - ErrorAttributes.ERROR_TYPE, type(error).__qualname__ - ) - span.end() diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/genai_utils.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/genai_utils.py new file mode 100644 index 0000000000..f9db12c4a7 --- /dev/null +++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/genai_utils.py @@ -0,0 +1,51 @@ +# 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. + +from os import environ + +from opentelemetry.semconv._incubating.attributes import ( + gen_ai_attributes as GenAIAttributes, +) +from opentelemetry.semconv.attributes import ( + error_attributes as ErrorAttributes, +) +from opentelemetry.trace.status import Status, StatusCode + + +OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT = ( + "OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT" +) + + +def is_content_enabled() -> bool: + capture_content = environ.get( + OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT, "false" + ) + + return capture_content.lower() == "true" + + +def get_span_name(span_attributes): + name = span_attributes.get(GenAIAttributes.GEN_AI_OPERATION_NAME, "") + model = span_attributes.get(GenAIAttributes.GEN_AI_REQUEST_MODEL, "") + return f"{name} {model}" + + +def handle_span_exception(span, error): + span.set_status(Status(StatusCode.ERROR, str(error))) + if span.is_recording(): + span.set_attribute( + ErrorAttributes.ERROR_TYPE, type(error).__qualname__ + ) + span.end() From a9337d59ddb8888b774c492ebe31fccde678e2ab Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Wed, 4 Dec 2024 11:08:34 -0800 Subject: [PATCH 3/9] response --- .../instrumentation/cohere_v2/patch.py | 16 ++-- .../instrumentation/cohere_v2/utils.py | 75 +++++++++++++++++-- .../instrumentation/openai_v2/utils.py | 4 - 3 files changed, 76 insertions(+), 19 deletions(-) diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/patch.py b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/patch.py index bf74dd7187..70f4c22b57 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/patch.py +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/patch.py @@ -12,8 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -from opentelemetry._events import Event, EventLogger -from opentelemetry.trace import Span, SpanKind, Tracer +from opentelemetry._events import EventLogger +from opentelemetry.trace import SpanKind, Tracer from opentelemetry.instrumentation.genai_utils import ( get_span_name, handle_span_exception @@ -22,7 +22,8 @@ from .utils import ( get_llm_request_attributes, message_to_event, - set_server_address_and_port + set_response_attributes, + set_server_address_and_port, ) @@ -52,11 +53,10 @@ def traced_method(wrapped, instance, args, kwargs): try: result = wrapped(*args, **kwargs) - # if span.is_recording(): - # _set_response_attributes( - # span, result, event_logger, capture_content - # ) - span.end() + if span.is_recording(): + set_response_attributes( + span, result, event_logger, capture_content + ) return result except Exception as error: diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/utils.py b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/utils.py index e91711c86e..51ebc43dde 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/utils.py +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/utils.py @@ -11,21 +11,23 @@ # 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. +import cohere -from typing import Optional, Union +from typing import List, Optional, Union from urllib.parse import urlparse -from opentelemetry._events import Event +from opentelemetry._events import Event, EventLogger from opentelemetry.semconv._incubating.attributes import ( gen_ai_attributes as GenAIAttributes, ) from opentelemetry.semconv._incubating.attributes import ( server_attributes as ServerAttributes, ) +from opentelemetry.trace import Span -def extract_tool_calls(item, capture_content): - tool_calls = get_property_value(item, "tool_calls") +def extract_tool_calls(item: Union[cohere.types.ChatMessageV2, cohere.AssistantMessageResponse], capture_content: bool): + tool_calls: Optional[List[cohere.ToolCallV2]] = get_property_value(item, "tool_calls") if tool_calls is None: return None @@ -65,7 +67,7 @@ def get_property_value(obj, property_name): return getattr(obj, property_name, None) -def set_server_address_and_port(client_instance, attributes): +def set_server_address_and_port(client_instance: cohere.client_v2.V2Client, attributes): base_client = getattr(client_instance, "_client_wrapper", None) base_url = getattr(base_client, "base_url", None) if not base_url: @@ -82,7 +84,7 @@ def set_server_address_and_port(client_instance, attributes): def get_llm_request_attributes( kwargs, - client_instance, + client_instance: cohere.client_v2.V2Client, operation_name=GenAIAttributes.GenAiOperationNameValues.CHAT.value, ): attributes = { @@ -116,7 +118,7 @@ def get_llm_request_attributes( return {k: v for k, v in attributes.items() if v is not None} -def message_to_event(message, capture_content): +def message_to_event(message: cohere.types.ChatMessageV2, capture_content: bool) -> Event: attributes = { GenAIAttributes.GEN_AI_SYSTEM: GenAIAttributes.GenAiSystemValues.COHERE.value } @@ -140,3 +142,62 @@ def message_to_event(message, capture_content): attributes=attributes, body=body if body else None, ) + + +def set_response_attributes( + span: Span, result: cohere.ChatResponse, event_logger: EventLogger, capture_content: bool +): + event_logger.emit(_response_to_event(result, capture_content)) + + span.set_attribute( + GenAIAttributes.GEN_AI_RESPONSE_FINISH_REASONS, + [result.finish_reason], + ) + + if getattr(result, "id", None): + span.set_attribute(GenAIAttributes.GEN_AI_RESPONSE_ID, result.id) + + # Get the usage + if getattr(result, "usage", None): + if getattr(result.usage, "tokens"): + span.set_attribute( + GenAIAttributes.GEN_AI_USAGE_INPUT_TOKENS, + result.usage.tokens.input_tokens, + ) + span.set_attribute( + GenAIAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, + result.usage.tokens.output_tokens, + ) + + +def _response_to_event(response: cohere.ChatResponse, capture_content): + attributes = { + GenAIAttributes.GEN_AI_SYSTEM: GenAIAttributes.GenAiSystemValues.COHERE.value + } + + body = { + "id": response.id, + "finish_reason": response.finish_reason or "error", + } + + if response.message: + message = { + "role": ( + response.message.role + if response.message.role and response.message.role != "assistant" + else None + ) + } + tool_calls = extract_tool_calls(response.message, capture_content) + if tool_calls: + message["tool_calls"] = tool_calls + content: List[cohere.AssistantMessageResponseContentItem] = get_property_value(response.message, "content") + if capture_content and content: + message["content"] = content + body["message"] = message + + return Event( + name="gen_ai.choice", + attributes=attributes, + body=body, + ) \ No newline at end of file diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py index 13c1ba78a2..429af15a35 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py @@ -26,10 +26,6 @@ from opentelemetry.semconv._incubating.attributes import ( server_attributes as ServerAttributes, ) -from opentelemetry.semconv.attributes import ( - error_attributes as ErrorAttributes, -) -from opentelemetry.trace.status import Status, StatusCode OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT = ( "OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT" From ff6d7412a3064600d2603b2af99c292ef648f5f0 Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Mon, 9 Dec 2024 11:26:31 -0800 Subject: [PATCH 4/9] tests --- dev-requirements.txt | 1 + .../example/main.py | 2 + .../test_async_chat_completion_404.yaml | 89 -- ...st_async_chat_completion_extra_params.yaml | 137 -- ...sync_chat_completion_multiple_choices.yaml | 143 -- ...completion_multiple_choices_streaming.yaml | 382 ----- ...n_multiple_tools_streaming_no_content.yaml | 164 --- ...multiple_tools_streaming_with_content.yaml | 164 --- .../test_async_chat_completion_streaming.yaml | 117 -- ...hat_completion_streaming_not_complete.yaml | 112 -- ...chat_completion_tool_calls_no_content.yaml | 342 ----- ...at_completion_tool_calls_with_content.yaml | 342 ----- ...st_async_chat_completion_with_content.yaml | 132 -- .../cassettes/test_chat_completion_404.yaml | 91 -- .../test_chat_completion_extra_params.yaml | 139 -- ...test_chat_completion_multiple_choices.yaml | 145 -- ...completion_multiple_choices_streaming.yaml | 326 ---- ...n_multiple_tools_streaming_no_content.yaml | 166 --- ...multiple_tools_streaming_with_content.yaml | 166 --- .../test_chat_completion_streaming.yaml | 119 -- ...hat_completion_streaming_not_complete.yaml | 114 -- ...chat_completion_tool_calls_no_content.yaml | 346 ----- ...at_completion_tool_calls_with_content.yaml | 346 ----- .../test_chat_completion_with_content.yaml | 162 +- .../tests/conftest.py | 27 +- .../tests/test_async_chat_completions.py | 847 ----------- .../tests/test_chat_completions.py | 1307 ++++++++--------- .../instrumentation/openai_v2/patch.py | 1 - .../instrumentation/openai_v2/utils.py | 12 - .../tests/conftest.py | 4 +- 30 files changed, 731 insertions(+), 5714 deletions(-) delete mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_404.yaml delete mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_extra_params.yaml delete mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_multiple_choices.yaml delete mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_multiple_choices_streaming.yaml delete mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_multiple_tools_streaming_no_content.yaml delete mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_multiple_tools_streaming_with_content.yaml delete mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_streaming.yaml delete mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_streaming_not_complete.yaml delete mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_tool_calls_no_content.yaml delete mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_tool_calls_with_content.yaml delete mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_with_content.yaml delete mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_404.yaml delete mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_extra_params.yaml delete mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_multiple_choices.yaml delete mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_multiple_choices_streaming.yaml delete mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_no_content.yaml delete mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_with_content.yaml delete mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_streaming.yaml delete mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_streaming_not_complete.yaml delete mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_tool_calls_no_content.yaml delete mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_tool_calls_with_content.yaml delete mode 100644 instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/test_async_chat_completions.py diff --git a/dev-requirements.txt b/dev-requirements.txt index 70464ffdd7..7147e08f15 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -6,6 +6,7 @@ sphinx-rtd-theme==2.0.0rc4 sphinx-autodoc-typehints==1.25.2 pytest==7.4.4 pytest-cov==4.1.0 +pytest-vcr==1.0.2 readme-renderer==42.0 bleach==4.1.0 # transient dependency for readme-renderer protobuf~=3.13 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/example/main.py b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/example/main.py index 3f2450159c..6e7ded4dc9 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/example/main.py +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/example/main.py @@ -1,5 +1,7 @@ import cohere +import openai +import openai.resources from opentelemetry import trace from opentelemetry.instrumentation.cohere_v2 import CohereInstrumentor from opentelemetry.sdk.trace import TracerProvider diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_404.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_404.yaml deleted file mode 100644 index e055e68f20..0000000000 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_404.yaml +++ /dev/null @@ -1,89 +0,0 @@ -interactions: -- request: - body: |- - { - "messages": [ - { - "role": "user", - "content": "Say this is a test" - } - ], - "model": "this-model-does-not-exist" - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - authorization: - - Bearer test_openai_api_key - connection: - - keep-alive - content-length: - - '103' - content-type: - - application/json - host: - - api.openai.com - user-agent: - - AsyncOpenAI/Python 1.26.0 - x-stainless-arch: - - arm64 - x-stainless-async: - - async:asyncio - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 1.26.0 - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.12.5 - method: POST - uri: https://api.openai.com/v1/chat/completions - response: - body: - string: |- - { - "error": { - "message": "The model `this-model-does-not-exist` does not exist or you do not have access to it.", - "type": "invalid_request_error", - "param": null, - "code": "model_not_found" - } - } - headers: - CF-Cache-Status: - - DYNAMIC - CF-RAY: - - 8e1a80827a861852-MRS - Connection: - - keep-alive - Content-Type: - - application/json; charset=utf-8 - Date: - - Wed, 13 Nov 2024 00:04:01 GMT - Server: - - cloudflare - Set-Cookie: test_set_cookie - Transfer-Encoding: - - chunked - X-Content-Type-Options: - - nosniff - alt-svc: - - h3=":443"; ma=86400 - content-length: - - '231' - openai-organization: test_openai_org_id - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - vary: - - Origin - x-request-id: - - req_5cf06a7fabd45ebe21ee38c14c5b2f76 - status: - code: 404 - message: Not Found -version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_extra_params.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_extra_params.yaml deleted file mode 100644 index 3d13c9344e..0000000000 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_extra_params.yaml +++ /dev/null @@ -1,137 +0,0 @@ -interactions: -- request: - body: |- - { - "messages": [ - { - "role": "user", - "content": "Say this is a test" - } - ], - "model": "gpt-4o-mini", - "max_tokens": 50, - "seed": 42, - "stream": false, - "temperature": 0.5, - "service_tier": "default" - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - authorization: - - Bearer test_openai_api_key - connection: - - keep-alive - content-length: - - '183' - content-type: - - application/json - host: - - api.openai.com - user-agent: - - AsyncOpenAI/Python 1.26.0 - x-stainless-arch: - - arm64 - x-stainless-async: - - async:asyncio - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 1.26.0 - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.12.5 - method: POST - uri: https://api.openai.com/v1/chat/completions - response: - body: - string: |- - { - "id": "chatcmpl-ASv9WMTAMZY4O1EImv3csZa6Ch7KI", - "object": "chat.completion", - "created": 1731456242, - "model": "gpt-4o-mini-2024-07-18", - "choices": [ - { - "index": 0, - "message": { - "role": "assistant", - "content": "This is a test. How can I assist you further?", - "refusal": null - }, - "logprobs": null, - "finish_reason": "stop" - } - ], - "usage": { - "prompt_tokens": 12, - "completion_tokens": 12, - "total_tokens": 24, - "prompt_tokens_details": { - "cached_tokens": 0, - "audio_tokens": 0 - }, - "completion_tokens_details": { - "reasoning_tokens": 0, - "audio_tokens": 0, - "accepted_prediction_tokens": 0, - "rejected_prediction_tokens": 0 - } - }, - "service_tier": "default", - "system_fingerprint": "fp_0ba0d124f1" - } - headers: - CF-Cache-Status: - - DYNAMIC - CF-RAY: - - 8e1a8088f867e167-MRS - Connection: - - keep-alive - Content-Type: - - application/json - Date: - - Wed, 13 Nov 2024 00:04:02 GMT - Server: - - cloudflare - Set-Cookie: test_set_cookie - Transfer-Encoding: - - chunked - X-Content-Type-Options: - - nosniff - access-control-expose-headers: - - X-Request-ID - alt-svc: - - h3=":443"; ma=86400 - content-length: - - '825' - openai-organization: test_openai_org_id - openai-processing-ms: - - '488' - openai-version: - - '2020-10-01' - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-ratelimit-limit-requests: - - '30000' - x-ratelimit-limit-tokens: - - '150000000' - x-ratelimit-remaining-requests: - - '29999' - x-ratelimit-remaining-tokens: - - '149999943' - x-ratelimit-reset-requests: - - 2ms - x-ratelimit-reset-tokens: - - 0s - x-request-id: - - req_6df08d6267415e8f5db3628a6757edad - status: - code: 200 - message: OK -version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_multiple_choices.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_multiple_choices.yaml deleted file mode 100644 index 1404b8163a..0000000000 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_multiple_choices.yaml +++ /dev/null @@ -1,143 +0,0 @@ -interactions: -- request: - body: |- - { - "messages": [ - { - "role": "user", - "content": "Say this is a test" - } - ], - "model": "gpt-4o-mini", - "n": 2, - "stream": false - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - authorization: - - Bearer test_openai_api_key - connection: - - keep-alive - content-length: - - '114' - content-type: - - application/json - host: - - api.openai.com - user-agent: - - AsyncOpenAI/Python 1.26.0 - x-stainless-arch: - - arm64 - x-stainless-async: - - async:asyncio - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 1.26.0 - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.12.5 - method: POST - uri: https://api.openai.com/v1/chat/completions - response: - body: - string: |- - { - "id": "chatcmpl-ASv9XLlMmT7H3cf50dNTesHDBDwX5", - "object": "chat.completion", - "created": 1731456243, - "model": "gpt-4o-mini-2024-07-18", - "choices": [ - { - "index": 0, - "message": { - "role": "assistant", - "content": "This is a test.", - "refusal": null - }, - "logprobs": null, - "finish_reason": "stop" - }, - { - "index": 1, - "message": { - "role": "assistant", - "content": "This is a test.", - "refusal": null - }, - "logprobs": null, - "finish_reason": "stop" - } - ], - "usage": { - "prompt_tokens": 12, - "completion_tokens": 10, - "total_tokens": 22, - "prompt_tokens_details": { - "cached_tokens": 0, - "audio_tokens": 0 - }, - "completion_tokens_details": { - "reasoning_tokens": 0, - "audio_tokens": 0, - "accepted_prediction_tokens": 0, - "rejected_prediction_tokens": 0 - } - }, - "system_fingerprint": "fp_0ba0d124f1" - } - headers: - CF-Cache-Status: - - DYNAMIC - CF-RAY: - - 8e1a808f6d8e0d8b-MRS - Connection: - - keep-alive - Content-Type: - - application/json - Date: - - Wed, 13 Nov 2024 00:04:04 GMT - Server: - - cloudflare - Set-Cookie: test_set_cookie - Transfer-Encoding: - - chunked - X-Content-Type-Options: - - nosniff - access-control-expose-headers: - - X-Request-ID - alt-svc: - - h3=":443"; ma=86400 - content-length: - - '970' - openai-organization: test_openai_org_id - openai-processing-ms: - - '306' - openai-version: - - '2020-10-01' - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-ratelimit-limit-requests: - - '30000' - x-ratelimit-limit-tokens: - - '150000000' - x-ratelimit-remaining-requests: - - '29999' - x-ratelimit-remaining-tokens: - - '149999962' - x-ratelimit-reset-requests: - - 2ms - x-ratelimit-reset-tokens: - - 0s - x-request-id: - - req_1317908e0f9b73276b57d4e171c533ea - status: - code: 200 - message: OK -version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_multiple_choices_streaming.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_multiple_choices_streaming.yaml deleted file mode 100644 index 4bca03a9e8..0000000000 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_multiple_choices_streaming.yaml +++ /dev/null @@ -1,382 +0,0 @@ -interactions: -- request: - body: |- - { - "messages": [ - { - "role": "system", - "content": "You're a helpful assistant." - }, - { - "role": "user", - "content": "What's the weather in Seattle and San Francisco today?" - } - ], - "model": "gpt-4o-mini", - "n": 2, - "stream": true, - "stream_options": { - "include_usage": true - } - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - authorization: - - Bearer test_openai_api_key - connection: - - keep-alive - content-length: - - '254' - content-type: - - application/json - host: - - api.openai.com - user-agent: - - AsyncOpenAI/Python 1.26.0 - x-stainless-arch: - - arm64 - x-stainless-async: - - async:asyncio - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 1.26.0 - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.12.5 - method: POST - uri: https://api.openai.com/v1/chat/completions - response: - body: - string: |+ - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"I'm"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"I'm"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" unable"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" unable"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" provide"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" provide"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" real"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" real"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"-time"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"-time"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" updates"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" updates"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" as"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" as"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" my"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" my"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" knowledge"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" knowledge"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" was"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" only"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" last"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" extends"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" until"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" updated"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" in"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" October"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" October"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" "},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" "},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"202"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"202"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"3"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"1"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" I"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" I"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" don't"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" have"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" access"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" don't"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" have"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" access"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" live"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" live"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" data"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" data"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" However"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" However"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" you"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" you"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" can"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" can"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" easily"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" easily"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" check"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" check"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" current"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" current"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" in"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" for"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" Seattle"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" Seattle"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" San"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" San"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" Francisco"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" Francisco"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" by"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" using"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" visiting"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" website"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" website"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" or"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" or"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" using"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" mobile"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" app"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" for"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" app"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" most"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" If"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" accurate"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" you"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" need"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" up"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" historical"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" information"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" or"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" general"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" climate"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" data"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" for"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" those"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" cities"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" feel"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" free"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" ask"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"!"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"-to"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"-date"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" information"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null} - - data: {"id":"chatcmpl-ASv9hB9He94oQyZr1CDC8coqvmn5U","object":"chat.completion.chunk","created":1731456253,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[],"usage":{"prompt_tokens":26,"completion_tokens":133,"total_tokens":159,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}}} - - data: [DONE] - - headers: - CF-Cache-Status: - - DYNAMIC - CF-RAY: - - 8e1a80ceac3ce19a-MRS - Connection: - - keep-alive - Content-Type: - - text/event-stream; charset=utf-8 - Date: - - Wed, 13 Nov 2024 00:04:13 GMT - Server: - - cloudflare - Set-Cookie: test_set_cookie - Transfer-Encoding: - - chunked - X-Content-Type-Options: - - nosniff - access-control-expose-headers: - - X-Request-ID - alt-svc: - - h3=":443"; ma=86400 - openai-organization: test_openai_org_id - openai-processing-ms: - - '126' - openai-version: - - '2020-10-01' - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-ratelimit-limit-requests: - - '30000' - x-ratelimit-limit-tokens: - - '150000000' - x-ratelimit-remaining-requests: - - '29999' - x-ratelimit-remaining-tokens: - - '149999945' - x-ratelimit-reset-requests: - - 2ms - x-ratelimit-reset-tokens: - - 0s - x-request-id: - - req_5dd8b6845db59fa55cf226eda1f5a2c6 - status: - code: 200 - message: OK -version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_multiple_tools_streaming_no_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_multiple_tools_streaming_no_content.yaml deleted file mode 100644 index 19319de476..0000000000 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_multiple_tools_streaming_no_content.yaml +++ /dev/null @@ -1,164 +0,0 @@ -interactions: -- request: - body: |- - { - "messages": [ - { - "role": "system", - "content": "You're a helpful assistant." - }, - { - "role": "user", - "content": "What's the weather in Seattle and San Francisco today?" - } - ], - "model": "gpt-4o-mini", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "type": "function", - "function": { - "name": "get_current_weather", - "description": "Get the current weather in a given location", - "parameters": { - "type": "object", - "properties": { - "location": { - "type": "string", - "description": "The city and state, e.g. Boston, MA" - } - }, - "required": [ - "location" - ], - "additionalProperties": false - } - } - } - ] - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - authorization: - - Bearer test_openai_api_key - connection: - - keep-alive - content-length: - - '602' - content-type: - - application/json - host: - - api.openai.com - user-agent: - - AsyncOpenAI/Python 1.26.0 - x-stainless-arch: - - arm64 - x-stainless-async: - - async:asyncio - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 1.26.0 - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.12.5 - method: POST - uri: https://api.openai.com/v1/chat/completions - response: - body: - string: |+ - data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"role":"assistant","content":null},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_hqkL24CLEwnniv4GDrjk14Iu","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n\": \"S"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"eatt"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"le, W"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"id":"call_0s1enkFttXjIR7ozHoGMcnUu","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"n\": \"S"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"an F"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"ranci"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"sco, C"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"tool_calls"}],"usage":null} - - data: {"id":"chatcmpl-ASv9l0RKJrq2fTx2dK5jhJoIr4rMI","object":"chat.completion.chunk","created":1731456257,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[],"usage":{"prompt_tokens":75,"completion_tokens":51,"total_tokens":126,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}}} - - data: [DONE] - - headers: - CF-Cache-Status: - - DYNAMIC - CF-RAY: - - 8e1a80e4cfb00d86-MRS - Connection: - - keep-alive - Content-Type: - - text/event-stream; charset=utf-8 - Date: - - Wed, 13 Nov 2024 00:04:19 GMT - Server: - - cloudflare - Set-Cookie: test_set_cookie - Transfer-Encoding: - - chunked - X-Content-Type-Options: - - nosniff - access-control-expose-headers: - - X-Request-ID - alt-svc: - - h3=":443"; ma=86400 - openai-organization: test_openai_org_id - openai-processing-ms: - - '1597' - openai-version: - - '2020-10-01' - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-ratelimit-limit-requests: - - '30000' - x-ratelimit-limit-tokens: - - '150000000' - x-ratelimit-remaining-requests: - - '29999' - x-ratelimit-remaining-tokens: - - '149999960' - x-ratelimit-reset-requests: - - 2ms - x-ratelimit-reset-tokens: - - 0s - x-request-id: - - req_487aef2347cb4d1f97077c488dd93628 - status: - code: 200 - message: OK -version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_multiple_tools_streaming_with_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_multiple_tools_streaming_with_content.yaml deleted file mode 100644 index a026912ee1..0000000000 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_multiple_tools_streaming_with_content.yaml +++ /dev/null @@ -1,164 +0,0 @@ -interactions: -- request: - body: |- - { - "messages": [ - { - "role": "system", - "content": "You're a helpful assistant." - }, - { - "role": "user", - "content": "What's the weather in Seattle and San Francisco today?" - } - ], - "model": "gpt-4o-mini", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "type": "function", - "function": { - "name": "get_current_weather", - "description": "Get the current weather in a given location", - "parameters": { - "type": "object", - "properties": { - "location": { - "type": "string", - "description": "The city and state, e.g. Boston, MA" - } - }, - "required": [ - "location" - ], - "additionalProperties": false - } - } - } - ] - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - authorization: - - Bearer test_openai_api_key - connection: - - keep-alive - content-length: - - '602' - content-type: - - application/json - host: - - api.openai.com - user-agent: - - AsyncOpenAI/Python 1.26.0 - x-stainless-arch: - - arm64 - x-stainless-async: - - async:asyncio - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 1.26.0 - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.12.5 - method: POST - uri: https://api.openai.com/v1/chat/completions - response: - body: - string: |+ - data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"role":"assistant","content":null},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_oJL2dc4GjWVxqBtWlGLwjbsR","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n\": \"S"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"eatt"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"le, W"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"id":"call_ON3lp1OWsbw2obNRD43KVDp6","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"n\": \"S"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"an F"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"ranci"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"sco, C"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"tool_calls"}],"usage":null} - - data: {"id":"chatcmpl-ASv9jfgm5JguNGaR9o9u94HpuhV7T","object":"chat.completion.chunk","created":1731456255,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[],"usage":{"prompt_tokens":75,"completion_tokens":51,"total_tokens":126,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}}} - - data: [DONE] - - headers: - CF-Cache-Status: - - DYNAMIC - CF-RAY: - - 8e1a80d8efb9e1c8-MRS - Connection: - - keep-alive - Content-Type: - - text/event-stream; charset=utf-8 - Date: - - Wed, 13 Nov 2024 00:04:16 GMT - Server: - - cloudflare - Set-Cookie: test_set_cookie - Transfer-Encoding: - - chunked - X-Content-Type-Options: - - nosniff - access-control-expose-headers: - - X-Request-ID - alt-svc: - - h3=":443"; ma=86400 - openai-organization: test_openai_org_id - openai-processing-ms: - - '1162' - openai-version: - - '2020-10-01' - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-ratelimit-limit-requests: - - '30000' - x-ratelimit-limit-tokens: - - '150000000' - x-ratelimit-remaining-requests: - - '29999' - x-ratelimit-remaining-tokens: - - '149999960' - x-ratelimit-reset-requests: - - 2ms - x-ratelimit-reset-tokens: - - 0s - x-request-id: - - req_0b6729aef347cecd61ba3b7b7a8d4719 - status: - code: 200 - message: OK -version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_streaming.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_streaming.yaml deleted file mode 100644 index efffcd7423..0000000000 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_streaming.yaml +++ /dev/null @@ -1,117 +0,0 @@ -interactions: -- request: - body: |- - { - "messages": [ - { - "role": "user", - "content": "Say this is a test" - } - ], - "model": "gpt-4", - "stream": true, - "stream_options": { - "include_usage": true - } - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - authorization: - - Bearer test_openai_api_key - connection: - - keep-alive - content-length: - - '142' - content-type: - - application/json - host: - - api.openai.com - user-agent: - - AsyncOpenAI/Python 1.26.0 - x-stainless-arch: - - arm64 - x-stainless-async: - - async:asyncio - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 1.26.0 - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.12.5 - method: POST - uri: https://api.openai.com/v1/chat/completions - response: - body: - string: |+ - data: {"id":"chatcmpl-ASv9ejXDUtAhGOJJxWuw026zdinc4","object":"chat.completion.chunk","created":1731456250,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9ejXDUtAhGOJJxWuw026zdinc4","object":"chat.completion.chunk","created":1731456250,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"This"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9ejXDUtAhGOJJxWuw026zdinc4","object":"chat.completion.chunk","created":1731456250,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" is"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9ejXDUtAhGOJJxWuw026zdinc4","object":"chat.completion.chunk","created":1731456250,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9ejXDUtAhGOJJxWuw026zdinc4","object":"chat.completion.chunk","created":1731456250,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" test"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9ejXDUtAhGOJJxWuw026zdinc4","object":"chat.completion.chunk","created":1731456250,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASv9ejXDUtAhGOJJxWuw026zdinc4","object":"chat.completion.chunk","created":1731456250,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null} - - data: {"id":"chatcmpl-ASv9ejXDUtAhGOJJxWuw026zdinc4","object":"chat.completion.chunk","created":1731456250,"model":"gpt-4-0613","system_fingerprint":null,"choices":[],"usage":{"prompt_tokens":12,"completion_tokens":5,"total_tokens":17,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}}} - - data: [DONE] - - headers: - CF-Cache-Status: - - DYNAMIC - CF-RAY: - - 8e1a80bd2f31e1e5-MRS - Connection: - - keep-alive - Content-Type: - - text/event-stream; charset=utf-8 - Date: - - Wed, 13 Nov 2024 00:04:11 GMT - Server: - - cloudflare - Set-Cookie: test_set_cookie - Transfer-Encoding: - - chunked - X-Content-Type-Options: - - nosniff - access-control-expose-headers: - - X-Request-ID - alt-svc: - - h3=":443"; ma=86400 - openai-organization: test_openai_org_id - openai-processing-ms: - - '196' - openai-version: - - '2020-10-01' - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-ratelimit-limit-requests: - - '10000' - x-ratelimit-limit-tokens: - - '1000000' - x-ratelimit-remaining-requests: - - '9999' - x-ratelimit-remaining-tokens: - - '999977' - x-ratelimit-reset-requests: - - 6ms - x-ratelimit-reset-tokens: - - 1ms - x-request-id: - - req_cc9204ae23338b130df11c8c5b5f31af - status: - code: 200 - message: OK -version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_streaming_not_complete.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_streaming_not_complete.yaml deleted file mode 100644 index 9ef5613d17..0000000000 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_streaming_not_complete.yaml +++ /dev/null @@ -1,112 +0,0 @@ -interactions: -- request: - body: |- - { - "messages": [ - { - "role": "user", - "content": "Say this is a test" - } - ], - "model": "gpt-4", - "stream": true - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - authorization: - - Bearer test_openai_api_key - connection: - - keep-alive - content-length: - - '99' - content-type: - - application/json - host: - - api.openai.com - user-agent: - - AsyncOpenAI/Python 1.26.0 - x-stainless-arch: - - arm64 - x-stainless-async: - - async:asyncio - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 1.26.0 - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.12.5 - method: POST - uri: https://api.openai.com/v1/chat/completions - response: - body: - string: |+ - data: {"id":"chatcmpl-ASv9gROIIAvRs9QnmLP8Nzs3PGMCX","object":"chat.completion.chunk","created":1731456252,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASv9gROIIAvRs9QnmLP8Nzs3PGMCX","object":"chat.completion.chunk","created":1731456252,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"This"},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASv9gROIIAvRs9QnmLP8Nzs3PGMCX","object":"chat.completion.chunk","created":1731456252,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" is"},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASv9gROIIAvRs9QnmLP8Nzs3PGMCX","object":"chat.completion.chunk","created":1731456252,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASv9gROIIAvRs9QnmLP8Nzs3PGMCX","object":"chat.completion.chunk","created":1731456252,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" test"},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASv9gROIIAvRs9QnmLP8Nzs3PGMCX","object":"chat.completion.chunk","created":1731456252,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASv9gROIIAvRs9QnmLP8Nzs3PGMCX","object":"chat.completion.chunk","created":1731456252,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]} - - data: [DONE] - - headers: - CF-Cache-Status: - - DYNAMIC - CF-RAY: - - 8e1a80c54d00e288-MRS - Connection: - - keep-alive - Content-Type: - - text/event-stream; charset=utf-8 - Date: - - Wed, 13 Nov 2024 00:04:12 GMT - Server: - - cloudflare - Set-Cookie: test_set_cookie - Transfer-Encoding: - - chunked - X-Content-Type-Options: - - nosniff - access-control-expose-headers: - - X-Request-ID - alt-svc: - - h3=":443"; ma=86400 - openai-organization: test_openai_org_id - openai-processing-ms: - - '283' - openai-version: - - '2020-10-01' - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-ratelimit-limit-requests: - - '10000' - x-ratelimit-limit-tokens: - - '1000000' - x-ratelimit-remaining-requests: - - '9999' - x-ratelimit-remaining-tokens: - - '999977' - x-ratelimit-reset-requests: - - 6ms - x-ratelimit-reset-tokens: - - 1ms - x-request-id: - - req_e9e4ea6fd060391e8cc8cfea78ad9a15 - status: - code: 200 - message: OK -version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_tool_calls_no_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_tool_calls_no_content.yaml deleted file mode 100644 index 053e271d45..0000000000 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_tool_calls_no_content.yaml +++ /dev/null @@ -1,342 +0,0 @@ -interactions: -- request: - body: |- - { - "messages": [ - { - "role": "system", - "content": "You're a helpful assistant." - }, - { - "role": "user", - "content": "What's the weather in Seattle and San Francisco today?" - } - ], - "model": "gpt-4o-mini", - "tool_choice": "auto", - "tools": [ - { - "type": "function", - "function": { - "name": "get_current_weather", - "description": "Get the current weather in a given location", - "parameters": { - "type": "object", - "properties": { - "location": { - "type": "string", - "description": "The city and state, e.g. Boston, MA" - } - }, - "required": [ - "location" - ], - "additionalProperties": false - } - } - } - ] - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - authorization: - - Bearer test_openai_api_key - connection: - - keep-alive - content-length: - - '543' - content-type: - - application/json - host: - - api.openai.com - user-agent: - - AsyncOpenAI/Python 1.26.0 - x-stainless-arch: - - arm64 - x-stainless-async: - - async:asyncio - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 1.26.0 - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.12.5 - method: POST - uri: https://api.openai.com/v1/chat/completions - response: - body: - string: |- - { - "id": "chatcmpl-ASv9bJqWatpvCC0YMsYRcTSIiXoxk", - "object": "chat.completion", - "created": 1731456247, - "model": "gpt-4o-mini-2024-07-18", - "choices": [ - { - "index": 0, - "message": { - "role": "assistant", - "content": null, - "tool_calls": [ - { - "id": "call_vwOezSsB5j9ei1SSMlZjqx7g", - "type": "function", - "function": { - "name": "get_current_weather", - "arguments": "{\"location\": \"Seattle, WA\"}" - } - }, - { - "id": "call_LzeIYcKhHnVF60u4LmBpT1tv", - "type": "function", - "function": { - "name": "get_current_weather", - "arguments": "{\"location\": \"San Francisco, CA\"}" - } - } - ], - "refusal": null - }, - "logprobs": null, - "finish_reason": "tool_calls" - } - ], - "usage": { - "prompt_tokens": 75, - "completion_tokens": 51, - "total_tokens": 126, - "prompt_tokens_details": { - "cached_tokens": 0, - "audio_tokens": 0 - }, - "completion_tokens_details": { - "reasoning_tokens": 0, - "audio_tokens": 0, - "accepted_prediction_tokens": 0, - "rejected_prediction_tokens": 0 - } - }, - "system_fingerprint": "fp_0ba0d124f1" - } - headers: - CF-Cache-Status: - - DYNAMIC - CF-RAY: - - 8e1a80a9f8fbe1c9-MRS - Connection: - - keep-alive - Content-Type: - - application/json - Date: - - Wed, 13 Nov 2024 00:04:08 GMT - Server: - - cloudflare - Set-Cookie: test_set_cookie - Transfer-Encoding: - - chunked - X-Content-Type-Options: - - nosniff - access-control-expose-headers: - - X-Request-ID - alt-svc: - - h3=":443"; ma=86400 - content-length: - - '1308' - openai-organization: test_openai_org_id - openai-processing-ms: - - '808' - openai-version: - - '2020-10-01' - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-ratelimit-limit-requests: - - '30000' - x-ratelimit-limit-tokens: - - '150000000' - x-ratelimit-remaining-requests: - - '29999' - x-ratelimit-remaining-tokens: - - '149999960' - x-ratelimit-reset-requests: - - 2ms - x-ratelimit-reset-tokens: - - 0s - x-request-id: - - req_f1b9b75e4a73b542c9b1b992cd52c66f - status: - code: 200 - message: OK -- request: - body: |- - { - "messages": [ - { - "role": "system", - "content": "You're a helpful assistant." - }, - { - "role": "user", - "content": "What's the weather in Seattle and San Francisco today?" - }, - { - "role": "assistant", - "tool_calls": [ - { - "id": "call_vwOezSsB5j9ei1SSMlZjqx7g", - "function": { - "arguments": "{\"location\": \"Seattle, WA\"}", - "name": "get_current_weather" - }, - "type": "function" - }, - { - "id": "call_LzeIYcKhHnVF60u4LmBpT1tv", - "function": { - "arguments": "{\"location\": \"San Francisco, CA\"}", - "name": "get_current_weather" - }, - "type": "function" - } - ] - }, - { - "role": "tool", - "content": "50 degrees and raining", - "tool_call_id": "call_vwOezSsB5j9ei1SSMlZjqx7g" - }, - { - "role": "tool", - "content": "70 degrees and sunny", - "tool_call_id": "call_LzeIYcKhHnVF60u4LmBpT1tv" - } - ], - "model": "gpt-4o-mini" - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - authorization: - - Bearer test_openai_api_key - connection: - - keep-alive - content-length: - - '746' - content-type: - - application/json - cookie: - - test_cookie - host: - - api.openai.com - user-agent: - - AsyncOpenAI/Python 1.26.0 - x-stainless-arch: - - arm64 - x-stainless-async: - - async:asyncio - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 1.26.0 - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.12.5 - method: POST - uri: https://api.openai.com/v1/chat/completions - response: - body: - string: |- - { - "id": "chatcmpl-ASv9dfXfIwGCZgeWzDTbCh0FuU9kh", - "object": "chat.completion", - "created": 1731456249, - "model": "gpt-4o-mini-2024-07-18", - "choices": [ - { - "index": 0, - "message": { - "role": "assistant", - "content": "Today, the weather in Seattle is 50 degrees and raining, while in San Francisco, it's 70 degrees and sunny.", - "refusal": null - }, - "logprobs": null, - "finish_reason": "stop" - } - ], - "usage": { - "prompt_tokens": 99, - "completion_tokens": 25, - "total_tokens": 124, - "prompt_tokens_details": { - "cached_tokens": 0, - "audio_tokens": 0 - }, - "completion_tokens_details": { - "reasoning_tokens": 0, - "audio_tokens": 0, - "accepted_prediction_tokens": 0, - "rejected_prediction_tokens": 0 - } - }, - "system_fingerprint": "fp_0ba0d124f1" - } - headers: - CF-Cache-Status: - - DYNAMIC - CF-RAY: - - 8e1a80b3baade1c9-MRS - Connection: - - keep-alive - Content-Type: - - application/json - Date: - - Wed, 13 Nov 2024 00:04:10 GMT - Server: - - cloudflare - Set-Cookie: test_set_cookie - Transfer-Encoding: - - chunked - X-Content-Type-Options: - - nosniff - access-control-expose-headers: - - X-Request-ID - alt-svc: - - h3=":443"; ma=86400 - content-length: - - '859' - openai-organization: test_openai_org_id - openai-processing-ms: - - '972' - openai-version: - - '2020-10-01' - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-ratelimit-limit-requests: - - '30000' - x-ratelimit-limit-tokens: - - '150000000' - x-ratelimit-remaining-requests: - - '29999' - x-ratelimit-remaining-tokens: - - '149999948' - x-ratelimit-reset-requests: - - 2ms - x-ratelimit-reset-tokens: - - 0s - x-request-id: - - req_754e6b59f1d3da727e2210e3d8c56243 - status: - code: 200 - message: OK -version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_tool_calls_with_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_tool_calls_with_content.yaml deleted file mode 100644 index ebebb20603..0000000000 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_tool_calls_with_content.yaml +++ /dev/null @@ -1,342 +0,0 @@ -interactions: -- request: - body: |- - { - "messages": [ - { - "role": "system", - "content": "You're a helpful assistant." - }, - { - "role": "user", - "content": "What's the weather in Seattle and San Francisco today?" - } - ], - "model": "gpt-4o-mini", - "tool_choice": "auto", - "tools": [ - { - "type": "function", - "function": { - "name": "get_current_weather", - "description": "Get the current weather in a given location", - "parameters": { - "type": "object", - "properties": { - "location": { - "type": "string", - "description": "The city and state, e.g. Boston, MA" - } - }, - "required": [ - "location" - ], - "additionalProperties": false - } - } - } - ] - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - authorization: - - Bearer test_openai_api_key - connection: - - keep-alive - content-length: - - '543' - content-type: - - application/json - host: - - api.openai.com - user-agent: - - AsyncOpenAI/Python 1.26.0 - x-stainless-arch: - - arm64 - x-stainless-async: - - async:asyncio - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 1.26.0 - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.12.5 - method: POST - uri: https://api.openai.com/v1/chat/completions - response: - body: - string: |- - { - "id": "chatcmpl-ASv9ZqgNAOJAOLYMgdmxouatKXJlk", - "object": "chat.completion", - "created": 1731456245, - "model": "gpt-4o-mini-2024-07-18", - "choices": [ - { - "index": 0, - "message": { - "role": "assistant", - "content": null, - "tool_calls": [ - { - "id": "call_O8NOz8VlxosSASEsOY7LDUcP", - "type": "function", - "function": { - "name": "get_current_weather", - "arguments": "{\"location\": \"Seattle, WA\"}" - } - }, - { - "id": "call_3m7cyuckijnpiWr6tq0Tl8Mg", - "type": "function", - "function": { - "name": "get_current_weather", - "arguments": "{\"location\": \"San Francisco, CA\"}" - } - } - ], - "refusal": null - }, - "logprobs": null, - "finish_reason": "tool_calls" - } - ], - "usage": { - "prompt_tokens": 75, - "completion_tokens": 51, - "total_tokens": 126, - "prompt_tokens_details": { - "cached_tokens": 0, - "audio_tokens": 0 - }, - "completion_tokens_details": { - "reasoning_tokens": 0, - "audio_tokens": 0, - "accepted_prediction_tokens": 0, - "rejected_prediction_tokens": 0 - } - }, - "system_fingerprint": "fp_0ba0d124f1" - } - headers: - CF-Cache-Status: - - DYNAMIC - CF-RAY: - - 8e1a8098ac5ae167-MRS - Connection: - - keep-alive - Content-Type: - - application/json - Date: - - Wed, 13 Nov 2024 00:04:06 GMT - Server: - - cloudflare - Set-Cookie: test_set_cookie - Transfer-Encoding: - - chunked - X-Content-Type-Options: - - nosniff - access-control-expose-headers: - - X-Request-ID - alt-svc: - - h3=":443"; ma=86400 - content-length: - - '1308' - openai-organization: test_openai_org_id - openai-processing-ms: - - '937' - openai-version: - - '2020-10-01' - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-ratelimit-limit-requests: - - '30000' - x-ratelimit-limit-tokens: - - '150000000' - x-ratelimit-remaining-requests: - - '29999' - x-ratelimit-remaining-tokens: - - '149999960' - x-ratelimit-reset-requests: - - 2ms - x-ratelimit-reset-tokens: - - 0s - x-request-id: - - req_3cd7152d2c8c10b4f354b27165f6c2b5 - status: - code: 200 - message: OK -- request: - body: |- - { - "messages": [ - { - "role": "system", - "content": "You're a helpful assistant." - }, - { - "role": "user", - "content": "What's the weather in Seattle and San Francisco today?" - }, - { - "role": "assistant", - "tool_calls": [ - { - "id": "call_O8NOz8VlxosSASEsOY7LDUcP", - "function": { - "arguments": "{\"location\": \"Seattle, WA\"}", - "name": "get_current_weather" - }, - "type": "function" - }, - { - "id": "call_3m7cyuckijnpiWr6tq0Tl8Mg", - "function": { - "arguments": "{\"location\": \"San Francisco, CA\"}", - "name": "get_current_weather" - }, - "type": "function" - } - ] - }, - { - "role": "tool", - "content": "50 degrees and raining", - "tool_call_id": "call_O8NOz8VlxosSASEsOY7LDUcP" - }, - { - "role": "tool", - "content": "70 degrees and sunny", - "tool_call_id": "call_3m7cyuckijnpiWr6tq0Tl8Mg" - } - ], - "model": "gpt-4o-mini" - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - authorization: - - Bearer test_openai_api_key - connection: - - keep-alive - content-length: - - '746' - content-type: - - application/json - cookie: - - test_cookie - host: - - api.openai.com - user-agent: - - AsyncOpenAI/Python 1.26.0 - x-stainless-arch: - - arm64 - x-stainless-async: - - async:asyncio - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 1.26.0 - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.12.5 - method: POST - uri: https://api.openai.com/v1/chat/completions - response: - body: - string: |- - { - "id": "chatcmpl-ASv9aQnGndy04lqKoPRagym1eEaQK", - "object": "chat.completion", - "created": 1731456246, - "model": "gpt-4o-mini-2024-07-18", - "choices": [ - { - "index": 0, - "message": { - "role": "assistant", - "content": "Today, Seattle is experiencing 50 degrees and raining, while San Francisco has a pleasant 70 degrees and sunny weather.", - "refusal": null - }, - "logprobs": null, - "finish_reason": "stop" - } - ], - "usage": { - "prompt_tokens": 99, - "completion_tokens": 24, - "total_tokens": 123, - "prompt_tokens_details": { - "cached_tokens": 0, - "audio_tokens": 0 - }, - "completion_tokens_details": { - "reasoning_tokens": 0, - "audio_tokens": 0, - "accepted_prediction_tokens": 0, - "rejected_prediction_tokens": 0 - } - }, - "system_fingerprint": "fp_f59a81427f" - } - headers: - CF-Cache-Status: - - DYNAMIC - CF-RAY: - - 8e1a80a39c71e167-MRS - Connection: - - keep-alive - Content-Type: - - application/json - Date: - - Wed, 13 Nov 2024 00:04:07 GMT - Server: - - cloudflare - Set-Cookie: test_set_cookie - Transfer-Encoding: - - chunked - X-Content-Type-Options: - - nosniff - access-control-expose-headers: - - X-Request-ID - alt-svc: - - h3=":443"; ma=86400 - content-length: - - '871' - openai-organization: test_openai_org_id - openai-processing-ms: - - '477' - openai-version: - - '2020-10-01' - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-ratelimit-limit-requests: - - '30000' - x-ratelimit-limit-tokens: - - '150000000' - x-ratelimit-remaining-requests: - - '29999' - x-ratelimit-remaining-tokens: - - '149999948' - x-ratelimit-reset-requests: - - 2ms - x-ratelimit-reset-tokens: - - 0s - x-request-id: - - req_193c74758ea30e77e55afe931e89fd6c - status: - code: 200 - message: OK -version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_with_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_with_content.yaml deleted file mode 100644 index 61ec4a646e..0000000000 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_async_chat_completion_with_content.yaml +++ /dev/null @@ -1,132 +0,0 @@ -interactions: -- request: - body: |- - { - "messages": [ - { - "role": "user", - "content": "Say this is a test" - } - ], - "model": "gpt-4o-mini", - "stream": false - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - authorization: - - Bearer test_openai_api_key - connection: - - keep-alive - content-length: - - '106' - content-type: - - application/json - host: - - api.openai.com - user-agent: - - AsyncOpenAI/Python 1.26.0 - x-stainless-arch: - - arm64 - x-stainless-async: - - async:asyncio - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 1.26.0 - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.12.5 - method: POST - uri: https://api.openai.com/v1/chat/completions - response: - body: - string: |- - { - "id": "chatcmpl-ASv9R2E7Yhb2e7bj4Xl0qm9s3J42Y", - "object": "chat.completion", - "created": 1731456237, - "model": "gpt-4o-mini-2024-07-18", - "choices": [ - { - "index": 0, - "message": { - "role": "assistant", - "content": "This is a test. How can I assist you further?", - "refusal": null - }, - "logprobs": null, - "finish_reason": "stop" - } - ], - "usage": { - "prompt_tokens": 12, - "completion_tokens": 12, - "total_tokens": 24, - "prompt_tokens_details": { - "cached_tokens": 0, - "audio_tokens": 0 - }, - "completion_tokens_details": { - "reasoning_tokens": 0, - "audio_tokens": 0, - "accepted_prediction_tokens": 0, - "rejected_prediction_tokens": 0 - } - }, - "system_fingerprint": "fp_0ba0d124f1" - } - headers: - CF-Cache-Status: - - DYNAMIC - CF-RAY: - - 8e1a80679a8311a6-MRS - Connection: - - keep-alive - Content-Type: - - application/json - Date: - - Wed, 13 Nov 2024 00:03:58 GMT - Server: - - cloudflare - Set-Cookie: test_set_cookie - Transfer-Encoding: - - chunked - X-Content-Type-Options: - - nosniff - access-control-expose-headers: - - X-Request-ID - alt-svc: - - h3=":443"; ma=86400 - content-length: - - '796' - openai-organization: test_openai_org_id - openai-processing-ms: - - '359' - openai-version: - - '2020-10-01' - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-ratelimit-limit-requests: - - '30000' - x-ratelimit-limit-tokens: - - '150000000' - x-ratelimit-remaining-requests: - - '29999' - x-ratelimit-remaining-tokens: - - '149999978' - x-ratelimit-reset-requests: - - 2ms - x-ratelimit-reset-tokens: - - 0s - x-request-id: - - req_41ea134c1fc450d4ca4cf8d0c6a7c53a - status: - code: 200 - message: OK -version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_404.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_404.yaml deleted file mode 100644 index fb713363d5..0000000000 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_404.yaml +++ /dev/null @@ -1,91 +0,0 @@ -interactions: -- request: - body: |- - { - "messages": [ - { - "role": "user", - "content": "Say this is a test" - } - ], - "model": "this-model-does-not-exist" - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - authorization: - - Bearer test_openai_api_key - connection: - - keep-alive - content-length: - - '103' - content-type: - - application/json - host: - - api.openai.com - user-agent: - - OpenAI/Python 1.54.3 - x-stainless-arch: - - arm64 - x-stainless-async: - - 'false' - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 1.54.3 - x-stainless-retry-count: - - '0' - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.12.6 - method: POST - uri: https://api.openai.com/v1/chat/completions - response: - body: - string: |- - { - "error": { - "message": "The model `this-model-does-not-exist` does not exist or you do not have access to it.", - "type": "invalid_request_error", - "param": null, - "code": "model_not_found" - } - } - headers: - CF-Cache-Status: - - DYNAMIC - CF-RAY: - - 8e1225a16c283d93-SIN - Connection: - - keep-alive - Content-Type: - - application/json; charset=utf-8 - Date: - - Mon, 11 Nov 2024 23:43:52 GMT - Server: - - cloudflare - Set-Cookie: test_set_cookie - Transfer-Encoding: - - chunked - X-Content-Type-Options: - - nosniff - alt-svc: - - h3=":443"; ma=86400 - content-length: - - '231' - openai-organization: test_openai_org_id - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - vary: - - Origin - x-request-id: - - req_c3e0f92d7b5426d1a4a17bb3d39953ea - status: - code: 404 - message: Not Found -version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_extra_params.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_extra_params.yaml deleted file mode 100644 index 7cc89ad9b8..0000000000 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_extra_params.yaml +++ /dev/null @@ -1,139 +0,0 @@ -interactions: -- request: - body: |- - { - "messages": [ - { - "role": "user", - "content": "Say this is a test" - } - ], - "model": "gpt-4o-mini", - "max_tokens": 50, - "seed": 42, - "stream": false, - "temperature": 0.5, - "service_tier": "default" - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - authorization: - - Bearer test_openai_api_key - connection: - - keep-alive - content-length: - - '183' - content-type: - - application/json - host: - - api.openai.com - user-agent: - - OpenAI/Python 1.54.3 - x-stainless-arch: - - arm64 - x-stainless-async: - - 'false' - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 1.54.3 - x-stainless-retry-count: - - '0' - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.12.6 - method: POST - uri: https://api.openai.com/v1/chat/completions - response: - body: - string: |- - { - "id": "chatcmpl-ASYMT7913Sp58qhZqQgY7g7Ia2J4M", - "object": "chat.completion", - "created": 1731368633, - "model": "gpt-4o-mini-2024-07-18", - "choices": [ - { - "index": 0, - "message": { - "role": "assistant", - "content": "This is a test. How can I assist you further?", - "refusal": null - }, - "logprobs": null, - "finish_reason": "stop" - } - ], - "usage": { - "prompt_tokens": 12, - "completion_tokens": 12, - "total_tokens": 24, - "prompt_tokens_details": { - "cached_tokens": 0, - "audio_tokens": 0 - }, - "completion_tokens_details": { - "reasoning_tokens": 0, - "audio_tokens": 0, - "accepted_prediction_tokens": 0, - "rejected_prediction_tokens": 0 - } - }, - "service_tier": "default", - "system_fingerprint": "fp_0ba0d124f1" - } - headers: - CF-Cache-Status: - - DYNAMIC - CF-RAY: - - 8e1225a3f8e9ce65-SIN - Connection: - - keep-alive - Content-Type: - - application/json - Date: - - Mon, 11 Nov 2024 23:43:53 GMT - Server: - - cloudflare - Set-Cookie: test_set_cookie - Transfer-Encoding: - - chunked - X-Content-Type-Options: - - nosniff - access-control-expose-headers: - - X-Request-ID - alt-svc: - - h3=":443"; ma=86400 - content-length: - - '825' - openai-organization: test_openai_org_id - openai-processing-ms: - - '431' - openai-version: - - '2020-10-01' - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-ratelimit-limit-requests: - - '10000' - x-ratelimit-limit-tokens: - - '200000' - x-ratelimit-remaining-requests: - - '9998' - x-ratelimit-remaining-tokens: - - '199943' - x-ratelimit-reset-requests: - - 14.746s - x-ratelimit-reset-tokens: - - 16ms - x-request-id: - - req_81e29a8992ea8001c0240bd990acf0ab - status: - code: 200 - message: OK -version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_multiple_choices.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_multiple_choices.yaml deleted file mode 100644 index 23828e98f4..0000000000 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_multiple_choices.yaml +++ /dev/null @@ -1,145 +0,0 @@ -interactions: -- request: - body: |- - { - "messages": [ - { - "role": "user", - "content": "Say this is a test" - } - ], - "model": "gpt-4o-mini", - "n": 2, - "stream": false - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - authorization: - - Bearer test_openai_api_key - connection: - - keep-alive - content-length: - - '114' - content-type: - - application/json - host: - - api.openai.com - user-agent: - - OpenAI/Python 1.54.3 - x-stainless-arch: - - arm64 - x-stainless-async: - - 'false' - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 1.54.3 - x-stainless-retry-count: - - '0' - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.12.6 - method: POST - uri: https://api.openai.com/v1/chat/completions - response: - body: - string: |- - { - "id": "chatcmpl-ASYMUBq69UHDarAz2fsd0O50rv0r1", - "object": "chat.completion", - "created": 1731368634, - "model": "gpt-4o-mini-2024-07-18", - "choices": [ - { - "index": 0, - "message": { - "role": "assistant", - "content": "This is a test. How can I assist you further?", - "refusal": null - }, - "logprobs": null, - "finish_reason": "stop" - }, - { - "index": 1, - "message": { - "role": "assistant", - "content": "This is a test. How can I assist you further?", - "refusal": null - }, - "logprobs": null, - "finish_reason": "stop" - } - ], - "usage": { - "prompt_tokens": 12, - "completion_tokens": 24, - "total_tokens": 36, - "prompt_tokens_details": { - "cached_tokens": 0, - "audio_tokens": 0 - }, - "completion_tokens_details": { - "reasoning_tokens": 0, - "audio_tokens": 0, - "accepted_prediction_tokens": 0, - "rejected_prediction_tokens": 0 - } - }, - "system_fingerprint": "fp_0ba0d124f1" - } - headers: - CF-Cache-Status: - - DYNAMIC - CF-RAY: - - 8e1225a91a253e53-SIN - Connection: - - keep-alive - Content-Type: - - application/json - Date: - - Mon, 11 Nov 2024 23:43:54 GMT - Server: - - cloudflare - Set-Cookie: test_set_cookie - Transfer-Encoding: - - chunked - X-Content-Type-Options: - - nosniff - access-control-expose-headers: - - X-Request-ID - alt-svc: - - h3=":443"; ma=86400 - content-length: - - '1030' - openai-organization: test_openai_org_id - openai-processing-ms: - - '399' - openai-version: - - '2020-10-01' - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-ratelimit-limit-requests: - - '10000' - x-ratelimit-limit-tokens: - - '200000' - x-ratelimit-remaining-requests: - - '9997' - x-ratelimit-remaining-tokens: - - '199962' - x-ratelimit-reset-requests: - - 22.564s - x-ratelimit-reset-tokens: - - 11ms - x-request-id: - - req_01290a92a1a3d787c7a00bb3836da597 - status: - code: 200 - message: OK -version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_multiple_choices_streaming.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_multiple_choices_streaming.yaml deleted file mode 100644 index ea06ca5984..0000000000 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_multiple_choices_streaming.yaml +++ /dev/null @@ -1,326 +0,0 @@ -interactions: -- request: - body: |- - { - "messages": [ - { - "role": "system", - "content": "You're a helpful assistant." - }, - { - "role": "user", - "content": "What's the weather in Seattle and San Francisco today?" - } - ], - "model": "gpt-4o-mini", - "n": 2, - "stream": true, - "stream_options": { - "include_usage": true - } - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - authorization: - - Bearer test_openai_api_key - connection: - - keep-alive - content-length: - - '254' - content-type: - - application/json - host: - - api.openai.com - user-agent: - - OpenAI/Python 1.54.3 - x-stainless-arch: - - arm64 - x-stainless-async: - - 'false' - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 1.54.3 - x-stainless-retry-count: - - '0' - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.12.6 - method: POST - uri: https://api.openai.com/v1/chat/completions - response: - body: - string: |+ - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"I'm"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"I'm"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" unable"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" unable"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" provide"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" provide"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" real"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" real"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"-time"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"-time"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" updates"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" updates"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" as"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" To"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" my"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" get"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" capabilities"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" do"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" latest"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" not"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" include"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" information"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" accessing"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" for"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" live"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" Seattle"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" data"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" San"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" However"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" Francisco"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" you"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" I"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" can"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" recommend"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" easily"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" checking"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" check"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" reliable"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" current"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" website"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" in"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" or"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" Seattle"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" using"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" and"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" San"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" Francisco"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" app"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" using"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" You"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" can"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" also"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" website"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" ask"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" app"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":","},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" voice"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" or"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" assistant"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" service"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" or"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" search"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" Would"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" online"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" you"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" for"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" like"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" the"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" some"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" current"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" tips"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" weather"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" on"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":" conditions"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" where"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" to"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" find"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" this"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":" information"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{"content":"?"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[{"index":1,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null} - - data: {"id":"chatcmpl-ASYMaNc7XmbGRUNREnmvhyyISBHsv","object":"chat.completion.chunk","created":1731368640,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_0ba0d124f1","choices":[],"usage":{"prompt_tokens":26,"completion_tokens":104,"total_tokens":130,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}}} - - data: [DONE] - - headers: - CF-Cache-Status: - - DYNAMIC - CF-RAY: - - 8e1225d0fa1481e4-SIN - Connection: - - keep-alive - Content-Type: - - text/event-stream; charset=utf-8 - Date: - - Mon, 11 Nov 2024 23:44:00 GMT - Server: - - cloudflare - Set-Cookie: test_set_cookie - Transfer-Encoding: - - chunked - X-Content-Type-Options: - - nosniff - access-control-expose-headers: - - X-Request-ID - alt-svc: - - h3=":443"; ma=86400 - openai-organization: test_openai_org_id - openai-processing-ms: - - '176' - openai-version: - - '2020-10-01' - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-ratelimit-limit-requests: - - '10000' - x-ratelimit-limit-tokens: - - '200000' - x-ratelimit-remaining-requests: - - '9993' - x-ratelimit-remaining-tokens: - - '199945' - x-ratelimit-reset-requests: - - 59.369s - x-ratelimit-reset-tokens: - - 16ms - x-request-id: - - req_892a6021b1acc00254d8ff80adcd82fb - status: - code: 200 - message: OK -version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_no_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_no_content.yaml deleted file mode 100644 index 951aa52259..0000000000 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_no_content.yaml +++ /dev/null @@ -1,166 +0,0 @@ -interactions: -- request: - body: |- - { - "messages": [ - { - "role": "system", - "content": "You're a helpful assistant." - }, - { - "role": "user", - "content": "What's the weather in Seattle and San Francisco today?" - } - ], - "model": "gpt-4o-mini", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "type": "function", - "function": { - "name": "get_current_weather", - "description": "Get the current weather in a given location", - "parameters": { - "type": "object", - "properties": { - "location": { - "type": "string", - "description": "The city and state, e.g. Boston, MA" - } - }, - "required": [ - "location" - ], - "additionalProperties": false - } - } - } - ] - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - authorization: - - Bearer test_openai_api_key - connection: - - keep-alive - content-length: - - '602' - content-type: - - application/json - host: - - api.openai.com - user-agent: - - OpenAI/Python 1.54.3 - x-stainless-arch: - - arm64 - x-stainless-async: - - 'false' - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 1.54.3 - x-stainless-retry-count: - - '0' - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.12.6 - method: POST - uri: https://api.openai.com/v1/chat/completions - response: - body: - string: |+ - data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"role":"assistant","content":null},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_j7L00WV19wwQCvKOIVZewXZm","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n\": \"S"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"eatt"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"le, W"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"id":"call_sAIOI3dvcd1YMsEqD8DI3l8B","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"n\": \"S"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"an F"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"ranci"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"sco, C"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"tool_calls"}],"usage":null} - - data: {"id":"chatcmpl-ASYMdbuQwnGMCODejEnbp2ufs6WgR","object":"chat.completion.chunk","created":1731368643,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","choices":[],"usage":{"prompt_tokens":75,"completion_tokens":51,"total_tokens":126,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}}} - - data: [DONE] - - headers: - CF-Cache-Status: - - DYNAMIC - CF-RAY: - - 8e1225e40bed40c8-SIN - Connection: - - keep-alive - Content-Type: - - text/event-stream; charset=utf-8 - Date: - - Mon, 11 Nov 2024 23:44:04 GMT - Server: - - cloudflare - Set-Cookie: test_set_cookie - Transfer-Encoding: - - chunked - X-Content-Type-Options: - - nosniff - access-control-expose-headers: - - X-Request-ID - alt-svc: - - h3=":443"; ma=86400 - openai-organization: test_openai_org_id - openai-processing-ms: - - '1225' - openai-version: - - '2020-10-01' - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-ratelimit-limit-requests: - - '10000' - x-ratelimit-limit-tokens: - - '200000' - x-ratelimit-remaining-requests: - - '9991' - x-ratelimit-remaining-tokens: - - '199961' - x-ratelimit-reset-requests: - - 1m13.588s - x-ratelimit-reset-tokens: - - 11ms - x-request-id: - - req_102cd878d03c1cec0c12b95f928d03ee - status: - code: 200 - message: OK -version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_with_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_with_content.yaml deleted file mode 100644 index d42ac86e37..0000000000 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_multiple_tools_streaming_with_content.yaml +++ /dev/null @@ -1,166 +0,0 @@ -interactions: -- request: - body: |- - { - "messages": [ - { - "role": "system", - "content": "You're a helpful assistant." - }, - { - "role": "user", - "content": "What's the weather in Seattle and San Francisco today?" - } - ], - "model": "gpt-4o-mini", - "stream": true, - "stream_options": { - "include_usage": true - }, - "tool_choice": "auto", - "tools": [ - { - "type": "function", - "function": { - "name": "get_current_weather", - "description": "Get the current weather in a given location", - "parameters": { - "type": "object", - "properties": { - "location": { - "type": "string", - "description": "The city and state, e.g. Boston, MA" - } - }, - "required": [ - "location" - ], - "additionalProperties": false - } - } - } - ] - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - authorization: - - Bearer test_openai_api_key - connection: - - keep-alive - content-length: - - '602' - content-type: - - application/json - host: - - api.openai.com - user-agent: - - OpenAI/Python 1.54.3 - x-stainless-arch: - - arm64 - x-stainless-async: - - 'false' - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 1.54.3 - x-stainless-retry-count: - - '0' - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.12.6 - method: POST - uri: https://api.openai.com/v1/chat/completions - response: - body: - string: |+ - data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"role":"assistant","content":null},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_fHCjJqt9Pysde6vcJcvbXGBx","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"n\": \"S"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"eatt"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"le, W"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"id":"call_3J9foSw3CUb48lrqIXoTky6U","type":"function","function":{"name":"get_current_weather","arguments":""}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"{\"lo"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"catio"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"n\": \"S"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"an F"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"ranci"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"sco, C"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","usage":null,"choices":[{"index":0,"delta":{"tool_calls":[{"index":1,"function":{"arguments":"A\"}"}}]},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"tool_calls"}],"usage":null} - - data: {"id":"chatcmpl-ASYMbACebDoWcuraMEWQhU48q4dAp","object":"chat.completion.chunk","created":1731368641,"model":"gpt-4o-mini-2024-07-18","system_fingerprint":"fp_9b78b61c52","choices":[],"usage":{"prompt_tokens":75,"completion_tokens":51,"total_tokens":126,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}}} - - data: [DONE] - - headers: - CF-Cache-Status: - - DYNAMIC - CF-RAY: - - 8e1225d8af0c3d93-SIN - Connection: - - keep-alive - Content-Type: - - text/event-stream; charset=utf-8 - Date: - - Mon, 11 Nov 2024 23:44:03 GMT - Server: - - cloudflare - Set-Cookie: test_set_cookie - Transfer-Encoding: - - chunked - X-Content-Type-Options: - - nosniff - access-control-expose-headers: - - X-Request-ID - alt-svc: - - h3=":443"; ma=86400 - openai-organization: test_openai_org_id - openai-processing-ms: - - '1399' - openai-version: - - '2020-10-01' - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-ratelimit-limit-requests: - - '10000' - x-ratelimit-limit-tokens: - - '200000' - x-ratelimit-remaining-requests: - - '9992' - x-ratelimit-remaining-tokens: - - '199961' - x-ratelimit-reset-requests: - - 1m6.779s - x-ratelimit-reset-tokens: - - 11ms - x-request-id: - - req_d745d48bf030ac78e4790ee49848d05f - status: - code: 200 - message: OK -version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_streaming.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_streaming.yaml deleted file mode 100644 index db482a440c..0000000000 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_streaming.yaml +++ /dev/null @@ -1,119 +0,0 @@ -interactions: -- request: - body: |- - { - "messages": [ - { - "role": "user", - "content": "Say this is a test" - } - ], - "model": "gpt-4", - "stream": true, - "stream_options": { - "include_usage": true - } - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - authorization: - - Bearer test_openai_api_key - connection: - - keep-alive - content-length: - - '142' - content-type: - - application/json - host: - - api.openai.com - user-agent: - - OpenAI/Python 1.54.3 - x-stainless-arch: - - arm64 - x-stainless-async: - - 'false' - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 1.54.3 - x-stainless-retry-count: - - '0' - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.12.6 - method: POST - uri: https://api.openai.com/v1/chat/completions - response: - body: - string: |+ - data: {"id":"chatcmpl-ASYMZ4oSykiIFK4lXLReDiKyAjsQl","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMZ4oSykiIFK4lXLReDiKyAjsQl","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\"This"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMZ4oSykiIFK4lXLReDiKyAjsQl","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" is"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMZ4oSykiIFK4lXLReDiKyAjsQl","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMZ4oSykiIFK4lXLReDiKyAjsQl","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" test"},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMZ4oSykiIFK4lXLReDiKyAjsQl","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":".\""},"logprobs":null,"finish_reason":null}],"usage":null} - - data: {"id":"chatcmpl-ASYMZ4oSykiIFK4lXLReDiKyAjsQl","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":null} - - data: {"id":"chatcmpl-ASYMZ4oSykiIFK4lXLReDiKyAjsQl","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[],"usage":{"prompt_tokens":12,"completion_tokens":5,"total_tokens":17,"prompt_tokens_details":{"cached_tokens":0,"audio_tokens":0},"completion_tokens_details":{"reasoning_tokens":0,"audio_tokens":0,"accepted_prediction_tokens":0,"rejected_prediction_tokens":0}}} - - data: [DONE] - - headers: - CF-Cache-Status: - - DYNAMIC - CF-RAY: - - 8e1225c87b273e53-SIN - Connection: - - keep-alive - Content-Type: - - text/event-stream; charset=utf-8 - Date: - - Mon, 11 Nov 2024 23:43:59 GMT - Server: - - cloudflare - Set-Cookie: test_set_cookie - Transfer-Encoding: - - chunked - X-Content-Type-Options: - - nosniff - access-control-expose-headers: - - X-Request-ID - alt-svc: - - h3=":443"; ma=86400 - openai-organization: test_openai_org_id - openai-processing-ms: - - '207' - openai-version: - - '2020-10-01' - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-ratelimit-limit-requests: - - '10000' - x-ratelimit-limit-tokens: - - '10000' - x-ratelimit-remaining-requests: - - '9999' - x-ratelimit-remaining-tokens: - - '9978' - x-ratelimit-reset-requests: - - 8.64s - x-ratelimit-reset-tokens: - - 132ms - x-request-id: - - req_c367cf360ee88481fb7cd6c5d45bf9dc - status: - code: 200 - message: OK -version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_streaming_not_complete.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_streaming_not_complete.yaml deleted file mode 100644 index 4d56e51a06..0000000000 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_streaming_not_complete.yaml +++ /dev/null @@ -1,114 +0,0 @@ -interactions: -- request: - body: |- - { - "messages": [ - { - "role": "user", - "content": "Say this is a test" - } - ], - "model": "gpt-4", - "stream": true - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - authorization: - - Bearer test_openai_api_key - connection: - - keep-alive - content-length: - - '99' - content-type: - - application/json - host: - - api.openai.com - user-agent: - - OpenAI/Python 1.54.3 - x-stainless-arch: - - arm64 - x-stainless-async: - - 'false' - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 1.54.3 - x-stainless-retry-count: - - '0' - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.12.6 - method: POST - uri: https://api.openai.com/v1/chat/completions - response: - body: - string: |+ - data: {"id":"chatcmpl-ASYMZbRqo8Bkz53FVzaTj7W7feOn4","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":"","refusal":null},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASYMZbRqo8Bkz53FVzaTj7W7feOn4","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"This"},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASYMZbRqo8Bkz53FVzaTj7W7feOn4","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" is"},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASYMZbRqo8Bkz53FVzaTj7W7feOn4","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" a"},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASYMZbRqo8Bkz53FVzaTj7W7feOn4","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":" test"},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASYMZbRqo8Bkz53FVzaTj7W7feOn4","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}]} - - data: {"id":"chatcmpl-ASYMZbRqo8Bkz53FVzaTj7W7feOn4","object":"chat.completion.chunk","created":1731368639,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]} - - data: [DONE] - - headers: - CF-Cache-Status: - - DYNAMIC - CF-RAY: - - 8e1225ccb98e823b-SIN - Connection: - - keep-alive - Content-Type: - - text/event-stream; charset=utf-8 - Date: - - Mon, 11 Nov 2024 23:43:59 GMT - Server: - - cloudflare - Set-Cookie: test_set_cookie - Transfer-Encoding: - - chunked - X-Content-Type-Options: - - nosniff - access-control-expose-headers: - - X-Request-ID - alt-svc: - - h3=":443"; ma=86400 - openai-organization: test_openai_org_id - openai-processing-ms: - - '205' - openai-version: - - '2020-10-01' - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-ratelimit-limit-requests: - - '10000' - x-ratelimit-limit-tokens: - - '10000' - x-ratelimit-remaining-requests: - - '9998' - x-ratelimit-remaining-tokens: - - '9978' - x-ratelimit-reset-requests: - - 16.601s - x-ratelimit-reset-tokens: - - 132ms - x-request-id: - - req_d13225164a822ec3ebab5591ed0b6d6a - status: - code: 200 - message: OK -version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_tool_calls_no_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_tool_calls_no_content.yaml deleted file mode 100644 index 4731f202c3..0000000000 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_tool_calls_no_content.yaml +++ /dev/null @@ -1,346 +0,0 @@ -interactions: -- request: - body: |- - { - "messages": [ - { - "role": "system", - "content": "You're a helpful assistant." - }, - { - "role": "user", - "content": "What's the weather in Seattle and San Francisco today?" - } - ], - "model": "gpt-4o-mini", - "tool_choice": "auto", - "tools": [ - { - "type": "function", - "function": { - "name": "get_current_weather", - "description": "Get the current weather in a given location", - "parameters": { - "type": "object", - "properties": { - "location": { - "type": "string", - "description": "The city and state, e.g. Boston, MA" - } - }, - "required": [ - "location" - ], - "additionalProperties": false - } - } - } - ] - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - authorization: - - Bearer test_openai_api_key - connection: - - keep-alive - content-length: - - '543' - content-type: - - application/json - host: - - api.openai.com - user-agent: - - OpenAI/Python 1.54.3 - x-stainless-arch: - - arm64 - x-stainless-async: - - 'false' - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 1.54.3 - x-stainless-retry-count: - - '0' - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.12.6 - method: POST - uri: https://api.openai.com/v1/chat/completions - response: - body: - string: |- - { - "id": "chatcmpl-ASYMW6w3m9qqpHUVhYTbQbw61zMqA", - "object": "chat.completion", - "created": 1731368636, - "model": "gpt-4o-mini-2024-07-18", - "choices": [ - { - "index": 0, - "message": { - "role": "assistant", - "content": null, - "tool_calls": [ - { - "id": "call_eqbDFUdPqay2WjsSzZEiAn0U", - "type": "function", - "function": { - "name": "get_current_weather", - "arguments": "{\"location\": \"Seattle, WA\"}" - } - }, - { - "id": "call_tn3sgasg6GaftTdancBYJNJN", - "type": "function", - "function": { - "name": "get_current_weather", - "arguments": "{\"location\": \"San Francisco, CA\"}" - } - } - ], - "refusal": null - }, - "logprobs": null, - "finish_reason": "tool_calls" - } - ], - "usage": { - "prompt_tokens": 75, - "completion_tokens": 51, - "total_tokens": 126, - "prompt_tokens_details": { - "cached_tokens": 0, - "audio_tokens": 0 - }, - "completion_tokens_details": { - "reasoning_tokens": 0, - "audio_tokens": 0, - "accepted_prediction_tokens": 0, - "rejected_prediction_tokens": 0 - } - }, - "system_fingerprint": "fp_0ba0d124f1" - } - headers: - CF-Cache-Status: - - DYNAMIC - CF-RAY: - - 8e1225ba6a3440b0-SIN - Connection: - - keep-alive - Content-Type: - - application/json - Date: - - Mon, 11 Nov 2024 23:43:57 GMT - Server: - - cloudflare - Set-Cookie: test_set_cookie - Transfer-Encoding: - - chunked - X-Content-Type-Options: - - nosniff - access-control-expose-headers: - - X-Request-ID - alt-svc: - - h3=":443"; ma=86400 - content-length: - - '1308' - openai-organization: test_openai_org_id - openai-processing-ms: - - '761' - openai-version: - - '2020-10-01' - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-ratelimit-limit-requests: - - '10000' - x-ratelimit-limit-tokens: - - '200000' - x-ratelimit-remaining-requests: - - '9994' - x-ratelimit-remaining-tokens: - - '199961' - x-ratelimit-reset-requests: - - 45.694s - x-ratelimit-reset-tokens: - - 11ms - x-request-id: - - req_f98710550c77b43865572fc1a7a0bc53 - status: - code: 200 - message: OK -- request: - body: |- - { - "messages": [ - { - "role": "system", - "content": "You're a helpful assistant." - }, - { - "role": "user", - "content": "What's the weather in Seattle and San Francisco today?" - }, - { - "role": "assistant", - "tool_calls": [ - { - "id": "call_eqbDFUdPqay2WjsSzZEiAn0U", - "function": { - "arguments": "{\"location\": \"Seattle, WA\"}", - "name": "get_current_weather" - }, - "type": "function" - }, - { - "id": "call_tn3sgasg6GaftTdancBYJNJN", - "function": { - "arguments": "{\"location\": \"San Francisco, CA\"}", - "name": "get_current_weather" - }, - "type": "function" - } - ] - }, - { - "role": "tool", - "content": "50 degrees and raining", - "tool_call_id": "call_eqbDFUdPqay2WjsSzZEiAn0U" - }, - { - "role": "tool", - "content": "70 degrees and sunny", - "tool_call_id": "call_tn3sgasg6GaftTdancBYJNJN" - } - ], - "model": "gpt-4o-mini" - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - authorization: - - Bearer test_openai_api_key - connection: - - keep-alive - content-length: - - '746' - content-type: - - application/json - cookie: - - test_cookie - host: - - api.openai.com - user-agent: - - OpenAI/Python 1.54.3 - x-stainless-arch: - - arm64 - x-stainless-async: - - 'false' - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 1.54.3 - x-stainless-retry-count: - - '0' - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.12.6 - method: POST - uri: https://api.openai.com/v1/chat/completions - response: - body: - string: |- - { - "id": "chatcmpl-ASYMYObbcUyZ77rbvypWmcZPIVSf1", - "object": "chat.completion", - "created": 1731368638, - "model": "gpt-4o-mini-2024-07-18", - "choices": [ - { - "index": 0, - "message": { - "role": "assistant", - "content": "Today, the weather in Seattle is 50 degrees and raining, while San Francisco is enjoying 70 degrees and sunny weather.", - "refusal": null - }, - "logprobs": null, - "finish_reason": "stop" - } - ], - "usage": { - "prompt_tokens": 99, - "completion_tokens": 25, - "total_tokens": 124, - "prompt_tokens_details": { - "cached_tokens": 0, - "audio_tokens": 0 - }, - "completion_tokens_details": { - "reasoning_tokens": 0, - "audio_tokens": 0, - "accepted_prediction_tokens": 0, - "rejected_prediction_tokens": 0 - } - }, - "system_fingerprint": "fp_0ba0d124f1" - } - headers: - CF-Cache-Status: - - DYNAMIC - CF-RAY: - - 8e1225c12f6340b0-SIN - Connection: - - keep-alive - Content-Type: - - application/json - Date: - - Mon, 11 Nov 2024 23:43:58 GMT - Server: - - cloudflare - Set-Cookie: test_set_cookie - Transfer-Encoding: - - chunked - X-Content-Type-Options: - - nosniff - access-control-expose-headers: - - X-Request-ID - alt-svc: - - h3=":443"; ma=86400 - content-length: - - '870' - openai-organization: test_openai_org_id - openai-processing-ms: - - '722' - openai-version: - - '2020-10-01' - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-ratelimit-limit-requests: - - '10000' - x-ratelimit-limit-tokens: - - '200000' - x-ratelimit-remaining-requests: - - '9993' - x-ratelimit-remaining-tokens: - - '199948' - x-ratelimit-reset-requests: - - 53.254s - x-ratelimit-reset-tokens: - - 15ms - x-request-id: - - req_2bb3d10a2a75f5d64a24aef595a0d8dd - status: - code: 200 - message: OK -version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_tool_calls_with_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_tool_calls_with_content.yaml deleted file mode 100644 index 6ceb618d24..0000000000 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_tool_calls_with_content.yaml +++ /dev/null @@ -1,346 +0,0 @@ -interactions: -- request: - body: |- - { - "messages": [ - { - "role": "system", - "content": "You're a helpful assistant." - }, - { - "role": "user", - "content": "What's the weather in Seattle and San Francisco today?" - } - ], - "model": "gpt-4o-mini", - "tool_choice": "auto", - "tools": [ - { - "type": "function", - "function": { - "name": "get_current_weather", - "description": "Get the current weather in a given location", - "parameters": { - "type": "object", - "properties": { - "location": { - "type": "string", - "description": "The city and state, e.g. Boston, MA" - } - }, - "required": [ - "location" - ], - "additionalProperties": false - } - } - } - ] - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - authorization: - - Bearer test_openai_api_key - connection: - - keep-alive - content-length: - - '543' - content-type: - - application/json - host: - - api.openai.com - user-agent: - - OpenAI/Python 1.54.3 - x-stainless-arch: - - arm64 - x-stainless-async: - - 'false' - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 1.54.3 - x-stainless-retry-count: - - '0' - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.12.6 - method: POST - uri: https://api.openai.com/v1/chat/completions - response: - body: - string: |- - { - "id": "chatcmpl-ASYMU9Ntix7ePttk0MSuerJstef6U", - "object": "chat.completion", - "created": 1731368634, - "model": "gpt-4o-mini-2024-07-18", - "choices": [ - { - "index": 0, - "message": { - "role": "assistant", - "content": null, - "tool_calls": [ - { - "id": "call_JpNb8OiAkbIbHzDggfpdDHpi", - "type": "function", - "function": { - "name": "get_current_weather", - "arguments": "{\"location\": \"Seattle, WA\"}" - } - }, - { - "id": "call_vaFQc3zK6hHTRZKXRI5Eo2cJ", - "type": "function", - "function": { - "name": "get_current_weather", - "arguments": "{\"location\": \"San Francisco, CA\"}" - } - } - ], - "refusal": null - }, - "logprobs": null, - "finish_reason": "tool_calls" - } - ], - "usage": { - "prompt_tokens": 75, - "completion_tokens": 51, - "total_tokens": 126, - "prompt_tokens_details": { - "cached_tokens": 0, - "audio_tokens": 0 - }, - "completion_tokens_details": { - "reasoning_tokens": 0, - "audio_tokens": 0, - "accepted_prediction_tokens": 0, - "rejected_prediction_tokens": 0 - } - }, - "system_fingerprint": "fp_0ba0d124f1" - } - headers: - CF-Cache-Status: - - DYNAMIC - CF-RAY: - - 8e1225ae3ea281e4-SIN - Connection: - - keep-alive - Content-Type: - - application/json - Date: - - Mon, 11 Nov 2024 23:43:55 GMT - Server: - - cloudflare - Set-Cookie: test_set_cookie - Transfer-Encoding: - - chunked - X-Content-Type-Options: - - nosniff - access-control-expose-headers: - - X-Request-ID - alt-svc: - - h3=":443"; ma=86400 - content-length: - - '1308' - openai-organization: test_openai_org_id - openai-processing-ms: - - '748' - openai-version: - - '2020-10-01' - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-ratelimit-limit-requests: - - '10000' - x-ratelimit-limit-tokens: - - '200000' - x-ratelimit-remaining-requests: - - '9996' - x-ratelimit-remaining-tokens: - - '199961' - x-ratelimit-reset-requests: - - 30.375s - x-ratelimit-reset-tokens: - - 11ms - x-request-id: - - req_a0c3b432eb349a35b6d8dde6e01451e4 - status: - code: 200 - message: OK -- request: - body: |- - { - "messages": [ - { - "role": "system", - "content": "You're a helpful assistant." - }, - { - "role": "user", - "content": "What's the weather in Seattle and San Francisco today?" - }, - { - "role": "assistant", - "tool_calls": [ - { - "id": "call_JpNb8OiAkbIbHzDggfpdDHpi", - "function": { - "arguments": "{\"location\": \"Seattle, WA\"}", - "name": "get_current_weather" - }, - "type": "function" - }, - { - "id": "call_vaFQc3zK6hHTRZKXRI5Eo2cJ", - "function": { - "arguments": "{\"location\": \"San Francisco, CA\"}", - "name": "get_current_weather" - }, - "type": "function" - } - ] - }, - { - "role": "tool", - "content": "50 degrees and raining", - "tool_call_id": "call_JpNb8OiAkbIbHzDggfpdDHpi" - }, - { - "role": "tool", - "content": "70 degrees and sunny", - "tool_call_id": "call_vaFQc3zK6hHTRZKXRI5Eo2cJ" - } - ], - "model": "gpt-4o-mini" - } - headers: - accept: - - application/json - accept-encoding: - - gzip, deflate - authorization: - - Bearer test_openai_api_key - connection: - - keep-alive - content-length: - - '746' - content-type: - - application/json - cookie: - - test_cookie - host: - - api.openai.com - user-agent: - - OpenAI/Python 1.54.3 - x-stainless-arch: - - arm64 - x-stainless-async: - - 'false' - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 1.54.3 - x-stainless-retry-count: - - '0' - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.12.6 - method: POST - uri: https://api.openai.com/v1/chat/completions - response: - body: - string: |- - { - "id": "chatcmpl-ASYMVzdmBGDbUoHFmt6R16tdtZUzR", - "object": "chat.completion", - "created": 1731368635, - "model": "gpt-4o-mini-2024-07-18", - "choices": [ - { - "index": 0, - "message": { - "role": "assistant", - "content": "Today, the weather in Seattle is 50 degrees and raining, while in San Francisco, it's 70 degrees and sunny.", - "refusal": null - }, - "logprobs": null, - "finish_reason": "stop" - } - ], - "usage": { - "prompt_tokens": 99, - "completion_tokens": 25, - "total_tokens": 124, - "prompt_tokens_details": { - "cached_tokens": 0, - "audio_tokens": 0 - }, - "completion_tokens_details": { - "reasoning_tokens": 0, - "audio_tokens": 0, - "accepted_prediction_tokens": 0, - "rejected_prediction_tokens": 0 - } - }, - "system_fingerprint": "fp_9b78b61c52" - } - headers: - CF-Cache-Status: - - DYNAMIC - CF-RAY: - - 8e1225b4cbf581e4-SIN - Connection: - - keep-alive - Content-Type: - - application/json - Date: - - Mon, 11 Nov 2024 23:43:56 GMT - Server: - - cloudflare - Set-Cookie: test_set_cookie - Transfer-Encoding: - - chunked - X-Content-Type-Options: - - nosniff - access-control-expose-headers: - - X-Request-ID - alt-svc: - - h3=":443"; ma=86400 - content-length: - - '859' - openai-organization: test_openai_org_id - openai-processing-ms: - - '531' - openai-version: - - '2020-10-01' - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-ratelimit-limit-requests: - - '10000' - x-ratelimit-limit-tokens: - - '200000' - x-ratelimit-remaining-requests: - - '9995' - x-ratelimit-remaining-tokens: - - '199947' - x-ratelimit-reset-requests: - - 37.973s - x-ratelimit-reset-tokens: - - 15ms - x-request-id: - - req_22b79d2dddb920f55e33727d06724978 - status: - code: 200 - message: OK -version: 1 diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_with_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_with_content.yaml index 2abb443fe3..7d16c8a6a8 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_with_content.yaml +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_with_content.yaml @@ -2,132 +2,106 @@ interactions: - request: body: |- { + "model": "command-r-plus", "messages": [ { "role": "user", "content": "Say this is a test" } ], - "model": "gpt-4o-mini", "stream": false } headers: accept: - - application/json + - '*/*' accept-encoding: - gzip, deflate authorization: - - Bearer test_openai_api_key + - Bearer Z4EInAKRbIRKQV9lRZTciJqYyUBHXZGVUOAFBlRJ connection: - keep-alive content-length: - - '106' + - '109' content-type: - application/json host: - - api.openai.com + - api.cohere.com user-agent: - - OpenAI/Python 1.54.3 - x-stainless-arch: - - arm64 - x-stainless-async: - - 'false' - x-stainless-lang: - - python - x-stainless-os: - - MacOS - x-stainless-package-version: - - 1.54.3 - x-stainless-retry-count: - - '0' - x-stainless-runtime: - - CPython - x-stainless-runtime-version: - - 3.12.6 + - python-httpx/0.27.2 + x-fern-language: + - Python + x-fern-sdk-name: + - cohere + x-fern-sdk-version: + - 5.11.4 method: POST - uri: https://api.openai.com/v1/chat/completions + uri: https://api.cohere.com/v2/chat response: body: string: |- { - "id": "chatcmpl-ASYMQRl3A3DXL9FWCK9tnGRcKIO7q", - "object": "chat.completion", - "created": 1731368630, - "model": "gpt-4o-mini-2024-07-18", - "choices": [ - { - "index": 0, - "message": { - "role": "assistant", - "content": "This is a test.", - "refusal": null - }, - "logprobs": null, - "finish_reason": "stop" - } - ], + "id": "78c201dd-0f3d-43c4-a245-5ab6d28636ef", + "message": { + "role": "assistant", + "content": [ + { + "type": "text", + "text": "This is a test." + } + ] + }, + "finish_reason": "COMPLETE", "usage": { - "prompt_tokens": 12, - "completion_tokens": 5, - "total_tokens": 17, - "prompt_tokens_details": { - "cached_tokens": 0, - "audio_tokens": 0 + "billed_units": { + "input_tokens": 5, + "output_tokens": 5 }, - "completion_tokens_details": { - "reasoning_tokens": 0, - "audio_tokens": 0, - "accepted_prediction_tokens": 0, - "rejected_prediction_tokens": 0 + "tokens": { + "input_tokens": 198, + "output_tokens": 5 } - }, - "system_fingerprint": "fp_0ba0d124f1" + } } headers: - CF-Cache-Status: - - DYNAMIC - CF-RAY: - - 8e122593ff368bc8-SIN - Connection: - - keep-alive - Content-Type: - - application/json - Date: - - Mon, 11 Nov 2024 23:43:50 GMT - Server: - - cloudflare + Alt-Svc: + - h3=":443"; ma=2592000,h3-29=":443"; ma=2592000 + Content-Length: + - '266' Set-Cookie: test_set_cookie - Transfer-Encoding: - - chunked - X-Content-Type-Options: - - nosniff + Via: + - 1.1 google access-control-expose-headers: - - X-Request-ID - alt-svc: - - h3=":443"; ma=86400 - content-length: - - '765' - openai-organization: test_openai_org_id - openai-processing-ms: - - '287' - openai-version: - - '2020-10-01' - strict-transport-security: - - max-age=31536000; includeSubDomains; preload - x-ratelimit-limit-requests: - - '10000' - x-ratelimit-limit-tokens: - - '200000' - x-ratelimit-remaining-requests: - - '9999' - x-ratelimit-remaining-tokens: - - '199977' - x-ratelimit-reset-requests: - - 8.64s - x-ratelimit-reset-tokens: - - 6ms - x-request-id: - - req_58cff97afd0e7c0bba910ccf0b044a6f + - X-Debug-Trace-ID + cache-control: + - no-cache, no-store, no-transform, must-revalidate, private, max-age=0 + content-type: + - application/json + date: + - Mon, 09 Dec 2024 19:22:13 GMT + expires: + - Thu, 01 Jan 1970 00:00:00 UTC + num_chars: + - '1188' + num_tokens: + - '10' + pragma: + - no-cache + server: + - envoy + vary: + - Origin + x-accel-expires: + - '0' + x-debug-trace-id: + - 5bf598783ce550fab3dbd3c54bd617e7 + x-endpoint-monthly-call-limit: + - '1000' + x-envoy-upstream-service-time: + - '212' + x-trial-endpoint-call-limit: + - '40' + x-trial-endpoint-call-remaining: + - '39' status: code: 200 message: OK diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/conftest.py b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/conftest.py index 7ff7e46777..0dbed6a00b 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/conftest.py +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/conftest.py @@ -5,10 +5,10 @@ import pytest import yaml -from openai import AsyncOpenAI, OpenAI +from cohere import ClientV2 -from opentelemetry.instrumentation.openai_v2 import OpenAIInstrumentor -from opentelemetry.instrumentation.openai_v2.utils import ( +from opentelemetry.instrumentation.cohere_v2 import CohereInstrumentor +from opentelemetry.instrumentation.genai_utils import ( OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT, ) from opentelemetry.sdk._events import EventLoggerProvider @@ -54,18 +54,13 @@ def fixture_event_logger_provider(log_exporter): @pytest.fixture(autouse=True) def environment(): - if not os.getenv("OPENAI_API_KEY"): - os.environ["OPENAI_API_KEY"] = "test_openai_api_key" + if not os.getenv("CO_API_KEY"): + os.environ["CO_API_KEY"] = "test_cohere_api_key" @pytest.fixture -def openai_client(): - return OpenAI() - - -@pytest.fixture -def async_openai_client(): - return AsyncOpenAI() +def cohere_client(): + return ClientV2() @pytest.fixture(scope="module") @@ -73,9 +68,6 @@ def vcr_config(): return { "filter_headers": [ ("cookie", "test_cookie"), - ("authorization", "Bearer test_openai_api_key"), - ("openai-organization", "test_openai_org_id"), - ("openai-project", "test_openai_project_id"), ], "decode_compressed_response": True, "before_record_response": scrub_response_headers, @@ -84,7 +76,7 @@ def vcr_config(): @pytest.fixture(scope="function") def instrument_no_content(tracer_provider, event_logger_provider): - instrumentor = OpenAIInstrumentor() + instrumentor = CohereInstrumentor() instrumentor.instrument( tracer_provider=tracer_provider, event_logger_provider=event_logger_provider, @@ -99,7 +91,7 @@ def instrument_with_content(tracer_provider, event_logger_provider): os.environ.update( {OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT: "True"} ) - instrumentor = OpenAIInstrumentor() + instrumentor = CohereInstrumentor() instrumentor.instrument( tracer_provider=tracer_provider, event_logger_provider=event_logger_provider, @@ -181,6 +173,5 @@ def scrub_response_headers(response): """ This scrubs sensitive response headers. Note they are case-sensitive! """ - response["headers"]["openai-organization"] = "test_openai_org_id" response["headers"]["Set-Cookie"] = "test_set_cookie" return response diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/test_async_chat_completions.py b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/test_async_chat_completions.py deleted file mode 100644 index 1c4b3cb7dd..0000000000 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/test_async_chat_completions.py +++ /dev/null @@ -1,847 +0,0 @@ -# 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. -# pylint: disable=too-many-locals - -from typing import Optional - -import pytest -from openai import APIConnectionError, AsyncOpenAI, NotFoundError -from openai.resources.chat.completions import ChatCompletion - -from opentelemetry.sdk.trace import ReadableSpan -from opentelemetry.semconv._incubating.attributes import ( - error_attributes as ErrorAttributes, -) -from opentelemetry.semconv._incubating.attributes import ( - event_attributes as EventAttributes, -) -from opentelemetry.semconv._incubating.attributes import ( - gen_ai_attributes as GenAIAttributes, -) -from opentelemetry.semconv._incubating.attributes import ( - server_attributes as ServerAttributes, -) - - -@pytest.mark.vcr() -@pytest.mark.asyncio() -async def test_async_chat_completion_with_content( - span_exporter, log_exporter, async_openai_client, instrument_with_content -): - llm_model_value = "gpt-4o-mini" - messages_value = [{"role": "user", "content": "Say this is a test"}] - - response = await async_openai_client.chat.completions.create( - messages=messages_value, model=llm_model_value, stream=False - ) - - spans = span_exporter.get_finished_spans() - assert_completion_attributes(spans[0], llm_model_value, response) - - logs = log_exporter.get_finished_logs() - assert len(logs) == 2 - - user_message = {"content": messages_value[0]["content"]} - assert_message_in_logs( - logs[0], "gen_ai.user.message", user_message, spans[0] - ) - - choice_event = { - "index": 0, - "finish_reason": "stop", - "message": { - "role": "assistant", - "content": response.choices[0].message.content, - }, - } - assert_message_in_logs(logs[1], "gen_ai.choice", choice_event, spans[0]) - - -@pytest.mark.asyncio() -async def test_async_chat_completion_bad_endpoint( - span_exporter, instrument_no_content -): - llm_model_value = "gpt-4o-mini" - messages_value = [{"role": "user", "content": "Say this is a test"}] - - client = AsyncOpenAI(base_url="http://localhost:4242") - - with pytest.raises(APIConnectionError): - await client.chat.completions.create( - messages=messages_value, - model=llm_model_value, - timeout=0.1, - ) - - spans = span_exporter.get_finished_spans() - assert_all_attributes( - spans[0], llm_model_value, server_address="localhost" - ) - assert 4242 == spans[0].attributes[ServerAttributes.SERVER_PORT] - assert ( - "APIConnectionError" == spans[0].attributes[ErrorAttributes.ERROR_TYPE] - ) - - -@pytest.mark.vcr() -@pytest.mark.asyncio() -async def test_async_chat_completion_404( - span_exporter, async_openai_client, instrument_no_content -): - llm_model_value = "this-model-does-not-exist" - messages_value = [{"role": "user", "content": "Say this is a test"}] - - with pytest.raises(NotFoundError): - await async_openai_client.chat.completions.create( - messages=messages_value, - model=llm_model_value, - ) - - spans = span_exporter.get_finished_spans() - - assert_all_attributes(spans[0], llm_model_value) - assert "NotFoundError" == spans[0].attributes[ErrorAttributes.ERROR_TYPE] - - -@pytest.mark.vcr() -@pytest.mark.asyncio() -async def test_async_chat_completion_extra_params( - span_exporter, async_openai_client, instrument_no_content -): - llm_model_value = "gpt-4o-mini" - messages_value = [{"role": "user", "content": "Say this is a test"}] - - response = await async_openai_client.chat.completions.create( - messages=messages_value, - model=llm_model_value, - seed=42, - temperature=0.5, - max_tokens=50, - stream=False, - extra_body={"service_tier": "default"}, - ) - - spans = span_exporter.get_finished_spans() - assert_completion_attributes(spans[0], llm_model_value, response) - assert ( - spans[0].attributes[GenAIAttributes.GEN_AI_OPENAI_REQUEST_SEED] == 42 - ) - assert ( - spans[0].attributes[GenAIAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.5 - ) - assert spans[0].attributes[GenAIAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 50 - assert ( - spans[0].attributes[GenAIAttributes.GEN_AI_OPENAI_REQUEST_SERVICE_TIER] - == "default" - ) - - -@pytest.mark.vcr() -@pytest.mark.asyncio() -async def test_async_chat_completion_multiple_choices( - span_exporter, log_exporter, async_openai_client, instrument_with_content -): - llm_model_value = "gpt-4o-mini" - messages_value = [{"role": "user", "content": "Say this is a test"}] - - response = await async_openai_client.chat.completions.create( - messages=messages_value, model=llm_model_value, n=2, stream=False - ) - - spans = span_exporter.get_finished_spans() - assert_completion_attributes(spans[0], llm_model_value, response) - - logs = log_exporter.get_finished_logs() - assert len(logs) == 3 # 1 user message + 2 choice messages - - user_message = {"content": messages_value[0]["content"]} - assert_message_in_logs( - logs[0], "gen_ai.user.message", user_message, spans[0] - ) - - choice_event_0 = { - "index": 0, - "finish_reason": "stop", - "message": { - "role": "assistant", - "content": response.choices[0].message.content, - }, - } - assert_message_in_logs(logs[1], "gen_ai.choice", choice_event_0, spans[0]) - - choice_event_1 = { - "index": 1, - "finish_reason": "stop", - "message": { - "role": "assistant", - "content": response.choices[1].message.content, - }, - } - assert_message_in_logs(logs[2], "gen_ai.choice", choice_event_1, spans[0]) - - -@pytest.mark.vcr() -@pytest.mark.asyncio() -async def test_async_chat_completion_tool_calls_with_content( - span_exporter, log_exporter, async_openai_client, instrument_with_content -): - await chat_completion_tool_call( - span_exporter, log_exporter, async_openai_client, True - ) - - -@pytest.mark.vcr() -@pytest.mark.asyncio() -async def test_async_chat_completion_tool_calls_no_content( - span_exporter, log_exporter, async_openai_client, instrument_no_content -): - await chat_completion_tool_call( - span_exporter, log_exporter, async_openai_client, False - ) - - -async def chat_completion_tool_call( - span_exporter, log_exporter, async_openai_client, expect_content -): - llm_model_value = "gpt-4o-mini" - messages_value = [ - {"role": "system", "content": "You're a helpful assistant."}, - { - "role": "user", - "content": "What's the weather in Seattle and San Francisco today?", - }, - ] - - response_0 = await async_openai_client.chat.completions.create( - messages=messages_value, - model=llm_model_value, - tool_choice="auto", - tools=[get_current_weather_tool_definition()], - ) - - # sanity check - assert "tool_calls" in response_0.choices[0].finish_reason - - # final request - messages_value.append( - { - "role": "assistant", - "tool_calls": response_0.choices[0].message.to_dict()[ - "tool_calls" - ], - } - ) - - tool_call_result_0 = { - "role": "tool", - "content": "50 degrees and raining", - "tool_call_id": response_0.choices[0].message.tool_calls[0].id, - } - tool_call_result_1 = { - "role": "tool", - "content": "70 degrees and sunny", - "tool_call_id": response_0.choices[0].message.tool_calls[1].id, - } - - messages_value.append(tool_call_result_0) - messages_value.append(tool_call_result_1) - - response_1 = await async_openai_client.chat.completions.create( - messages=messages_value, model=llm_model_value - ) - - # sanity check - assert "stop" in response_1.choices[0].finish_reason - - # validate both calls - spans = span_exporter.get_finished_spans() - assert len(spans) == 2 - assert_completion_attributes(spans[0], llm_model_value, response_0) - assert_completion_attributes(spans[1], llm_model_value, response_1) - - logs = log_exporter.get_finished_logs() - assert len(logs) == 9 # 3 logs for first completion, 6 for second - - # call one - system_message = ( - {"content": messages_value[0]["content"]} if expect_content else None - ) - assert_message_in_logs( - logs[0], "gen_ai.system.message", system_message, spans[0] - ) - - user_message = ( - {"content": messages_value[1]["content"]} if expect_content else None - ) - assert_message_in_logs( - logs[1], "gen_ai.user.message", user_message, spans[0] - ) - - function_call_0 = {"name": "get_current_weather"} - function_call_1 = {"name": "get_current_weather"} - if expect_content: - function_call_0["arguments"] = ( - response_0.choices[0] - .message.tool_calls[0] - .function.arguments.replace("\n", "") - ) - function_call_1["arguments"] = ( - response_0.choices[0] - .message.tool_calls[1] - .function.arguments.replace("\n", "") - ) - - choice_event = { - "index": 0, - "finish_reason": "tool_calls", - "message": { - "role": "assistant", - "tool_calls": [ - { - "id": response_0.choices[0].message.tool_calls[0].id, - "type": "function", - "function": function_call_0, - }, - { - "id": response_0.choices[0].message.tool_calls[1].id, - "type": "function", - "function": function_call_1, - }, - ], - }, - } - assert_message_in_logs(logs[2], "gen_ai.choice", choice_event, spans[0]) - - # call two - system_message = ( - {"content": messages_value[0]["content"]} if expect_content else None - ) - assert_message_in_logs( - logs[3], "gen_ai.system.message", system_message, spans[1] - ) - - user_message = ( - {"content": messages_value[1]["content"]} if expect_content else None - ) - assert_message_in_logs( - logs[4], "gen_ai.user.message", user_message, spans[1] - ) - - assistant_tool_call = {"tool_calls": messages_value[2]["tool_calls"]} - if not expect_content: - assistant_tool_call["tool_calls"][0]["function"]["arguments"] = None - assistant_tool_call["tool_calls"][1]["function"]["arguments"] = None - - assert_message_in_logs( - logs[5], "gen_ai.assistant.message", assistant_tool_call, spans[1] - ) - - tool_message_0 = { - "id": tool_call_result_0["tool_call_id"], - "content": tool_call_result_0["content"] if expect_content else None, - } - - assert_message_in_logs( - logs[6], "gen_ai.tool.message", tool_message_0, spans[1] - ) - - tool_message_1 = { - "id": tool_call_result_1["tool_call_id"], - "content": tool_call_result_1["content"] if expect_content else None, - } - - assert_message_in_logs( - logs[7], "gen_ai.tool.message", tool_message_1, spans[1] - ) - - message = { - "role": "assistant", - "content": response_1.choices[0].message.content - if expect_content - else None, - } - choice = { - "index": 0, - "finish_reason": "stop", - "message": message, - } - assert_message_in_logs(logs[8], "gen_ai.choice", choice, spans[1]) - - -@pytest.mark.vcr() -@pytest.mark.asyncio() -async def test_async_chat_completion_streaming( - span_exporter, log_exporter, async_openai_client, instrument_with_content -): - llm_model_value = "gpt-4" - messages_value = [{"role": "user", "content": "Say this is a test"}] - - kwargs = { - "model": llm_model_value, - "messages": messages_value, - "stream": True, - "stream_options": {"include_usage": True}, - } - - response_stream_usage = None - response_stream_model = None - response_stream_id = None - response_stream_result = "" - response = await async_openai_client.chat.completions.create(**kwargs) - async for chunk in response: - if chunk.choices: - response_stream_result += chunk.choices[0].delta.content or "" - - # get the last chunk - if getattr(chunk, "usage", None): - response_stream_usage = chunk.usage - response_stream_model = chunk.model - response_stream_id = chunk.id - - spans = span_exporter.get_finished_spans() - assert_all_attributes( - spans[0], - llm_model_value, - response_stream_id, - response_stream_model, - response_stream_usage.prompt_tokens, - response_stream_usage.completion_tokens, - ) - - logs = log_exporter.get_finished_logs() - assert len(logs) == 2 - - user_message = {"content": "Say this is a test"} - assert_message_in_logs( - logs[0], "gen_ai.user.message", user_message, spans[0] - ) - - choice_event = { - "index": 0, - "finish_reason": "stop", - "message": {"role": "assistant", "content": response_stream_result}, - } - assert_message_in_logs(logs[1], "gen_ai.choice", choice_event, spans[0]) - - -@pytest.mark.vcr() -@pytest.mark.asyncio() -async def test_async_chat_completion_streaming_not_complete( - span_exporter, log_exporter, async_openai_client, instrument_with_content -): - llm_model_value = "gpt-4" - messages_value = [{"role": "user", "content": "Say this is a test"}] - - kwargs = { - "model": llm_model_value, - "messages": messages_value, - "stream": True, - } - - response_stream_model = None - response_stream_id = None - response_stream_result = "" - response = await async_openai_client.chat.completions.create(**kwargs) - idx = 0 - async for chunk in response: - if chunk.choices: - response_stream_result += chunk.choices[0].delta.content or "" - if idx == 1: - # fake a stop - break - - if chunk.model: - response_stream_model = chunk.model - if chunk.id: - response_stream_id = chunk.id - idx += 1 - - response.close() - spans = span_exporter.get_finished_spans() - assert_all_attributes( - spans[0], llm_model_value, response_stream_id, response_stream_model - ) - - logs = log_exporter.get_finished_logs() - assert len(logs) == 2 - - user_message = {"content": "Say this is a test"} - assert_message_in_logs( - logs[0], "gen_ai.user.message", user_message, spans[0] - ) - - choice_event = { - "index": 0, - "finish_reason": "error", - "message": {"role": "assistant", "content": response_stream_result}, - } - assert_message_in_logs(logs[1], "gen_ai.choice", choice_event, spans[0]) - - -@pytest.mark.vcr() -@pytest.mark.asyncio() -async def test_async_chat_completion_multiple_choices_streaming( - span_exporter, log_exporter, async_openai_client, instrument_with_content -): - llm_model_value = "gpt-4o-mini" - messages_value = [ - {"role": "system", "content": "You're a helpful assistant."}, - { - "role": "user", - "content": "What's the weather in Seattle and San Francisco today?", - }, - ] - - response_0 = await async_openai_client.chat.completions.create( - messages=messages_value, - model=llm_model_value, - n=2, - stream=True, - stream_options={"include_usage": True}, - ) - - # two strings for each choice - response_stream_result = ["", ""] - finish_reasons = ["", ""] - async for chunk in response_0: - if chunk.choices: - for choice in chunk.choices: - response_stream_result[choice.index] += ( - choice.delta.content or "" - ) - if choice.finish_reason: - finish_reasons[choice.index] = choice.finish_reason - - # get the last chunk - if getattr(chunk, "usage", None): - response_stream_usage = chunk.usage - response_stream_model = chunk.model - response_stream_id = chunk.id - - # sanity check - assert "stop" == finish_reasons[0] - - spans = span_exporter.get_finished_spans() - assert_all_attributes( - spans[0], - llm_model_value, - response_stream_id, - response_stream_model, - response_stream_usage.prompt_tokens, - response_stream_usage.completion_tokens, - ) - - logs = log_exporter.get_finished_logs() - assert len(logs) == 4 - - system_message = {"content": messages_value[0]["content"]} - assert_message_in_logs( - logs[0], "gen_ai.system.message", system_message, spans[0] - ) - - user_message = { - "content": "What's the weather in Seattle and San Francisco today?" - } - assert_message_in_logs( - logs[1], "gen_ai.user.message", user_message, spans[0] - ) - - choice_event_0 = { - "index": 0, - "finish_reason": "stop", - "message": { - "role": "assistant", - "content": "".join(response_stream_result[0]), - }, - } - assert_message_in_logs(logs[2], "gen_ai.choice", choice_event_0, spans[0]) - - choice_event_1 = { - "index": 1, - "finish_reason": "stop", - "message": { - "role": "assistant", - "content": "".join(response_stream_result[1]), - }, - } - assert_message_in_logs(logs[3], "gen_ai.choice", choice_event_1, spans[0]) - - -@pytest.mark.vcr() -@pytest.mark.asyncio() -async def test_async_chat_completion_multiple_tools_streaming_with_content( - span_exporter, log_exporter, async_openai_client, instrument_with_content -): - await async_chat_completion_multiple_tools_streaming( - span_exporter, log_exporter, async_openai_client, True - ) - - -@pytest.mark.vcr() -@pytest.mark.asyncio() -async def test_async_chat_completion_multiple_tools_streaming_no_content( - span_exporter, log_exporter, async_openai_client, instrument_no_content -): - await async_chat_completion_multiple_tools_streaming( - span_exporter, log_exporter, async_openai_client, False - ) - - -async def async_chat_completion_multiple_tools_streaming( - span_exporter, log_exporter, async_openai_client, expect_content -): - llm_model_value = "gpt-4o-mini" - messages_value = [ - {"role": "system", "content": "You're a helpful assistant."}, - { - "role": "user", - "content": "What's the weather in Seattle and San Francisco today?", - }, - ] - - response = await async_openai_client.chat.completions.create( - messages=messages_value, - model=llm_model_value, - tool_choice="auto", - tools=[get_current_weather_tool_definition()], - stream=True, - stream_options={"include_usage": True}, - ) - - finish_reason = None - # two tools - tool_names = ["", ""] - tool_call_ids = ["", ""] - tool_args = ["", ""] - async for chunk in response: - if chunk.choices: - if chunk.choices[0].finish_reason: - finish_reason = chunk.choices[0].finish_reason - for tool_call in chunk.choices[0].delta.tool_calls or []: - t_idx = tool_call.index - if tool_call.id: - tool_call_ids[t_idx] = tool_call.id - if tool_call.function: - if tool_call.function.arguments: - tool_args[t_idx] += tool_call.function.arguments - if tool_call.function.name: - tool_names[t_idx] = tool_call.function.name - - # get the last chunk - if getattr(chunk, "usage", None): - response_stream_usage = chunk.usage - response_stream_model = chunk.model - response_stream_id = chunk.id - - # sanity check - assert "tool_calls" == finish_reason - - spans = span_exporter.get_finished_spans() - assert_all_attributes( - spans[0], - llm_model_value, - response_stream_id, - response_stream_model, - response_stream_usage.prompt_tokens, - response_stream_usage.completion_tokens, - ) - - logs = log_exporter.get_finished_logs() - assert len(logs) == 3 - - system_message = ( - {"content": messages_value[0]["content"]} if expect_content else None - ) - assert_message_in_logs( - logs[0], "gen_ai.system.message", system_message, spans[0] - ) - - user_message = ( - {"content": "What's the weather in Seattle and San Francisco today?"} - if expect_content - else None - ) - assert_message_in_logs( - logs[1], "gen_ai.user.message", user_message, spans[0] - ) - - choice_event = { - "index": 0, - "finish_reason": "tool_calls", - "message": { - "role": "assistant", - "tool_calls": [ - { - "id": tool_call_ids[0], - "type": "function", - "function": { - "name": tool_names[0], - "arguments": ( - tool_args[0].replace("\n", "") - if expect_content - else None - ), - }, - }, - { - "id": tool_call_ids[1], - "type": "function", - "function": { - "name": tool_names[1], - "arguments": ( - tool_args[1].replace("\n", "") - if expect_content - else None - ), - }, - }, - ], - }, - } - assert_message_in_logs(logs[2], "gen_ai.choice", choice_event, spans[0]) - - -def assert_message_in_logs(log, event_name, expected_content, parent_span): - assert log.log_record.attributes[EventAttributes.EVENT_NAME] == event_name - assert ( - log.log_record.attributes[GenAIAttributes.GEN_AI_SYSTEM] - == GenAIAttributes.GenAiSystemValues.OPENAI.value - ) - - if not expected_content: - assert not log.log_record.body - else: - assert log.log_record.body - assert dict(log.log_record.body) == remove_none_values( - expected_content - ) - assert_log_parent(log, parent_span) - - -def remove_none_values(body): - result = {} - for key, value in body.items(): - if value is None: - continue - if isinstance(value, dict): - result[key] = remove_none_values(value) - elif isinstance(value, list): - result[key] = [remove_none_values(i) for i in value] - else: - result[key] = value - return result - - -def assert_completion_attributes( - span: ReadableSpan, - request_model: str, - response: ChatCompletion, - operation_name: str = "chat", - server_address: str = "api.openai.com", -): - return assert_all_attributes( - span, - request_model, - response.id, - response.model, - response.usage.prompt_tokens, - response.usage.completion_tokens, - operation_name, - server_address, - ) - - -def assert_all_attributes( - span: ReadableSpan, - request_model: str, - response_id: str = None, - response_model: str = None, - input_tokens: Optional[int] = None, - output_tokens: Optional[int] = None, - operation_name: str = "chat", - server_address: str = "api.openai.com", -): - assert span.name == f"{operation_name} {request_model}" - assert ( - operation_name - == span.attributes[GenAIAttributes.GEN_AI_OPERATION_NAME] - ) - assert ( - GenAIAttributes.GenAiSystemValues.OPENAI.value - == span.attributes[GenAIAttributes.GEN_AI_SYSTEM] - ) - assert ( - request_model == span.attributes[GenAIAttributes.GEN_AI_REQUEST_MODEL] - ) - if response_model: - assert ( - response_model - == span.attributes[GenAIAttributes.GEN_AI_RESPONSE_MODEL] - ) - else: - assert GenAIAttributes.GEN_AI_RESPONSE_MODEL not in span.attributes - - if response_id: - assert ( - response_id == span.attributes[GenAIAttributes.GEN_AI_RESPONSE_ID] - ) - else: - assert GenAIAttributes.GEN_AI_RESPONSE_ID not in span.attributes - - if input_tokens: - assert ( - input_tokens - == span.attributes[GenAIAttributes.GEN_AI_USAGE_INPUT_TOKENS] - ) - else: - assert GenAIAttributes.GEN_AI_USAGE_INPUT_TOKENS not in span.attributes - - if output_tokens: - assert ( - output_tokens - == span.attributes[GenAIAttributes.GEN_AI_USAGE_OUTPUT_TOKENS] - ) - else: - assert ( - GenAIAttributes.GEN_AI_USAGE_OUTPUT_TOKENS not in span.attributes - ) - - assert server_address == span.attributes[ServerAttributes.SERVER_ADDRESS] - - -def assert_log_parent(log, span): - assert log.log_record.trace_id == span.get_span_context().trace_id - assert log.log_record.span_id == span.get_span_context().span_id - assert log.log_record.trace_flags == span.get_span_context().trace_flags - - -def get_current_weather_tool_definition(): - return { - "type": "function", - "function": { - "name": "get_current_weather", - "description": "Get the current weather in a given location", - "parameters": { - "type": "object", - "properties": { - "location": { - "type": "string", - "description": "The city and state, e.g. Boston, MA", - }, - }, - "required": ["location"], - "additionalProperties": False, - }, - }, - } diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/test_chat_completions.py b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/test_chat_completions.py index c6cb19aa8d..9965c1e9d6 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/test_chat_completions.py +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/test_chat_completions.py @@ -16,8 +16,7 @@ from typing import Optional import pytest -from openai import APIConnectionError, NotFoundError, OpenAI -from openai.resources.chat.completions import ChatCompletion +from cohere import ChatResponse from opentelemetry.sdk.trace import ReadableSpan from opentelemetry.semconv._incubating.attributes import ( @@ -36,658 +35,658 @@ @pytest.mark.vcr() def test_chat_completion_with_content( - span_exporter, log_exporter, openai_client, instrument_with_content + span_exporter, log_exporter, cohere_client, instrument_with_content, tracer_provider ): - llm_model_value = "gpt-4o-mini" + llm_model_value = "command-r-plus" messages_value = [{"role": "user", "content": "Say this is a test"}] - response = openai_client.chat.completions.create( - messages=messages_value, model=llm_model_value, stream=False + response = cohere_client.chat( + messages=messages_value, model=llm_model_value, ) spans = span_exporter.get_finished_spans() assert_completion_attributes(spans[0], llm_model_value, response) - logs = log_exporter.get_finished_logs() - assert len(logs) == 2 - - user_message = {"content": messages_value[0]["content"]} - assert_message_in_logs( - logs[0], "gen_ai.user.message", user_message, spans[0] - ) - - choice_event = { - "index": 0, - "finish_reason": "stop", - "message": { - "role": "assistant", - "content": response.choices[0].message.content, - }, - } - assert_message_in_logs(logs[1], "gen_ai.choice", choice_event, spans[0]) - - -def test_chat_completion_bad_endpoint(span_exporter, instrument_no_content): - llm_model_value = "gpt-4o-mini" - messages_value = [{"role": "user", "content": "Say this is a test"}] - - client = OpenAI(base_url="http://localhost:4242") - - with pytest.raises(APIConnectionError): - client.chat.completions.create( - messages=messages_value, - model=llm_model_value, - timeout=0.1, - ) - - spans = span_exporter.get_finished_spans() - assert_all_attributes( - spans[0], llm_model_value, server_address="localhost" - ) - assert 4242 == spans[0].attributes[ServerAttributes.SERVER_PORT] - assert ( - "APIConnectionError" == spans[0].attributes[ErrorAttributes.ERROR_TYPE] - ) - - -@pytest.mark.vcr() -def test_chat_completion_404( - span_exporter, openai_client, instrument_no_content -): - llm_model_value = "this-model-does-not-exist" - messages_value = [{"role": "user", "content": "Say this is a test"}] - - with pytest.raises(NotFoundError): - openai_client.chat.completions.create( - messages=messages_value, - model=llm_model_value, - ) - - spans = span_exporter.get_finished_spans() - - assert_all_attributes(spans[0], llm_model_value) - assert "NotFoundError" == spans[0].attributes[ErrorAttributes.ERROR_TYPE] - - -@pytest.mark.vcr() -def test_chat_completion_extra_params( - span_exporter, openai_client, instrument_no_content -): - llm_model_value = "gpt-4o-mini" - messages_value = [{"role": "user", "content": "Say this is a test"}] - - response = openai_client.chat.completions.create( - messages=messages_value, - model=llm_model_value, - seed=42, - temperature=0.5, - max_tokens=50, - stream=False, - extra_body={"service_tier": "default"}, - ) - - spans = span_exporter.get_finished_spans() - assert_completion_attributes(spans[0], llm_model_value, response) - assert ( - spans[0].attributes[GenAIAttributes.GEN_AI_OPENAI_REQUEST_SEED] == 42 - ) - assert ( - spans[0].attributes[GenAIAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.5 - ) - assert spans[0].attributes[GenAIAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 50 - assert ( - spans[0].attributes[GenAIAttributes.GEN_AI_OPENAI_REQUEST_SERVICE_TIER] - == "default" - ) - - -@pytest.mark.vcr() -def test_chat_completion_multiple_choices( - span_exporter, log_exporter, openai_client, instrument_with_content -): - llm_model_value = "gpt-4o-mini" - messages_value = [{"role": "user", "content": "Say this is a test"}] - - response = openai_client.chat.completions.create( - messages=messages_value, model=llm_model_value, n=2, stream=False - ) - - spans = span_exporter.get_finished_spans() - assert_completion_attributes(spans[0], llm_model_value, response) - - logs = log_exporter.get_finished_logs() - assert len(logs) == 3 # 1 user message + 2 choice messages - - user_message = {"content": messages_value[0]["content"]} - assert_message_in_logs( - logs[0], "gen_ai.user.message", user_message, spans[0] - ) - - choice_event_0 = { - "index": 0, - "finish_reason": "stop", - "message": { - "role": "assistant", - "content": response.choices[0].message.content, - }, - } - assert_message_in_logs(logs[1], "gen_ai.choice", choice_event_0, spans[0]) - - choice_event_1 = { - "index": 1, - "finish_reason": "stop", - "message": { - "role": "assistant", - "content": response.choices[1].message.content, - }, - } - assert_message_in_logs(logs[2], "gen_ai.choice", choice_event_1, spans[0]) - - -@pytest.mark.vcr() -def test_chat_completion_tool_calls_with_content( - span_exporter, log_exporter, openai_client, instrument_with_content -): - chat_completion_tool_call(span_exporter, log_exporter, openai_client, True) - - -@pytest.mark.vcr() -def test_chat_completion_tool_calls_no_content( - span_exporter, log_exporter, openai_client, instrument_no_content -): - chat_completion_tool_call( - span_exporter, log_exporter, openai_client, False - ) - - -def chat_completion_tool_call( - span_exporter, log_exporter, openai_client, expect_content -): - llm_model_value = "gpt-4o-mini" - messages_value = [ - {"role": "system", "content": "You're a helpful assistant."}, - { - "role": "user", - "content": "What's the weather in Seattle and San Francisco today?", - }, - ] - - response_0 = openai_client.chat.completions.create( - messages=messages_value, - model=llm_model_value, - tool_choice="auto", - tools=[get_current_weather_tool_definition()], - ) - - # sanity check - assert "tool_calls" in response_0.choices[0].finish_reason - - # final request - messages_value.append( - { - "role": "assistant", - "tool_calls": response_0.choices[0].message.to_dict()[ - "tool_calls" - ], - } - ) - - tool_call_result_0 = { - "role": "tool", - "content": "50 degrees and raining", - "tool_call_id": response_0.choices[0].message.tool_calls[0].id, - } - tool_call_result_1 = { - "role": "tool", - "content": "70 degrees and sunny", - "tool_call_id": response_0.choices[0].message.tool_calls[1].id, - } - - messages_value.append(tool_call_result_0) - messages_value.append(tool_call_result_1) - - response_1 = openai_client.chat.completions.create( - messages=messages_value, model=llm_model_value - ) - - # sanity check - assert "stop" in response_1.choices[0].finish_reason - - # validate both calls - spans = span_exporter.get_finished_spans() - assert len(spans) == 2 - assert_completion_attributes(spans[0], llm_model_value, response_0) - assert_completion_attributes(spans[1], llm_model_value, response_1) - - logs = log_exporter.get_finished_logs() - assert len(logs) == 9 # 3 logs for first completion, 6 for second - - # call one - system_message = ( - {"content": messages_value[0]["content"]} if expect_content else None - ) - assert_message_in_logs( - logs[0], "gen_ai.system.message", system_message, spans[0] - ) - - user_message = ( - {"content": messages_value[1]["content"]} if expect_content else None - ) - assert_message_in_logs( - logs[1], "gen_ai.user.message", user_message, spans[0] - ) - - function_call_0 = {"name": "get_current_weather"} - function_call_1 = {"name": "get_current_weather"} - if expect_content: - function_call_0["arguments"] = ( - response_0.choices[0] - .message.tool_calls[0] - .function.arguments.replace("\n", "") - ) - function_call_1["arguments"] = ( - response_0.choices[0] - .message.tool_calls[1] - .function.arguments.replace("\n", "") - ) - - choice_event = { - "index": 0, - "finish_reason": "tool_calls", - "message": { - "role": "assistant", - "tool_calls": [ - { - "id": response_0.choices[0].message.tool_calls[0].id, - "type": "function", - "function": function_call_0, - }, - { - "id": response_0.choices[0].message.tool_calls[1].id, - "type": "function", - "function": function_call_1, - }, - ], - }, - } - assert_message_in_logs(logs[2], "gen_ai.choice", choice_event, spans[0]) - - # call two - system_message = ( - {"content": messages_value[0]["content"]} if expect_content else None - ) - assert_message_in_logs( - logs[3], "gen_ai.system.message", system_message, spans[1] - ) - - user_message = ( - {"content": messages_value[1]["content"]} if expect_content else None - ) - assert_message_in_logs( - logs[4], "gen_ai.user.message", user_message, spans[1] - ) - - assistant_tool_call = {"tool_calls": messages_value[2]["tool_calls"]} - if not expect_content: - assistant_tool_call["tool_calls"][0]["function"]["arguments"] = None - assistant_tool_call["tool_calls"][1]["function"]["arguments"] = None - - assert_message_in_logs( - logs[5], "gen_ai.assistant.message", assistant_tool_call, spans[1] - ) - - tool_message_0 = { - "id": tool_call_result_0["tool_call_id"], - "content": tool_call_result_0["content"] if expect_content else None, - } - - assert_message_in_logs( - logs[6], "gen_ai.tool.message", tool_message_0, spans[1] - ) - - tool_message_1 = { - "id": tool_call_result_1["tool_call_id"], - "content": tool_call_result_1["content"] if expect_content else None, - } - - assert_message_in_logs( - logs[7], "gen_ai.tool.message", tool_message_1, spans[1] - ) - - message = { - "role": "assistant", - "content": response_1.choices[0].message.content - if expect_content - else None, - } - choice = { - "index": 0, - "finish_reason": "stop", - "message": message, - } - assert_message_in_logs(logs[8], "gen_ai.choice", choice, spans[1]) - - -@pytest.mark.vcr() -def test_chat_completion_streaming( - span_exporter, log_exporter, openai_client, instrument_with_content -): - llm_model_value = "gpt-4" - messages_value = [{"role": "user", "content": "Say this is a test"}] - - kwargs = { - "model": llm_model_value, - "messages": messages_value, - "stream": True, - "stream_options": {"include_usage": True}, - } - - response_stream_usage = None - response_stream_model = None - response_stream_id = None - response_stream_result = "" - response = openai_client.chat.completions.create(**kwargs) - for chunk in response: - if chunk.choices: - response_stream_result += chunk.choices[0].delta.content or "" - - # get the last chunk - if getattr(chunk, "usage", None): - response_stream_usage = chunk.usage - response_stream_model = chunk.model - response_stream_id = chunk.id - - spans = span_exporter.get_finished_spans() - assert_all_attributes( - spans[0], - llm_model_value, - response_stream_id, - response_stream_model, - response_stream_usage.prompt_tokens, - response_stream_usage.completion_tokens, - ) - - logs = log_exporter.get_finished_logs() - assert len(logs) == 2 - - user_message = {"content": "Say this is a test"} - assert_message_in_logs( - logs[0], "gen_ai.user.message", user_message, spans[0] - ) - - choice_event = { - "index": 0, - "finish_reason": "stop", - "message": {"role": "assistant", "content": response_stream_result}, - } - assert_message_in_logs(logs[1], "gen_ai.choice", choice_event, spans[0]) - - -@pytest.mark.vcr() -def test_chat_completion_streaming_not_complete( - span_exporter, log_exporter, openai_client, instrument_with_content -): - llm_model_value = "gpt-4" - messages_value = [{"role": "user", "content": "Say this is a test"}] - - kwargs = { - "model": llm_model_value, - "messages": messages_value, - "stream": True, - } - - response_stream_model = None - response_stream_id = None - response_stream_result = "" - response = openai_client.chat.completions.create(**kwargs) - for idx, chunk in enumerate(response): - if chunk.choices: - response_stream_result += chunk.choices[0].delta.content or "" - if idx == 1: - # fake a stop - break - - if chunk.model: - response_stream_model = chunk.model - if chunk.id: - response_stream_id = chunk.id - - response.close() - spans = span_exporter.get_finished_spans() - assert_all_attributes( - spans[0], llm_model_value, response_stream_id, response_stream_model - ) - - logs = log_exporter.get_finished_logs() - assert len(logs) == 2 - - user_message = {"content": "Say this is a test"} - assert_message_in_logs( - logs[0], "gen_ai.user.message", user_message, spans[0] - ) - - choice_event = { - "index": 0, - "finish_reason": "error", - "message": {"role": "assistant", "content": response_stream_result}, - } - assert_message_in_logs(logs[1], "gen_ai.choice", choice_event, spans[0]) - - -@pytest.mark.vcr() -def test_chat_completion_multiple_choices_streaming( - span_exporter, log_exporter, openai_client, instrument_with_content -): - llm_model_value = "gpt-4o-mini" - messages_value = [ - {"role": "system", "content": "You're a helpful assistant."}, - { - "role": "user", - "content": "What's the weather in Seattle and San Francisco today?", - }, - ] - - response_0 = openai_client.chat.completions.create( - messages=messages_value, - model=llm_model_value, - n=2, - stream=True, - stream_options={"include_usage": True}, - ) - - # two strings for each choice - response_stream_result = ["", ""] - finish_reasons = ["", ""] - for chunk in response_0: - if chunk.choices: - for choice in chunk.choices: - response_stream_result[choice.index] += ( - choice.delta.content or "" - ) - if choice.finish_reason: - finish_reasons[choice.index] = choice.finish_reason - - # get the last chunk - if getattr(chunk, "usage", None): - response_stream_usage = chunk.usage - response_stream_model = chunk.model - response_stream_id = chunk.id - - # sanity check - assert "stop" == finish_reasons[0] - - spans = span_exporter.get_finished_spans() - assert_all_attributes( - spans[0], - llm_model_value, - response_stream_id, - response_stream_model, - response_stream_usage.prompt_tokens, - response_stream_usage.completion_tokens, - ) - - logs = log_exporter.get_finished_logs() - assert len(logs) == 4 - - system_message = {"content": messages_value[0]["content"]} - assert_message_in_logs( - logs[0], "gen_ai.system.message", system_message, spans[0] - ) - - user_message = { - "content": "What's the weather in Seattle and San Francisco today?" - } - assert_message_in_logs( - logs[1], "gen_ai.user.message", user_message, spans[0] - ) - - choice_event_0 = { - "index": 0, - "finish_reason": "stop", - "message": { - "role": "assistant", - "content": "".join(response_stream_result[0]), - }, - } - assert_message_in_logs(logs[2], "gen_ai.choice", choice_event_0, spans[0]) - - choice_event_1 = { - "index": 1, - "finish_reason": "stop", - "message": { - "role": "assistant", - "content": "".join(response_stream_result[1]), - }, - } - assert_message_in_logs(logs[3], "gen_ai.choice", choice_event_1, spans[0]) - - -@pytest.mark.vcr() -def test_chat_completion_multiple_tools_streaming_with_content( - span_exporter, log_exporter, openai_client, instrument_with_content -): - chat_completion_multiple_tools_streaming( - span_exporter, log_exporter, openai_client, True - ) - - -@pytest.mark.vcr() -def test_chat_completion_multiple_tools_streaming_no_content( - span_exporter, log_exporter, openai_client, instrument_no_content -): - chat_completion_multiple_tools_streaming( - span_exporter, log_exporter, openai_client, False - ) - - -def chat_completion_multiple_tools_streaming( - span_exporter, log_exporter, openai_client, expect_content -): - llm_model_value = "gpt-4o-mini" - messages_value = [ - {"role": "system", "content": "You're a helpful assistant."}, - { - "role": "user", - "content": "What's the weather in Seattle and San Francisco today?", - }, - ] - - response = openai_client.chat.completions.create( - messages=messages_value, - model=llm_model_value, - tool_choice="auto", - tools=[get_current_weather_tool_definition()], - stream=True, - stream_options={"include_usage": True}, - ) - - finish_reason = None - # two tools - tool_names = ["", ""] - tool_call_ids = ["", ""] - tool_args = ["", ""] - for chunk in response: - if chunk.choices: - if chunk.choices[0].finish_reason: - finish_reason = chunk.choices[0].finish_reason - for tool_call in chunk.choices[0].delta.tool_calls or []: - t_idx = tool_call.index - if tool_call.id: - tool_call_ids[t_idx] = tool_call.id - if tool_call.function: - if tool_call.function.arguments: - tool_args[t_idx] += tool_call.function.arguments - if tool_call.function.name: - tool_names[t_idx] = tool_call.function.name - - # get the last chunk - if getattr(chunk, "usage", None): - response_stream_usage = chunk.usage - response_stream_model = chunk.model - response_stream_id = chunk.id - - # sanity check - assert "tool_calls" == finish_reason - - spans = span_exporter.get_finished_spans() - assert_all_attributes( - spans[0], - llm_model_value, - response_stream_id, - response_stream_model, - response_stream_usage.prompt_tokens, - response_stream_usage.completion_tokens, - ) - - logs = log_exporter.get_finished_logs() - assert len(logs) == 3 - - system_message = ( - {"content": messages_value[0]["content"]} if expect_content else None - ) - assert_message_in_logs( - logs[0], "gen_ai.system.message", system_message, spans[0] - ) - - user_message = ( - {"content": "What's the weather in Seattle and San Francisco today?"} - if expect_content - else None - ) - assert_message_in_logs( - logs[1], "gen_ai.user.message", user_message, spans[0] - ) - - choice_event = { - "index": 0, - "finish_reason": "tool_calls", - "message": { - "role": "assistant", - "tool_calls": [ - { - "id": tool_call_ids[0], - "type": "function", - "function": { - "name": tool_names[0], - "arguments": tool_args[0].replace("\n", "") - if expect_content - else None, - }, - }, - { - "id": tool_call_ids[1], - "type": "function", - "function": { - "name": tool_names[1], - "arguments": tool_args[1].replace("\n", "") - if expect_content - else None, - }, - }, - ], - }, - } - assert_message_in_logs(logs[2], "gen_ai.choice", choice_event, spans[0]) + # logs = log_exporter.get_finished_logs() + # assert len(logs) == 2 + + # user_message = {"content": messages_value[0]["content"]} + # assert_message_in_logs( + # logs[0], "gen_ai.user.message", user_message, spans[0] + # ) + + # choice_event = { + # "index": 0, + # "finish_reason": "stop", + # "message": { + # "role": "assistant", + # "content": response.choices[0].message.content, + # }, + # } + # assert_message_in_logs(logs[1], "gen_ai.choice", choice_event, spans[0]) + + +# def test_chat_completion_bad_endpoint(span_exporter, instrument_no_content): +# llm_model_value = "gpt-4o-mini" +# messages_value = [{"role": "user", "content": "Say this is a test"}] + +# client = OpenAI(base_url="http://localhost:4242") + +# with pytest.raises(APIConnectionError): +# client.chat.completions.create( +# messages=messages_value, +# model=llm_model_value, +# timeout=0.1, +# ) + +# spans = span_exporter.get_finished_spans() +# assert_all_attributes( +# spans[0], llm_model_value, server_address="localhost" +# ) +# assert 4242 == spans[0].attributes[ServerAttributes.SERVER_PORT] +# assert ( +# "APIConnectionError" == spans[0].attributes[ErrorAttributes.ERROR_TYPE] +# ) + + +# @pytest.mark.vcr() +# def test_chat_completion_404( +# span_exporter, openai_client, instrument_no_content +# ): +# llm_model_value = "this-model-does-not-exist" +# messages_value = [{"role": "user", "content": "Say this is a test"}] + +# with pytest.raises(NotFoundError): +# openai_client.chat.completions.create( +# messages=messages_value, +# model=llm_model_value, +# ) + +# spans = span_exporter.get_finished_spans() + +# assert_all_attributes(spans[0], llm_model_value) +# assert "NotFoundError" == spans[0].attributes[ErrorAttributes.ERROR_TYPE] + + +# @pytest.mark.vcr() +# def test_chat_completion_extra_params( +# span_exporter, openai_client, instrument_no_content +# ): +# llm_model_value = "gpt-4o-mini" +# messages_value = [{"role": "user", "content": "Say this is a test"}] + +# response = openai_client.chat.completions.create( +# messages=messages_value, +# model=llm_model_value, +# seed=42, +# temperature=0.5, +# max_tokens=50, +# stream=False, +# extra_body={"service_tier": "default"}, +# ) + +# spans = span_exporter.get_finished_spans() +# assert_completion_attributes(spans[0], llm_model_value, response) +# assert ( +# spans[0].attributes[GenAIAttributes.GEN_AI_OPENAI_REQUEST_SEED] == 42 +# ) +# assert ( +# spans[0].attributes[GenAIAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.5 +# ) +# assert spans[0].attributes[GenAIAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 50 +# assert ( +# spans[0].attributes[GenAIAttributes.GEN_AI_OPENAI_REQUEST_SERVICE_TIER] +# == "default" +# ) + + +# @pytest.mark.vcr() +# def test_chat_completion_multiple_choices( +# span_exporter, log_exporter, openai_client, instrument_with_content +# ): +# llm_model_value = "gpt-4o-mini" +# messages_value = [{"role": "user", "content": "Say this is a test"}] + +# response = openai_client.chat.completions.create( +# messages=messages_value, model=llm_model_value, n=2, stream=False +# ) + +# spans = span_exporter.get_finished_spans() +# assert_completion_attributes(spans[0], llm_model_value, response) + +# logs = log_exporter.get_finished_logs() +# assert len(logs) == 3 # 1 user message + 2 choice messages + +# user_message = {"content": messages_value[0]["content"]} +# assert_message_in_logs( +# logs[0], "gen_ai.user.message", user_message, spans[0] +# ) + +# choice_event_0 = { +# "index": 0, +# "finish_reason": "stop", +# "message": { +# "role": "assistant", +# "content": response.choices[0].message.content, +# }, +# } +# assert_message_in_logs(logs[1], "gen_ai.choice", choice_event_0, spans[0]) + +# choice_event_1 = { +# "index": 1, +# "finish_reason": "stop", +# "message": { +# "role": "assistant", +# "content": response.choices[1].message.content, +# }, +# } +# assert_message_in_logs(logs[2], "gen_ai.choice", choice_event_1, spans[0]) + + +# @pytest.mark.vcr() +# def test_chat_completion_tool_calls_with_content( +# span_exporter, log_exporter, openai_client, instrument_with_content +# ): +# chat_completion_tool_call(span_exporter, log_exporter, openai_client, True) + + +# @pytest.mark.vcr() +# def test_chat_completion_tool_calls_no_content( +# span_exporter, log_exporter, openai_client, instrument_no_content +# ): +# chat_completion_tool_call( +# span_exporter, log_exporter, openai_client, False +# ) + + +# def chat_completion_tool_call( +# span_exporter, log_exporter, openai_client, expect_content +# ): +# llm_model_value = "gpt-4o-mini" +# messages_value = [ +# {"role": "system", "content": "You're a helpful assistant."}, +# { +# "role": "user", +# "content": "What's the weather in Seattle and San Francisco today?", +# }, +# ] + +# response_0 = openai_client.chat.completions.create( +# messages=messages_value, +# model=llm_model_value, +# tool_choice="auto", +# tools=[get_current_weather_tool_definition()], +# ) + +# # sanity check +# assert "tool_calls" in response_0.choices[0].finish_reason + +# # final request +# messages_value.append( +# { +# "role": "assistant", +# "tool_calls": response_0.choices[0].message.to_dict()[ +# "tool_calls" +# ], +# } +# ) + +# tool_call_result_0 = { +# "role": "tool", +# "content": "50 degrees and raining", +# "tool_call_id": response_0.choices[0].message.tool_calls[0].id, +# } +# tool_call_result_1 = { +# "role": "tool", +# "content": "70 degrees and sunny", +# "tool_call_id": response_0.choices[0].message.tool_calls[1].id, +# } + +# messages_value.append(tool_call_result_0) +# messages_value.append(tool_call_result_1) + +# response_1 = openai_client.chat.completions.create( +# messages=messages_value, model=llm_model_value +# ) + +# # sanity check +# assert "stop" in response_1.choices[0].finish_reason + +# # validate both calls +# spans = span_exporter.get_finished_spans() +# assert len(spans) == 2 +# assert_completion_attributes(spans[0], llm_model_value, response_0) +# assert_completion_attributes(spans[1], llm_model_value, response_1) + +# logs = log_exporter.get_finished_logs() +# assert len(logs) == 9 # 3 logs for first completion, 6 for second + +# # call one +# system_message = ( +# {"content": messages_value[0]["content"]} if expect_content else None +# ) +# assert_message_in_logs( +# logs[0], "gen_ai.system.message", system_message, spans[0] +# ) + +# user_message = ( +# {"content": messages_value[1]["content"]} if expect_content else None +# ) +# assert_message_in_logs( +# logs[1], "gen_ai.user.message", user_message, spans[0] +# ) + +# function_call_0 = {"name": "get_current_weather"} +# function_call_1 = {"name": "get_current_weather"} +# if expect_content: +# function_call_0["arguments"] = ( +# response_0.choices[0] +# .message.tool_calls[0] +# .function.arguments.replace("\n", "") +# ) +# function_call_1["arguments"] = ( +# response_0.choices[0] +# .message.tool_calls[1] +# .function.arguments.replace("\n", "") +# ) + +# choice_event = { +# "index": 0, +# "finish_reason": "tool_calls", +# "message": { +# "role": "assistant", +# "tool_calls": [ +# { +# "id": response_0.choices[0].message.tool_calls[0].id, +# "type": "function", +# "function": function_call_0, +# }, +# { +# "id": response_0.choices[0].message.tool_calls[1].id, +# "type": "function", +# "function": function_call_1, +# }, +# ], +# }, +# } +# assert_message_in_logs(logs[2], "gen_ai.choice", choice_event, spans[0]) + +# # call two +# system_message = ( +# {"content": messages_value[0]["content"]} if expect_content else None +# ) +# assert_message_in_logs( +# logs[3], "gen_ai.system.message", system_message, spans[1] +# ) + +# user_message = ( +# {"content": messages_value[1]["content"]} if expect_content else None +# ) +# assert_message_in_logs( +# logs[4], "gen_ai.user.message", user_message, spans[1] +# ) + +# assistant_tool_call = {"tool_calls": messages_value[2]["tool_calls"]} +# if not expect_content: +# assistant_tool_call["tool_calls"][0]["function"]["arguments"] = None +# assistant_tool_call["tool_calls"][1]["function"]["arguments"] = None + +# assert_message_in_logs( +# logs[5], "gen_ai.assistant.message", assistant_tool_call, spans[1] +# ) + +# tool_message_0 = { +# "id": tool_call_result_0["tool_call_id"], +# "content": tool_call_result_0["content"] if expect_content else None, +# } + +# assert_message_in_logs( +# logs[6], "gen_ai.tool.message", tool_message_0, spans[1] +# ) + +# tool_message_1 = { +# "id": tool_call_result_1["tool_call_id"], +# "content": tool_call_result_1["content"] if expect_content else None, +# } + +# assert_message_in_logs( +# logs[7], "gen_ai.tool.message", tool_message_1, spans[1] +# ) + +# message = { +# "role": "assistant", +# "content": response_1.choices[0].message.content +# if expect_content +# else None, +# } +# choice = { +# "index": 0, +# "finish_reason": "stop", +# "message": message, +# } +# assert_message_in_logs(logs[8], "gen_ai.choice", choice, spans[1]) + + +# @pytest.mark.vcr() +# def test_chat_completion_streaming( +# span_exporter, log_exporter, openai_client, instrument_with_content +# ): +# llm_model_value = "gpt-4" +# messages_value = [{"role": "user", "content": "Say this is a test"}] + +# kwargs = { +# "model": llm_model_value, +# "messages": messages_value, +# "stream": True, +# "stream_options": {"include_usage": True}, +# } + +# response_stream_usage = None +# response_stream_model = None +# response_stream_id = None +# response_stream_result = "" +# response = openai_client.chat.completions.create(**kwargs) +# for chunk in response: +# if chunk.choices: +# response_stream_result += chunk.choices[0].delta.content or "" + +# # get the last chunk +# if getattr(chunk, "usage", None): +# response_stream_usage = chunk.usage +# response_stream_model = chunk.model +# response_stream_id = chunk.id + +# spans = span_exporter.get_finished_spans() +# assert_all_attributes( +# spans[0], +# llm_model_value, +# response_stream_id, +# response_stream_model, +# response_stream_usage.prompt_tokens, +# response_stream_usage.completion_tokens, +# ) + +# logs = log_exporter.get_finished_logs() +# assert len(logs) == 2 + +# user_message = {"content": "Say this is a test"} +# assert_message_in_logs( +# logs[0], "gen_ai.user.message", user_message, spans[0] +# ) + +# choice_event = { +# "index": 0, +# "finish_reason": "stop", +# "message": {"role": "assistant", "content": response_stream_result}, +# } +# assert_message_in_logs(logs[1], "gen_ai.choice", choice_event, spans[0]) + + +# @pytest.mark.vcr() +# def test_chat_completion_streaming_not_complete( +# span_exporter, log_exporter, openai_client, instrument_with_content +# ): +# llm_model_value = "gpt-4" +# messages_value = [{"role": "user", "content": "Say this is a test"}] + +# kwargs = { +# "model": llm_model_value, +# "messages": messages_value, +# "stream": True, +# } + +# response_stream_model = None +# response_stream_id = None +# response_stream_result = "" +# response = openai_client.chat.completions.create(**kwargs) +# for idx, chunk in enumerate(response): +# if chunk.choices: +# response_stream_result += chunk.choices[0].delta.content or "" +# if idx == 1: +# # fake a stop +# break + +# if chunk.model: +# response_stream_model = chunk.model +# if chunk.id: +# response_stream_id = chunk.id + +# response.close() +# spans = span_exporter.get_finished_spans() +# assert_all_attributes( +# spans[0], llm_model_value, response_stream_id, response_stream_model +# ) + +# logs = log_exporter.get_finished_logs() +# assert len(logs) == 2 + +# user_message = {"content": "Say this is a test"} +# assert_message_in_logs( +# logs[0], "gen_ai.user.message", user_message, spans[0] +# ) + +# choice_event = { +# "index": 0, +# "finish_reason": "error", +# "message": {"role": "assistant", "content": response_stream_result}, +# } +# assert_message_in_logs(logs[1], "gen_ai.choice", choice_event, spans[0]) + + +# @pytest.mark.vcr() +# def test_chat_completion_multiple_choices_streaming( +# span_exporter, log_exporter, openai_client, instrument_with_content +# ): +# llm_model_value = "gpt-4o-mini" +# messages_value = [ +# {"role": "system", "content": "You're a helpful assistant."}, +# { +# "role": "user", +# "content": "What's the weather in Seattle and San Francisco today?", +# }, +# ] + +# response_0 = openai_client.chat.completions.create( +# messages=messages_value, +# model=llm_model_value, +# n=2, +# stream=True, +# stream_options={"include_usage": True}, +# ) + +# # two strings for each choice +# response_stream_result = ["", ""] +# finish_reasons = ["", ""] +# for chunk in response_0: +# if chunk.choices: +# for choice in chunk.choices: +# response_stream_result[choice.index] += ( +# choice.delta.content or "" +# ) +# if choice.finish_reason: +# finish_reasons[choice.index] = choice.finish_reason + +# # get the last chunk +# if getattr(chunk, "usage", None): +# response_stream_usage = chunk.usage +# response_stream_model = chunk.model +# response_stream_id = chunk.id + +# # sanity check +# assert "stop" == finish_reasons[0] + +# spans = span_exporter.get_finished_spans() +# assert_all_attributes( +# spans[0], +# llm_model_value, +# response_stream_id, +# response_stream_model, +# response_stream_usage.prompt_tokens, +# response_stream_usage.completion_tokens, +# ) + +# logs = log_exporter.get_finished_logs() +# assert len(logs) == 4 + +# system_message = {"content": messages_value[0]["content"]} +# assert_message_in_logs( +# logs[0], "gen_ai.system.message", system_message, spans[0] +# ) + +# user_message = { +# "content": "What's the weather in Seattle and San Francisco today?" +# } +# assert_message_in_logs( +# logs[1], "gen_ai.user.message", user_message, spans[0] +# ) + +# choice_event_0 = { +# "index": 0, +# "finish_reason": "stop", +# "message": { +# "role": "assistant", +# "content": "".join(response_stream_result[0]), +# }, +# } +# assert_message_in_logs(logs[2], "gen_ai.choice", choice_event_0, spans[0]) + +# choice_event_1 = { +# "index": 1, +# "finish_reason": "stop", +# "message": { +# "role": "assistant", +# "content": "".join(response_stream_result[1]), +# }, +# } +# assert_message_in_logs(logs[3], "gen_ai.choice", choice_event_1, spans[0]) + + +# @pytest.mark.vcr() +# def test_chat_completion_multiple_tools_streaming_with_content( +# span_exporter, log_exporter, openai_client, instrument_with_content +# ): +# chat_completion_multiple_tools_streaming( +# span_exporter, log_exporter, openai_client, True +# ) + + +# @pytest.mark.vcr() +# def test_chat_completion_multiple_tools_streaming_no_content( +# span_exporter, log_exporter, openai_client, instrument_no_content +# ): +# chat_completion_multiple_tools_streaming( +# span_exporter, log_exporter, openai_client, False +# ) + + +# def chat_completion_multiple_tools_streaming( +# span_exporter, log_exporter, openai_client, expect_content +# ): +# llm_model_value = "gpt-4o-mini" +# messages_value = [ +# {"role": "system", "content": "You're a helpful assistant."}, +# { +# "role": "user", +# "content": "What's the weather in Seattle and San Francisco today?", +# }, +# ] + +# response = openai_client.chat.completions.create( +# messages=messages_value, +# model=llm_model_value, +# tool_choice="auto", +# tools=[get_current_weather_tool_definition()], +# stream=True, +# stream_options={"include_usage": True}, +# ) + +# finish_reason = None +# # two tools +# tool_names = ["", ""] +# tool_call_ids = ["", ""] +# tool_args = ["", ""] +# for chunk in response: +# if chunk.choices: +# if chunk.choices[0].finish_reason: +# finish_reason = chunk.choices[0].finish_reason +# for tool_call in chunk.choices[0].delta.tool_calls or []: +# t_idx = tool_call.index +# if tool_call.id: +# tool_call_ids[t_idx] = tool_call.id +# if tool_call.function: +# if tool_call.function.arguments: +# tool_args[t_idx] += tool_call.function.arguments +# if tool_call.function.name: +# tool_names[t_idx] = tool_call.function.name + +# # get the last chunk +# if getattr(chunk, "usage", None): +# response_stream_usage = chunk.usage +# response_stream_model = chunk.model +# response_stream_id = chunk.id + +# # sanity check +# assert "tool_calls" == finish_reason + +# spans = span_exporter.get_finished_spans() +# assert_all_attributes( +# spans[0], +# llm_model_value, +# response_stream_id, +# response_stream_model, +# response_stream_usage.prompt_tokens, +# response_stream_usage.completion_tokens, +# ) + +# logs = log_exporter.get_finished_logs() +# assert len(logs) == 3 + +# system_message = ( +# {"content": messages_value[0]["content"]} if expect_content else None +# ) +# assert_message_in_logs( +# logs[0], "gen_ai.system.message", system_message, spans[0] +# ) + +# user_message = ( +# {"content": "What's the weather in Seattle and San Francisco today?"} +# if expect_content +# else None +# ) +# assert_message_in_logs( +# logs[1], "gen_ai.user.message", user_message, spans[0] +# ) + +# choice_event = { +# "index": 0, +# "finish_reason": "tool_calls", +# "message": { +# "role": "assistant", +# "tool_calls": [ +# { +# "id": tool_call_ids[0], +# "type": "function", +# "function": { +# "name": tool_names[0], +# "arguments": tool_args[0].replace("\n", "") +# if expect_content +# else None, +# }, +# }, +# { +# "id": tool_call_ids[1], +# "type": "function", +# "function": { +# "name": tool_names[1], +# "arguments": tool_args[1].replace("\n", "") +# if expect_content +# else None, +# }, +# }, +# ], +# }, +# } +# assert_message_in_logs(logs[2], "gen_ai.choice", choice_event, spans[0]) def assert_message_in_logs(log, event_name, expected_content, parent_span): @@ -724,9 +723,9 @@ def remove_none_values(body): def assert_completion_attributes( span: ReadableSpan, request_model: str, - response: ChatCompletion, + response: ChatResponse, operation_name: str = "chat", - server_address: str = "api.openai.com", + server_address: str = "api.cohere.com", ): return assert_all_attributes( span, @@ -744,11 +743,10 @@ def assert_all_attributes( span: ReadableSpan, request_model: str, response_id: str = None, - response_model: str = None, input_tokens: Optional[int] = None, output_tokens: Optional[int] = None, operation_name: str = "chat", - server_address: str = "api.openai.com", + server_address: str = "api.cohere.com", ): assert span.name == f"{operation_name} {request_model}" assert ( @@ -756,19 +754,12 @@ def assert_all_attributes( == span.attributes[GenAIAttributes.GEN_AI_OPERATION_NAME] ) assert ( - GenAIAttributes.GenAiSystemValues.OPENAI.value + GenAIAttributes.GenAiSystemValues.COHERE.value == span.attributes[GenAIAttributes.GEN_AI_SYSTEM] ) assert ( request_model == span.attributes[GenAIAttributes.GEN_AI_REQUEST_MODEL] ) - if response_model: - assert ( - response_model - == span.attributes[GenAIAttributes.GEN_AI_RESPONSE_MODEL] - ) - else: - assert GenAIAttributes.GEN_AI_RESPONSE_MODEL not in span.attributes if response_id: assert ( diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py index 0f91e4acb7..3635e474ed 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py @@ -30,7 +30,6 @@ from .utils import ( choice_to_event, get_llm_request_attributes, - handle_span_exception, is_streaming, message_to_event, set_span_attribute, diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py index 429af15a35..4b462a1bcc 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py @@ -27,18 +27,6 @@ server_attributes as ServerAttributes, ) -OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT = ( - "OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT" -) - - -def is_content_enabled() -> bool: - capture_content = environ.get( - OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT, "false" - ) - - return capture_content.lower() == "true" - def extract_tool_calls(item, capture_content): tool_calls = get_property_value(item, "tool_calls") diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py index 7ff7e46777..8979d1933a 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py @@ -7,10 +7,10 @@ import yaml from openai import AsyncOpenAI, OpenAI -from opentelemetry.instrumentation.openai_v2 import OpenAIInstrumentor -from opentelemetry.instrumentation.openai_v2.utils import ( +from opentelemetry.instrumentation.genai_utils import ( OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT, ) +from opentelemetry.instrumentation.openai_v2 import OpenAIInstrumentor from opentelemetry.sdk._events import EventLoggerProvider from opentelemetry.sdk._logs import LoggerProvider from opentelemetry.sdk._logs.export import ( From 9a2a0ec8d0a98c52b61cb5969b47c6867cdd0f52 Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Mon, 9 Dec 2024 13:09:18 -0800 Subject: [PATCH 5/9] chat --- .../opentelemetry/instrumentation/cohere_v2/utils.py | 2 +- .../cassettes/test_chat_completion_with_content.yaml | 10 +++++----- .../tests/test_chat_completions.py | 7 +++---- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/utils.py b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/utils.py index 51ebc43dde..582acbe3c0 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/utils.py +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/utils.py @@ -69,7 +69,7 @@ def get_property_value(obj, property_name): def set_server_address_and_port(client_instance: cohere.client_v2.V2Client, attributes): base_client = getattr(client_instance, "_client_wrapper", None) - base_url = getattr(base_client, "base_url", None) + base_url = getattr(base_client, "_base_url", None) if not base_url: return diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_with_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_with_content.yaml index 7d16c8a6a8..f8fa1acaa1 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_with_content.yaml +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_with_content.yaml @@ -40,7 +40,7 @@ interactions: body: string: |- { - "id": "78c201dd-0f3d-43c4-a245-5ab6d28636ef", + "id": "06e43724-5286-4eeb-bb10-bad73f976655", "message": { "role": "assistant", "content": [ @@ -77,7 +77,7 @@ interactions: content-type: - application/json date: - - Mon, 09 Dec 2024 19:22:13 GMT + - Mon, 09 Dec 2024 21:08:41 GMT expires: - Thu, 01 Jan 1970 00:00:00 UTC num_chars: @@ -93,15 +93,15 @@ interactions: x-accel-expires: - '0' x-debug-trace-id: - - 5bf598783ce550fab3dbd3c54bd617e7 + - 52412790708b1cfbe79a11850fbc09ec x-endpoint-monthly-call-limit: - '1000' x-envoy-upstream-service-time: - - '212' + - '173' x-trial-endpoint-call-limit: - '40' x-trial-endpoint-call-remaining: - - '39' + - '37' status: code: 200 message: OK diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/test_chat_completions.py b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/test_chat_completions.py index 9965c1e9d6..cf9491141a 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/test_chat_completions.py +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/test_chat_completions.py @@ -35,7 +35,7 @@ @pytest.mark.vcr() def test_chat_completion_with_content( - span_exporter, log_exporter, cohere_client, instrument_with_content, tracer_provider + span_exporter, log_exporter, instrument_with_content, cohere_client ): llm_model_value = "command-r-plus" messages_value = [{"role": "user", "content": "Say this is a test"}] @@ -731,9 +731,8 @@ def assert_completion_attributes( span, request_model, response.id, - response.model, - response.usage.prompt_tokens, - response.usage.completion_tokens, + response.usage.tokens.input_tokens, + response.usage.tokens.output_tokens, operation_name, server_address, ) From 1afcae5d62b57961c004fec863eb0f039be16a1d Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Mon, 9 Dec 2024 13:37:32 -0800 Subject: [PATCH 6/9] test --- .../instrumentation/cohere_v2/utils.py | 10 +- .../test_chat_completion_with_content.yaml | 10 +- .../tests/test_chat_completions.py | 697 +----------------- 3 files changed, 26 insertions(+), 691 deletions(-) diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/utils.py b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/utils.py index 582acbe3c0..4cae63eed4 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/utils.py +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/utils.py @@ -181,13 +181,9 @@ def _response_to_event(response: cohere.ChatResponse, capture_content): } if response.message: - message = { - "role": ( - response.message.role - if response.message.role and response.message.role != "assistant" - else None - ) - } + message = {} + if response.message.role and response.message.role != "assistant": + message["role"] = response.message.role tool_calls = extract_tool_calls(response.message, capture_content) if tool_calls: message["tool_calls"] = tool_calls diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_with_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_with_content.yaml index f8fa1acaa1..030685c311 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_with_content.yaml +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_with_content.yaml @@ -40,7 +40,7 @@ interactions: body: string: |- { - "id": "06e43724-5286-4eeb-bb10-bad73f976655", + "id": "e7d8e128-c2b6-452b-9274-a52298d4e279", "message": { "role": "assistant", "content": [ @@ -77,7 +77,7 @@ interactions: content-type: - application/json date: - - Mon, 09 Dec 2024 21:08:41 GMT + - Mon, 09 Dec 2024 21:18:26 GMT expires: - Thu, 01 Jan 1970 00:00:00 UTC num_chars: @@ -93,15 +93,15 @@ interactions: x-accel-expires: - '0' x-debug-trace-id: - - 52412790708b1cfbe79a11850fbc09ec + - afec42690070e90f99584d392dcd1d5d x-endpoint-monthly-call-limit: - '1000' x-envoy-upstream-service-time: - - '173' + - '192' x-trial-endpoint-call-limit: - '40' x-trial-endpoint-call-remaining: - - '37' + - '39' status: code: 200 message: OK diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/test_chat_completions.py b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/test_chat_completions.py index cf9491141a..a910d1685b 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/test_chat_completions.py +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/test_chat_completions.py @@ -45,682 +45,42 @@ def test_chat_completion_with_content( ) spans = span_exporter.get_finished_spans() - assert_completion_attributes(spans[0], llm_model_value, response) + assert_chat_attributes(spans[0], llm_model_value, response) - # logs = log_exporter.get_finished_logs() - # assert len(logs) == 2 + logs = log_exporter.get_finished_logs() + assert len(logs) == 2 - # user_message = {"content": messages_value[0]["content"]} - # assert_message_in_logs( - # logs[0], "gen_ai.user.message", user_message, spans[0] - # ) - - # choice_event = { - # "index": 0, - # "finish_reason": "stop", - # "message": { - # "role": "assistant", - # "content": response.choices[0].message.content, - # }, - # } - # assert_message_in_logs(logs[1], "gen_ai.choice", choice_event, spans[0]) - - -# def test_chat_completion_bad_endpoint(span_exporter, instrument_no_content): -# llm_model_value = "gpt-4o-mini" -# messages_value = [{"role": "user", "content": "Say this is a test"}] - -# client = OpenAI(base_url="http://localhost:4242") - -# with pytest.raises(APIConnectionError): -# client.chat.completions.create( -# messages=messages_value, -# model=llm_model_value, -# timeout=0.1, -# ) - -# spans = span_exporter.get_finished_spans() -# assert_all_attributes( -# spans[0], llm_model_value, server_address="localhost" -# ) -# assert 4242 == spans[0].attributes[ServerAttributes.SERVER_PORT] -# assert ( -# "APIConnectionError" == spans[0].attributes[ErrorAttributes.ERROR_TYPE] -# ) - - -# @pytest.mark.vcr() -# def test_chat_completion_404( -# span_exporter, openai_client, instrument_no_content -# ): -# llm_model_value = "this-model-does-not-exist" -# messages_value = [{"role": "user", "content": "Say this is a test"}] - -# with pytest.raises(NotFoundError): -# openai_client.chat.completions.create( -# messages=messages_value, -# model=llm_model_value, -# ) - -# spans = span_exporter.get_finished_spans() - -# assert_all_attributes(spans[0], llm_model_value) -# assert "NotFoundError" == spans[0].attributes[ErrorAttributes.ERROR_TYPE] - - -# @pytest.mark.vcr() -# def test_chat_completion_extra_params( -# span_exporter, openai_client, instrument_no_content -# ): -# llm_model_value = "gpt-4o-mini" -# messages_value = [{"role": "user", "content": "Say this is a test"}] - -# response = openai_client.chat.completions.create( -# messages=messages_value, -# model=llm_model_value, -# seed=42, -# temperature=0.5, -# max_tokens=50, -# stream=False, -# extra_body={"service_tier": "default"}, -# ) - -# spans = span_exporter.get_finished_spans() -# assert_completion_attributes(spans[0], llm_model_value, response) -# assert ( -# spans[0].attributes[GenAIAttributes.GEN_AI_OPENAI_REQUEST_SEED] == 42 -# ) -# assert ( -# spans[0].attributes[GenAIAttributes.GEN_AI_REQUEST_TEMPERATURE] == 0.5 -# ) -# assert spans[0].attributes[GenAIAttributes.GEN_AI_REQUEST_MAX_TOKENS] == 50 -# assert ( -# spans[0].attributes[GenAIAttributes.GEN_AI_OPENAI_REQUEST_SERVICE_TIER] -# == "default" -# ) - - -# @pytest.mark.vcr() -# def test_chat_completion_multiple_choices( -# span_exporter, log_exporter, openai_client, instrument_with_content -# ): -# llm_model_value = "gpt-4o-mini" -# messages_value = [{"role": "user", "content": "Say this is a test"}] - -# response = openai_client.chat.completions.create( -# messages=messages_value, model=llm_model_value, n=2, stream=False -# ) - -# spans = span_exporter.get_finished_spans() -# assert_completion_attributes(spans[0], llm_model_value, response) - -# logs = log_exporter.get_finished_logs() -# assert len(logs) == 3 # 1 user message + 2 choice messages - -# user_message = {"content": messages_value[0]["content"]} -# assert_message_in_logs( -# logs[0], "gen_ai.user.message", user_message, spans[0] -# ) - -# choice_event_0 = { -# "index": 0, -# "finish_reason": "stop", -# "message": { -# "role": "assistant", -# "content": response.choices[0].message.content, -# }, -# } -# assert_message_in_logs(logs[1], "gen_ai.choice", choice_event_0, spans[0]) - -# choice_event_1 = { -# "index": 1, -# "finish_reason": "stop", -# "message": { -# "role": "assistant", -# "content": response.choices[1].message.content, -# }, -# } -# assert_message_in_logs(logs[2], "gen_ai.choice", choice_event_1, spans[0]) - - -# @pytest.mark.vcr() -# def test_chat_completion_tool_calls_with_content( -# span_exporter, log_exporter, openai_client, instrument_with_content -# ): -# chat_completion_tool_call(span_exporter, log_exporter, openai_client, True) - - -# @pytest.mark.vcr() -# def test_chat_completion_tool_calls_no_content( -# span_exporter, log_exporter, openai_client, instrument_no_content -# ): -# chat_completion_tool_call( -# span_exporter, log_exporter, openai_client, False -# ) - - -# def chat_completion_tool_call( -# span_exporter, log_exporter, openai_client, expect_content -# ): -# llm_model_value = "gpt-4o-mini" -# messages_value = [ -# {"role": "system", "content": "You're a helpful assistant."}, -# { -# "role": "user", -# "content": "What's the weather in Seattle and San Francisco today?", -# }, -# ] - -# response_0 = openai_client.chat.completions.create( -# messages=messages_value, -# model=llm_model_value, -# tool_choice="auto", -# tools=[get_current_weather_tool_definition()], -# ) - -# # sanity check -# assert "tool_calls" in response_0.choices[0].finish_reason - -# # final request -# messages_value.append( -# { -# "role": "assistant", -# "tool_calls": response_0.choices[0].message.to_dict()[ -# "tool_calls" -# ], -# } -# ) - -# tool_call_result_0 = { -# "role": "tool", -# "content": "50 degrees and raining", -# "tool_call_id": response_0.choices[0].message.tool_calls[0].id, -# } -# tool_call_result_1 = { -# "role": "tool", -# "content": "70 degrees and sunny", -# "tool_call_id": response_0.choices[0].message.tool_calls[1].id, -# } - -# messages_value.append(tool_call_result_0) -# messages_value.append(tool_call_result_1) - -# response_1 = openai_client.chat.completions.create( -# messages=messages_value, model=llm_model_value -# ) - -# # sanity check -# assert "stop" in response_1.choices[0].finish_reason - -# # validate both calls -# spans = span_exporter.get_finished_spans() -# assert len(spans) == 2 -# assert_completion_attributes(spans[0], llm_model_value, response_0) -# assert_completion_attributes(spans[1], llm_model_value, response_1) - -# logs = log_exporter.get_finished_logs() -# assert len(logs) == 9 # 3 logs for first completion, 6 for second - -# # call one -# system_message = ( -# {"content": messages_value[0]["content"]} if expect_content else None -# ) -# assert_message_in_logs( -# logs[0], "gen_ai.system.message", system_message, spans[0] -# ) - -# user_message = ( -# {"content": messages_value[1]["content"]} if expect_content else None -# ) -# assert_message_in_logs( -# logs[1], "gen_ai.user.message", user_message, spans[0] -# ) - -# function_call_0 = {"name": "get_current_weather"} -# function_call_1 = {"name": "get_current_weather"} -# if expect_content: -# function_call_0["arguments"] = ( -# response_0.choices[0] -# .message.tool_calls[0] -# .function.arguments.replace("\n", "") -# ) -# function_call_1["arguments"] = ( -# response_0.choices[0] -# .message.tool_calls[1] -# .function.arguments.replace("\n", "") -# ) - -# choice_event = { -# "index": 0, -# "finish_reason": "tool_calls", -# "message": { -# "role": "assistant", -# "tool_calls": [ -# { -# "id": response_0.choices[0].message.tool_calls[0].id, -# "type": "function", -# "function": function_call_0, -# }, -# { -# "id": response_0.choices[0].message.tool_calls[1].id, -# "type": "function", -# "function": function_call_1, -# }, -# ], -# }, -# } -# assert_message_in_logs(logs[2], "gen_ai.choice", choice_event, spans[0]) - -# # call two -# system_message = ( -# {"content": messages_value[0]["content"]} if expect_content else None -# ) -# assert_message_in_logs( -# logs[3], "gen_ai.system.message", system_message, spans[1] -# ) - -# user_message = ( -# {"content": messages_value[1]["content"]} if expect_content else None -# ) -# assert_message_in_logs( -# logs[4], "gen_ai.user.message", user_message, spans[1] -# ) - -# assistant_tool_call = {"tool_calls": messages_value[2]["tool_calls"]} -# if not expect_content: -# assistant_tool_call["tool_calls"][0]["function"]["arguments"] = None -# assistant_tool_call["tool_calls"][1]["function"]["arguments"] = None - -# assert_message_in_logs( -# logs[5], "gen_ai.assistant.message", assistant_tool_call, spans[1] -# ) - -# tool_message_0 = { -# "id": tool_call_result_0["tool_call_id"], -# "content": tool_call_result_0["content"] if expect_content else None, -# } - -# assert_message_in_logs( -# logs[6], "gen_ai.tool.message", tool_message_0, spans[1] -# ) - -# tool_message_1 = { -# "id": tool_call_result_1["tool_call_id"], -# "content": tool_call_result_1["content"] if expect_content else None, -# } - -# assert_message_in_logs( -# logs[7], "gen_ai.tool.message", tool_message_1, spans[1] -# ) - -# message = { -# "role": "assistant", -# "content": response_1.choices[0].message.content -# if expect_content -# else None, -# } -# choice = { -# "index": 0, -# "finish_reason": "stop", -# "message": message, -# } -# assert_message_in_logs(logs[8], "gen_ai.choice", choice, spans[1]) - - -# @pytest.mark.vcr() -# def test_chat_completion_streaming( -# span_exporter, log_exporter, openai_client, instrument_with_content -# ): -# llm_model_value = "gpt-4" -# messages_value = [{"role": "user", "content": "Say this is a test"}] - -# kwargs = { -# "model": llm_model_value, -# "messages": messages_value, -# "stream": True, -# "stream_options": {"include_usage": True}, -# } - -# response_stream_usage = None -# response_stream_model = None -# response_stream_id = None -# response_stream_result = "" -# response = openai_client.chat.completions.create(**kwargs) -# for chunk in response: -# if chunk.choices: -# response_stream_result += chunk.choices[0].delta.content or "" - -# # get the last chunk -# if getattr(chunk, "usage", None): -# response_stream_usage = chunk.usage -# response_stream_model = chunk.model -# response_stream_id = chunk.id - -# spans = span_exporter.get_finished_spans() -# assert_all_attributes( -# spans[0], -# llm_model_value, -# response_stream_id, -# response_stream_model, -# response_stream_usage.prompt_tokens, -# response_stream_usage.completion_tokens, -# ) - -# logs = log_exporter.get_finished_logs() -# assert len(logs) == 2 - -# user_message = {"content": "Say this is a test"} -# assert_message_in_logs( -# logs[0], "gen_ai.user.message", user_message, spans[0] -# ) - -# choice_event = { -# "index": 0, -# "finish_reason": "stop", -# "message": {"role": "assistant", "content": response_stream_result}, -# } -# assert_message_in_logs(logs[1], "gen_ai.choice", choice_event, spans[0]) - - -# @pytest.mark.vcr() -# def test_chat_completion_streaming_not_complete( -# span_exporter, log_exporter, openai_client, instrument_with_content -# ): -# llm_model_value = "gpt-4" -# messages_value = [{"role": "user", "content": "Say this is a test"}] - -# kwargs = { -# "model": llm_model_value, -# "messages": messages_value, -# "stream": True, -# } - -# response_stream_model = None -# response_stream_id = None -# response_stream_result = "" -# response = openai_client.chat.completions.create(**kwargs) -# for idx, chunk in enumerate(response): -# if chunk.choices: -# response_stream_result += chunk.choices[0].delta.content or "" -# if idx == 1: -# # fake a stop -# break - -# if chunk.model: -# response_stream_model = chunk.model -# if chunk.id: -# response_stream_id = chunk.id - -# response.close() -# spans = span_exporter.get_finished_spans() -# assert_all_attributes( -# spans[0], llm_model_value, response_stream_id, response_stream_model -# ) - -# logs = log_exporter.get_finished_logs() -# assert len(logs) == 2 - -# user_message = {"content": "Say this is a test"} -# assert_message_in_logs( -# logs[0], "gen_ai.user.message", user_message, spans[0] -# ) - -# choice_event = { -# "index": 0, -# "finish_reason": "error", -# "message": {"role": "assistant", "content": response_stream_result}, -# } -# assert_message_in_logs(logs[1], "gen_ai.choice", choice_event, spans[0]) - - -# @pytest.mark.vcr() -# def test_chat_completion_multiple_choices_streaming( -# span_exporter, log_exporter, openai_client, instrument_with_content -# ): -# llm_model_value = "gpt-4o-mini" -# messages_value = [ -# {"role": "system", "content": "You're a helpful assistant."}, -# { -# "role": "user", -# "content": "What's the weather in Seattle and San Francisco today?", -# }, -# ] - -# response_0 = openai_client.chat.completions.create( -# messages=messages_value, -# model=llm_model_value, -# n=2, -# stream=True, -# stream_options={"include_usage": True}, -# ) - -# # two strings for each choice -# response_stream_result = ["", ""] -# finish_reasons = ["", ""] -# for chunk in response_0: -# if chunk.choices: -# for choice in chunk.choices: -# response_stream_result[choice.index] += ( -# choice.delta.content or "" -# ) -# if choice.finish_reason: -# finish_reasons[choice.index] = choice.finish_reason - -# # get the last chunk -# if getattr(chunk, "usage", None): -# response_stream_usage = chunk.usage -# response_stream_model = chunk.model -# response_stream_id = chunk.id - -# # sanity check -# assert "stop" == finish_reasons[0] - -# spans = span_exporter.get_finished_spans() -# assert_all_attributes( -# spans[0], -# llm_model_value, -# response_stream_id, -# response_stream_model, -# response_stream_usage.prompt_tokens, -# response_stream_usage.completion_tokens, -# ) - -# logs = log_exporter.get_finished_logs() -# assert len(logs) == 4 - -# system_message = {"content": messages_value[0]["content"]} -# assert_message_in_logs( -# logs[0], "gen_ai.system.message", system_message, spans[0] -# ) - -# user_message = { -# "content": "What's the weather in Seattle and San Francisco today?" -# } -# assert_message_in_logs( -# logs[1], "gen_ai.user.message", user_message, spans[0] -# ) - -# choice_event_0 = { -# "index": 0, -# "finish_reason": "stop", -# "message": { -# "role": "assistant", -# "content": "".join(response_stream_result[0]), -# }, -# } -# assert_message_in_logs(logs[2], "gen_ai.choice", choice_event_0, spans[0]) - -# choice_event_1 = { -# "index": 1, -# "finish_reason": "stop", -# "message": { -# "role": "assistant", -# "content": "".join(response_stream_result[1]), -# }, -# } -# assert_message_in_logs(logs[3], "gen_ai.choice", choice_event_1, spans[0]) - - -# @pytest.mark.vcr() -# def test_chat_completion_multiple_tools_streaming_with_content( -# span_exporter, log_exporter, openai_client, instrument_with_content -# ): -# chat_completion_multiple_tools_streaming( -# span_exporter, log_exporter, openai_client, True -# ) - - -# @pytest.mark.vcr() -# def test_chat_completion_multiple_tools_streaming_no_content( -# span_exporter, log_exporter, openai_client, instrument_no_content -# ): -# chat_completion_multiple_tools_streaming( -# span_exporter, log_exporter, openai_client, False -# ) - - -# def chat_completion_multiple_tools_streaming( -# span_exporter, log_exporter, openai_client, expect_content -# ): -# llm_model_value = "gpt-4o-mini" -# messages_value = [ -# {"role": "system", "content": "You're a helpful assistant."}, -# { -# "role": "user", -# "content": "What's the weather in Seattle and San Francisco today?", -# }, -# ] - -# response = openai_client.chat.completions.create( -# messages=messages_value, -# model=llm_model_value, -# tool_choice="auto", -# tools=[get_current_weather_tool_definition()], -# stream=True, -# stream_options={"include_usage": True}, -# ) - -# finish_reason = None -# # two tools -# tool_names = ["", ""] -# tool_call_ids = ["", ""] -# tool_args = ["", ""] -# for chunk in response: -# if chunk.choices: -# if chunk.choices[0].finish_reason: -# finish_reason = chunk.choices[0].finish_reason -# for tool_call in chunk.choices[0].delta.tool_calls or []: -# t_idx = tool_call.index -# if tool_call.id: -# tool_call_ids[t_idx] = tool_call.id -# if tool_call.function: -# if tool_call.function.arguments: -# tool_args[t_idx] += tool_call.function.arguments -# if tool_call.function.name: -# tool_names[t_idx] = tool_call.function.name - -# # get the last chunk -# if getattr(chunk, "usage", None): -# response_stream_usage = chunk.usage -# response_stream_model = chunk.model -# response_stream_id = chunk.id - -# # sanity check -# assert "tool_calls" == finish_reason - -# spans = span_exporter.get_finished_spans() -# assert_all_attributes( -# spans[0], -# llm_model_value, -# response_stream_id, -# response_stream_model, -# response_stream_usage.prompt_tokens, -# response_stream_usage.completion_tokens, -# ) - -# logs = log_exporter.get_finished_logs() -# assert len(logs) == 3 - -# system_message = ( -# {"content": messages_value[0]["content"]} if expect_content else None -# ) -# assert_message_in_logs( -# logs[0], "gen_ai.system.message", system_message, spans[0] -# ) - -# user_message = ( -# {"content": "What's the weather in Seattle and San Francisco today?"} -# if expect_content -# else None -# ) -# assert_message_in_logs( -# logs[1], "gen_ai.user.message", user_message, spans[0] -# ) + user_message = {"content": messages_value[0]["content"]} + assert_message_in_logs( + logs[0], "gen_ai.user.message", user_message, spans[0] + ) -# choice_event = { -# "index": 0, -# "finish_reason": "tool_calls", -# "message": { -# "role": "assistant", -# "tool_calls": [ -# { -# "id": tool_call_ids[0], -# "type": "function", -# "function": { -# "name": tool_names[0], -# "arguments": tool_args[0].replace("\n", "") -# if expect_content -# else None, -# }, -# }, -# { -# "id": tool_call_ids[1], -# "type": "function", -# "function": { -# "name": tool_names[1], -# "arguments": tool_args[1].replace("\n", "") -# if expect_content -# else None, -# }, -# }, -# ], -# }, -# } -# assert_message_in_logs(logs[2], "gen_ai.choice", choice_event, spans[0]) + response_event = { + "id": response.id, + "finish_reason": "COMPLETE", + "message": { + "content": response.message.content, + }, + } + assert_message_in_logs(logs[1], "gen_ai.choice", response_event, spans[0]) def assert_message_in_logs(log, event_name, expected_content, parent_span): assert log.log_record.attributes[EventAttributes.EVENT_NAME] == event_name assert ( log.log_record.attributes[GenAIAttributes.GEN_AI_SYSTEM] - == GenAIAttributes.GenAiSystemValues.OPENAI.value + == GenAIAttributes.GenAiSystemValues.COHERE.value ) if not expected_content: assert not log.log_record.body else: assert log.log_record.body - assert dict(log.log_record.body) == remove_none_values( - expected_content - ) + assert dict(log.log_record.body) == expected_content assert_log_parent(log, parent_span) -def remove_none_values(body): - result = {} - for key, value in body.items(): - if value is None: - continue - if isinstance(value, dict): - result[key] = remove_none_values(value) - elif isinstance(value, list): - result[key] = [remove_none_values(i) for i in value] - else: - result[key] = value - return result - - -def assert_completion_attributes( +def assert_chat_attributes( span: ReadableSpan, request_model: str, response: ChatResponse, @@ -792,24 +152,3 @@ def assert_log_parent(log, span): assert log.log_record.trace_id == span.get_span_context().trace_id assert log.log_record.span_id == span.get_span_context().span_id assert log.log_record.trace_flags == span.get_span_context().trace_flags - - -def get_current_weather_tool_definition(): - return { - "type": "function", - "function": { - "name": "get_current_weather", - "description": "Get the current weather in a given location", - "parameters": { - "type": "object", - "properties": { - "location": { - "type": "string", - "description": "The city and state, e.g. Boston, MA", - }, - }, - "required": ["location"], - "additionalProperties": False, - }, - }, - } From 7ef434585f14fe42dc8c61de6e86b500084fc0c8 Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Mon, 9 Dec 2024 13:38:51 -0800 Subject: [PATCH 7/9] test --- ...tion_with_content.yaml => test_chat_with_content.yaml} | 8 ++++---- .../{test_chat_completions.py => test_client_chat.py} | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) rename instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/{test_chat_completion_with_content.yaml => test_chat_with_content.yaml} (93%) rename instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/{test_chat_completions.py => test_client_chat.py} (99%) diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_with_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_with_content.yaml similarity index 93% rename from instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_with_content.yaml rename to instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_with_content.yaml index 030685c311..5bd178b8bf 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_completion_with_content.yaml +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_with_content.yaml @@ -40,7 +40,7 @@ interactions: body: string: |- { - "id": "e7d8e128-c2b6-452b-9274-a52298d4e279", + "id": "d6c6c01a-e089-47be-aa35-8e342a2425e6", "message": { "role": "assistant", "content": [ @@ -77,7 +77,7 @@ interactions: content-type: - application/json date: - - Mon, 09 Dec 2024 21:18:26 GMT + - Mon, 09 Dec 2024 21:38:34 GMT expires: - Thu, 01 Jan 1970 00:00:00 UTC num_chars: @@ -93,11 +93,11 @@ interactions: x-accel-expires: - '0' x-debug-trace-id: - - afec42690070e90f99584d392dcd1d5d + - 5f3eace25a51f8493ce35165bd0e83e6 x-endpoint-monthly-call-limit: - '1000' x-envoy-upstream-service-time: - - '192' + - '196' x-trial-endpoint-call-limit: - '40' x-trial-endpoint-call-remaining: diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/test_chat_completions.py b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/test_client_chat.py similarity index 99% rename from instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/test_chat_completions.py rename to instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/test_client_chat.py index a910d1685b..4d2d719e75 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/test_chat_completions.py +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/test_client_chat.py @@ -34,7 +34,7 @@ @pytest.mark.vcr() -def test_chat_completion_with_content( +def test_chat_with_content( span_exporter, log_exporter, instrument_with_content, cohere_client ): llm_model_value = "command-r-plus" From 5012b8d0d241627332794d1b28446ec217dbb573 Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Tue, 10 Dec 2024 08:05:00 -0800 Subject: [PATCH 8/9] chat --- .../CHANGELOG.md | 2 +- .../example/main.py | 4 +--- .../tests/cassettes/test_chat_with_content.yaml | 10 +++++----- .../tests/conftest.py | 1 + 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/CHANGELOG.md b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/CHANGELOG.md index f3f2bd3f56..3bd68460ea 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/CHANGELOG.md +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/CHANGELOG.md @@ -8,4 +8,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased - Initial Cohere instrumentation - ([#2759](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2759)) + ([#3081](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3081)) diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/example/main.py b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/example/main.py index 6e7ded4dc9..78eed6d518 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/example/main.py +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/example/main.py @@ -1,7 +1,5 @@ import cohere -import openai -import openai.resources from opentelemetry import trace from opentelemetry.instrumentation.cohere_v2 import CohereInstrumentor from opentelemetry.sdk.trace import TracerProvider @@ -18,7 +16,7 @@ ) tracer = trace.get_tracer(__name__) -co = cohere.ClientV2('Z4EInAKRbIRKQV9lRZTciJqYyUBHXZGVUOAFBlRJ') +co = cohere.ClientV2() with tracer.start_as_current_span("foo"): response = co.chat( diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_with_content.yaml b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_with_content.yaml index 5bd178b8bf..95650ec93f 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_with_content.yaml +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/cassettes/test_chat_with_content.yaml @@ -17,7 +17,7 @@ interactions: accept-encoding: - gzip, deflate authorization: - - Bearer Z4EInAKRbIRKQV9lRZTciJqYyUBHXZGVUOAFBlRJ + - Bearer test_cohere_api_key connection: - keep-alive content-length: @@ -40,7 +40,7 @@ interactions: body: string: |- { - "id": "d6c6c01a-e089-47be-aa35-8e342a2425e6", + "id": "68d63b3a-360d-4460-9cb9-8413ef2adc52", "message": { "role": "assistant", "content": [ @@ -77,7 +77,7 @@ interactions: content-type: - application/json date: - - Mon, 09 Dec 2024 21:38:34 GMT + - Tue, 10 Dec 2024 16:04:21 GMT expires: - Thu, 01 Jan 1970 00:00:00 UTC num_chars: @@ -93,11 +93,11 @@ interactions: x-accel-expires: - '0' x-debug-trace-id: - - 5f3eace25a51f8493ce35165bd0e83e6 + - 90f329169476c8dd3d7bf0071236f7f8 x-endpoint-monthly-call-limit: - '1000' x-envoy-upstream-service-time: - - '196' + - '188' x-trial-endpoint-call-limit: - '40' x-trial-endpoint-call-remaining: diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/conftest.py b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/conftest.py index 0dbed6a00b..318d62548d 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/conftest.py +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/tests/conftest.py @@ -68,6 +68,7 @@ def vcr_config(): return { "filter_headers": [ ("cookie", "test_cookie"), + ("authorization", "Bearer test_cohere_api_key"), ], "decode_compressed_response": True, "before_record_response": scrub_response_headers, From 045215c5f1bbbe3b64ab1aa91145fc0a8eae8f44 Mon Sep 17 00:00:00 2001 From: Leighton Chen Date: Thu, 19 Dec 2024 09:02:17 -0800 Subject: [PATCH 9/9] feedback --- .../src/opentelemetry/instrumentation/cohere_v2/__init__.py | 2 +- .../src/opentelemetry/instrumentation/cohere_v2/patch.py | 4 ++-- .../src/opentelemetry/instrumentation/cohere_v2/utils.py | 4 ++-- .../src/opentelemetry/instrumentation/openai_v2/patch.py | 6 +++--- .../src/opentelemetry/instrumentation/openai_v2/utils.py | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/__init__.py b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/__init__.py index 74a60952c4..fedcc04b89 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/__init__.py +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/__init__.py @@ -90,4 +90,4 @@ def _instrument(self, **kwargs): def _uninstrument(self, **kwargs): import cohere # pylint: disable=import-outside-toplevel - unwrap(cohere.client_v2.ClientV2, "chat") + unwrap("cohere.client_v2.ClientV2", "chat") diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/patch.py b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/patch.py index 70f4c22b57..e117899d04 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/patch.py +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/patch.py @@ -20,7 +20,7 @@ ) from opentelemetry.instrumentation.utils import is_instrumentation_enabled from .utils import ( - get_llm_request_attributes, + get_genai_request_attributes, message_to_event, set_response_attributes, set_server_address_and_port, @@ -36,7 +36,7 @@ def traced_method(wrapped, instance, args, kwargs): if not is_instrumentation_enabled(): return wrapped(*args, **kwargs) - span_attributes = {**get_llm_request_attributes(kwargs, instance)} + span_attributes = {**get_genai_request_attributes(kwargs, instance)} set_server_address_and_port(instance, span_attributes) span_name = get_span_name(span_attributes) diff --git a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/utils.py b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/utils.py index 4cae63eed4..26e46005d5 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/utils.py +++ b/instrumentation-genai/opentelemetry-instrumentation-cohere-v2/src/opentelemetry/instrumentation/cohere_v2/utils.py @@ -82,7 +82,7 @@ def set_server_address_and_port(client_instance: cohere.client_v2.V2Client, attr attributes[ServerAttributes.SERVER_PORT] = port -def get_llm_request_attributes( +def get_genai_request_attributes( kwargs, client_instance: cohere.client_v2.V2Client, operation_name=GenAIAttributes.GenAiOperationNameValues.CHAT.value, @@ -92,7 +92,7 @@ def get_llm_request_attributes( GenAIAttributes.GEN_AI_SYSTEM: GenAIAttributes.GenAiSystemValues.COHERE.value, GenAIAttributes.GEN_AI_REQUEST_MODEL: kwargs.get("model"), GenAIAttributes.GEN_AI_REQUEST_MAX_TOKENS: kwargs.get("max_tokens"), - GenAIAttributes.GEN_AI_REQUEST_FREQUENCY_PENALTY: kwargs.get( + GenAIAttributes.GEN_AI_REQUEST_STOP_SEQUENCES: kwargs.get( "stop_sequences" ), GenAIAttributes.GEN_AI_REQUEST_TEMPERATURE: kwargs.get("temperature"), diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py index 3635e474ed..4f56bc6c8f 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/patch.py @@ -29,7 +29,7 @@ from .utils import ( choice_to_event, - get_llm_request_attributes, + get_genai_request_attributes, is_streaming, message_to_event, set_span_attribute, @@ -42,7 +42,7 @@ def chat_completions_create( """Wrap the `create` method of the `ChatCompletion` class to trace it.""" def traced_method(wrapped, instance, args, kwargs): - span_attributes = {**get_llm_request_attributes(kwargs, instance)} + span_attributes = {**get_genai_request_attributes(kwargs, instance)} span_name = get_span_name(span_attributes) with tracer.start_as_current_span( @@ -84,7 +84,7 @@ def async_chat_completions_create( """Wrap the `create` method of the `AsyncChatCompletion` class to trace it.""" async def traced_method(wrapped, instance, args, kwargs): - span_attributes = {**get_llm_request_attributes(kwargs, instance)} + span_attributes = {**get_genai_request_attributes(kwargs, instance)} span_name = f"{span_attributes[GenAIAttributes.GEN_AI_OPERATION_NAME]} {span_attributes[GenAIAttributes.GEN_AI_REQUEST_MODEL]}" with tracer.start_as_current_span( diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py index 2ae6dcdecc..809e1fad6d 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py +++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/utils.py @@ -167,7 +167,7 @@ def non_numerical_value_is_set(value: Optional[Union[bool, str]]): return bool(value) and value != NOT_GIVEN -def get_llm_request_attributes( +def get_genai_request_attributes( kwargs, client_instance, operation_name=GenAIAttributes.GenAiOperationNameValues.CHAT.value,