From 96db8439da177385a6ac86d07753976e4cd2c52d Mon Sep 17 00:00:00 2001 From: Din Date: Sun, 14 Sep 2025 04:28:57 +0100 Subject: [PATCH 1/4] fix(cohere): add v2 api instrumentation --- .../instrumentation/cohere/__init__.py | 256 ++++- .../instrumentation/cohere/span_utils.py | 218 ++++- .../instrumentation/cohere/streaming.py | 176 ++++ .../instrumentation/cohere/utils.py | 30 + .../poetry.lock | 158 +-- .../pyproject.toml | 3 +- .../test_cohere_chat_legacy_async.yaml | 81 ++ ...est_cohere_chat_legacy_with_streaming.yaml | 299 ++++++ ...here_chat_legacy_with_streaming_async.yaml | 375 +++++++ ...e_chat_with_events_with_content_async.yaml | 83 ++ ...hat_with_events_with_no_content_async.yaml | 83 ++ .../test_chat/test_cohere_v2_chat_legacy.yaml | 74 ++ ..._cohere_v2_chat_legacy_with_streaming.yaml | 658 +++++++++++++ ...e_v2_chat_legacy_with_streaming_async.yaml | 551 +++++++++++ ...at_legacy_with_tool_calls_and_history.yaml | 164 ++++ ...acy_with_tool_calls_and_history_async.yaml | 163 ++++ ..._legacy_with_tool_calls_and_streaming.yaml | 248 +++++ ...y_with_tool_calls_and_streaming_async.yaml | 283 ++++++ .../test_cohere_v2_embed_legacy.yaml | 92 ++ .../test_cohere_v2_embed_legacy_async.yaml | 92 ++ .../test_cohere_v2_rerank_legacy.yaml | 76 ++ .../test_cohere_v2_rerank_legacy_async.yaml | 76 ++ .../tests/conftest.py | 15 + .../tests/test_chat.py | 914 ++++++++++++++++++ .../tests/test_embed.py | 120 +++ .../tests/test_rerank.py | 161 +++ 26 files changed, 5273 insertions(+), 176 deletions(-) create mode 100644 packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/streaming.py create mode 100644 packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_chat_legacy_async.yaml create mode 100644 packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_chat_legacy_with_streaming.yaml create mode 100644 packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_chat_legacy_with_streaming_async.yaml create mode 100644 packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_chat_with_events_with_content_async.yaml create mode 100644 packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_chat_with_events_with_no_content_async.yaml create mode 100644 packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_v2_chat_legacy.yaml create mode 100644 packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_v2_chat_legacy_with_streaming.yaml create mode 100644 packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_v2_chat_legacy_with_streaming_async.yaml create mode 100644 packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_v2_chat_legacy_with_tool_calls_and_history.yaml create mode 100644 packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_v2_chat_legacy_with_tool_calls_and_history_async.yaml create mode 100644 packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_v2_chat_legacy_with_tool_calls_and_streaming.yaml create mode 100644 packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_v2_chat_legacy_with_tool_calls_and_streaming_async.yaml create mode 100644 packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_embed/test_cohere_v2_embed_legacy.yaml create mode 100644 packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_embed/test_cohere_v2_embed_legacy_async.yaml create mode 100644 packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_rerank/test_cohere_v2_rerank_legacy.yaml create mode 100644 packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_rerank/test_cohere_v2_rerank_legacy_async.yaml create mode 100644 packages/opentelemetry-instrumentation-cohere/tests/test_embed.py diff --git a/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/__init__.py b/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/__init__.py index 5e43e1e43e..db88004aea 100644 --- a/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/__init__.py +++ b/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/__init__.py @@ -11,9 +11,16 @@ emit_response_events, ) from opentelemetry.instrumentation.cohere.span_utils import ( - set_input_attributes, - set_response_attributes, + set_input_content_attributes, + set_response_content_attributes, set_span_request_attributes, + set_span_response_attributes, +) +from opentelemetry.instrumentation.cohere.streaming import ( + process_chat_v1_streaming_response, + aprocess_chat_v1_streaming_response, + process_chat_v2_streaming_response, + aprocess_chat_v2_streaming_response, ) from opentelemetry.instrumentation.cohere.utils import dont_throw, should_emit_events from opentelemetry.instrumentation.cohere.version import __version__ @@ -27,7 +34,7 @@ LLMRequestTypeValues, SpanAttributes, ) -from opentelemetry.trace import SpanKind, Tracer, get_tracer +from opentelemetry.trace import SpanKind, Status, StatusCode, Tracer, get_tracer, use_span from wrapt import wrap_function_wrapper logger = logging.getLogger(__name__) @@ -36,20 +43,133 @@ WRAPPED_METHODS = [ { + "module": "cohere.client", "object": "Client", "method": "generate", "span_name": "cohere.completion", }, { + "module": "cohere.client", "object": "Client", "method": "chat", "span_name": "cohere.chat", }, { + "module": "cohere.client", + "object": "Client", + "method": "chat_stream", + "span_name": "cohere.chat", + "stream_process_func": process_chat_v1_streaming_response, + }, + { + "module": "cohere.client", "object": "Client", "method": "rerank", "span_name": "cohere.rerank", }, + { + "module": "cohere.client", + "object": "Client", + "method": "embed", + "span_name": "cohere.embed", + }, + { + "module": "cohere.client_v2", + "object": "ClientV2", + "method": "chat", + "span_name": "cohere.chat", + }, + { + "module": "cohere.client_v2", + "object": "ClientV2", + "method": "chat_stream", + "span_name": "cohere.chat", + "stream_process_func": process_chat_v2_streaming_response, + }, + { + "module": "cohere.client_v2", + "object": "ClientV2", + "method": "generate", + "span_name": "cohere.embed", + }, + { + "module": "cohere.client_v2", + "object": "ClientV2", + "method": "rerank", + "span_name": "cohere.rerank", + }, + { + "module": "cohere.client_v2", + "object": "ClientV2", + "method": "embed", + "span_name": "cohere.embed", + }, + # Async methods that return AsyncIterator must be wrapped with sync wrapper + { + "module": "cohere.client", + "object": "AsyncClient", + "method": "chat_stream", + "span_name": "cohere.chat", + "stream_process_func": aprocess_chat_v1_streaming_response, + }, + { + "module": "cohere.client_v2", + "object": "AsyncClientV2", + "method": "chat_stream", + "span_name": "cohere.chat", + "stream_process_func": aprocess_chat_v2_streaming_response, + }, +] + +WRAPPED_AMETHODS = [ + { + "module": "cohere.client", + "object": "AsyncClient", + "method": "generate", + "span_name": "cohere.completion", + }, + { + "module": "cohere.client", + "object": "AsyncClient", + "method": "chat", + "span_name": "cohere.chat", + }, + { + "module": "cohere.client", + "object": "AsyncClient", + "method": "rerank", + "span_name": "cohere.rerank", + }, + { + "module": "cohere.client", + "object": "AsyncClient", + "method": "embed", + "span_name": "cohere.embed", + }, + { + "module": "cohere.client_v2", + "object": "AsyncClientV2", + "method": "generate", + "span_name": "cohere.embed", + }, + { + "module": "cohere.client_v2", + "object": "AsyncClientV2", + "method": "chat", + "span_name": "cohere.chat", + }, + { + "module": "cohere.client_v2", + "object": "AsyncClientV2", + "method": "rerank", + "span_name": "cohere.rerank", + }, + { + "module": "cohere.client_v2", + "object": "AsyncClientV2", + "method": "embed", + "span_name": "cohere.embed", + }, ] @@ -66,30 +186,30 @@ def wrapper(wrapped, instance, args, kwargs): def _llm_request_type_by_method(method_name): - if method_name == "chat": + if method_name in ["chat", "chat_stream"]: return LLMRequestTypeValues.CHAT - elif method_name == "generate": + elif method_name in ["generate", "generate_stream"]: return LLMRequestTypeValues.COMPLETION elif method_name == "rerank": return LLMRequestTypeValues.RERANK + elif method_name == "embed": + return LLMRequestTypeValues.EMBEDDING else: return LLMRequestTypeValues.UNKNOWN @dont_throw -def _handle_input(span, event_logger, llm_request_type, kwargs): +def _handle_input_content(span, event_logger, llm_request_type, kwargs): + set_input_content_attributes(span, llm_request_type, kwargs) if should_emit_events(): emit_input_event(event_logger, llm_request_type, kwargs) - else: - set_input_attributes(span, llm_request_type, kwargs) @dont_throw -def _handle_response(span, event_logger, llm_request_type, response): +def _handle_response_content(span, event_logger, llm_request_type, response): + set_response_content_attributes(span, llm_request_type, response) if should_emit_events(): emit_response_events(event_logger, llm_request_type, response) - else: - set_response_attributes(span, llm_request_type, response) @_with_tracer_wrapper @@ -108,6 +228,55 @@ def _wrap( ): return wrapped(*args, **kwargs) + name = to_wrap.get("span_name") + llm_request_type = _llm_request_type_by_method(to_wrap.get("method")) + span = tracer.start_span( + name, + kind=SpanKind.CLIENT, + attributes={ + SpanAttributes.LLM_SYSTEM: "Cohere", + SpanAttributes.LLM_REQUEST_TYPE: llm_request_type.value, + }, + ) + + with use_span(span, end_on_exit=False): + set_span_request_attributes(span, kwargs) + _handle_input_content(span, event_logger, llm_request_type, kwargs) + + try: + response = wrapped(*args, **kwargs) + except Exception as e: + if span.is_recording(): + span.set_status(Status(StatusCode.ERROR, str(e))) + span.record_exception(e) + span.end() + raise + + if to_wrap.get("stream_process_func"): + return to_wrap.get("stream_process_func")(span, event_logger, llm_request_type, response) + + set_span_response_attributes(span, response) + _handle_response_content(span, event_logger, llm_request_type, response) + span.end() + return response + + +@_with_tracer_wrapper +async def _awrap( + tracer: Tracer, + event_logger: Union[EventLogger, None], + to_wrap, + wrapped, + instance, + args, + kwargs, +): + """Instruments and calls every function defined in TO_WRAP.""" + if context_api.get_value(_SUPPRESS_INSTRUMENTATION_KEY) or context_api.get_value( + SUPPRESS_LANGUAGE_MODEL_INSTRUMENTATION_KEY + ): + return await wrapped(*args, **kwargs) + name = to_wrap.get("span_name") llm_request_type = _llm_request_type_by_method(to_wrap.get("method")) with tracer.start_as_current_span( @@ -119,12 +288,18 @@ def _wrap( }, ) as span: set_span_request_attributes(span, kwargs) - _handle_input(span, event_logger, llm_request_type, kwargs) + _handle_input_content(span, event_logger, llm_request_type, kwargs) - response = wrapped(*args, **kwargs) + try: + response = await wrapped(*args, **kwargs) + except Exception as e: + if span.is_recording(): + span.set_status(Status(StatusCode.ERROR, str(e))) + span.record_exception(e) + raise - if response: - _handle_response(span, event_logger, llm_request_type, response) + set_span_response_attributes(span, response) + _handle_response_content(span, event_logger, llm_request_type, response) return response @@ -151,18 +326,51 @@ def _instrument(self, **kwargs): __name__, __version__, event_logger_provider=event_logger_provider ) for wrapped_method in WRAPPED_METHODS: + wrap_module = wrapped_method.get("module") wrap_object = wrapped_method.get("object") wrap_method = wrapped_method.get("method") - wrap_function_wrapper( - "cohere.client", - f"{wrap_object}.{wrap_method}", - _wrap(tracer, event_logger, wrapped_method), - ) + try: + wrap_function_wrapper( + wrap_module, + f"{wrap_object}.{wrap_method}", + _wrap(tracer, event_logger, wrapped_method), + ) + except (ImportError, ModuleNotFoundError, AttributeError): + logger.debug(f"Failed to instrument {wrap_module}.{wrap_object}.{wrap_method}") + + for wrapped_method in WRAPPED_AMETHODS: + wrap_module = wrapped_method.get("module") + wrap_object = wrapped_method.get("object") + wrap_method = wrapped_method.get("method") + try: + wrap_function_wrapper( + wrap_module, + f"{wrap_object}.{wrap_method}", + _awrap(tracer, event_logger, wrapped_method), + ) + except (ImportError, ModuleNotFoundError, AttributeError): + logger.debug(f"Failed to instrument {wrap_module}.{wrap_object}.{wrap_method}") def _uninstrument(self, **kwargs): for wrapped_method in WRAPPED_METHODS: + wrap_module = wrapped_method.get("module") wrap_object = wrapped_method.get("object") - unwrap( - f"cohere.client.{wrap_object}", - wrapped_method.get("method"), - ) + wrap_method = wrapped_method.get("method") + try: + unwrap( + f"{wrap_module}.{wrap_object}", + wrap_method, + ) + except (ImportError, ModuleNotFoundError, AttributeError): + logger.debug(f"Failed to uninstrument {wrap_module}.{wrap_object}.{wrap_method}") + for wrapped_method in WRAPPED_AMETHODS: + wrap_module = wrapped_method.get("module") + wrap_object = wrapped_method.get("object") + wrap_method = wrapped_method.get("method") + try: + unwrap( + f"{wrap_module}.{wrap_object}", + wrap_method, + ) + except (ImportError, ModuleNotFoundError, AttributeError): + logger.debug(f"Failed to uninstrument {wrap_module}.{wrap_object}.{wrap_method}") diff --git a/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/span_utils.py b/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/span_utils.py index a1a2d2aa03..c01eaffe49 100644 --- a/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/span_utils.py +++ b/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/span_utils.py @@ -1,9 +1,21 @@ from opentelemetry.instrumentation.cohere.utils import ( dont_throw, + dump_object, should_send_prompts, + to_dict, + should_emit_events, ) from opentelemetry.semconv._incubating.attributes.gen_ai_attributes import ( + GEN_AI_COMPLETION, GEN_AI_RESPONSE_ID, + GEN_AI_PROMPT, + GEN_AI_REQUEST_MODEL, + GEN_AI_REQUEST_MAX_TOKENS, + GEN_AI_REQUEST_TEMPERATURE, + GEN_AI_REQUEST_TOP_P, + GEN_AI_REQUEST_TOP_K, + GEN_AI_REQUEST_STOP_SEQUENCES, + GEN_AI_RESPONSE_FINISH_REASONS, ) from opentelemetry.semconv_ai import ( LLMRequestTypeValues, @@ -20,46 +32,104 @@ def _set_span_attribute(span, name, value): @dont_throw -def set_input_attributes(span, llm_request_type, kwargs): +def set_input_content_attributes(span, llm_request_type, kwargs): if not span.is_recording(): return - if should_send_prompts(): + if should_send_prompts() and not should_emit_events(): if llm_request_type == LLMRequestTypeValues.COMPLETION: - _set_span_attribute(span, f"{SpanAttributes.LLM_PROMPTS}.0.role", "user") + _set_span_attribute(span, f"{GEN_AI_PROMPT}.0.role", "user") _set_span_attribute( - span, f"{SpanAttributes.LLM_PROMPTS}.0.content", kwargs.get("prompt") + span, f"{GEN_AI_PROMPT}.0.content", kwargs.get("prompt") ) - elif llm_request_type == LLMRequestTypeValues.CHAT: - _set_span_attribute(span, f"{SpanAttributes.LLM_PROMPTS}.0.role", "user") + # client V1 + elif llm_request_type == LLMRequestTypeValues.CHAT and kwargs.get("message"): + user_message_index = 0 + if system_message := kwargs.get("preamble"): + _set_span_attribute(span, f"{GEN_AI_PROMPT}.0.role", "system") + _set_span_attribute( + span, f"{GEN_AI_PROMPT}.0.content", system_message + ) + user_message_index = 1 + _set_span_attribute(span, f"{GEN_AI_PROMPT}.{user_message_index}.role", "user") _set_span_attribute( - span, f"{SpanAttributes.LLM_PROMPTS}.0.content", kwargs.get("message") + span, f"{GEN_AI_PROMPT}.{user_message_index}.content", kwargs.get("message") ) + # client V2 + elif llm_request_type == LLMRequestTypeValues.CHAT and kwargs.get("messages"): + for index, message in enumerate(kwargs.get("messages")): + message_dict = to_dict(message) + _set_span_attribute(span, f"{GEN_AI_PROMPT}.{index}.role", message_dict.get("role")) + _set_span_attribute(span, f"{GEN_AI_PROMPT}.{index}.content", message_dict.get("content")) + + if kwargs.get("tools"): + for index, tool in enumerate(kwargs.get("tools")): + function = tool.get("function") + if not function: + continue + _set_span_attribute( + span, + f"{SpanAttributes.LLM_REQUEST_FUNCTIONS}.{index}.name", + function.get("name"), + ) + _set_span_attribute( + span, + f"{SpanAttributes.LLM_REQUEST_FUNCTIONS}.{index}.description", + function.get("description"), + ) + _set_span_attribute( + span, + f"{SpanAttributes.LLM_REQUEST_FUNCTIONS}.{index}.parameters", + dump_object(function.get("parameters")), + ) + _set_span_attribute( + span, + f"{SpanAttributes.LLM_REQUEST_FUNCTIONS}.{index}.parameters", + dump_object(function.get("parameters")), + ) elif llm_request_type == LLMRequestTypeValues.RERANK: - for index, document in enumerate(kwargs.get("documents")): + for index, document in enumerate(kwargs.get("documents", [])): _set_span_attribute( - span, f"{SpanAttributes.LLM_PROMPTS}.{index}.role", "system" + span, f"{GEN_AI_PROMPT}.{index}.role", "system" ) _set_span_attribute( - span, f"{SpanAttributes.LLM_PROMPTS}.{index}.content", document + span, f"{GEN_AI_PROMPT}.{index}.content", document ) _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{len(kwargs.get('documents'))}.role", + f"{GEN_AI_PROMPT}.{len(kwargs.get('documents'))}.role", "user", ) _set_span_attribute( span, - f"{SpanAttributes.LLM_PROMPTS}.{len(kwargs.get('documents'))}.content", + f"{GEN_AI_PROMPT}.{len(kwargs.get('documents'))}.content", kwargs.get("query"), ) + elif llm_request_type == LLMRequestTypeValues.EMBEDDING: + _set_span_attribute( + span, + f"{GEN_AI_PROMPT}.0.role", + "user", + ) + inputs = kwargs.get("inputs") + if not inputs: + texts = kwargs.get("texts") + inputs = [ + {"type": "text", "text": text} for text in texts + ] + _set_span_attribute( + span, + f"{GEN_AI_PROMPT}.0.content", + dump_object(inputs), + ) @dont_throw -def set_response_attributes(span, llm_request_type, response): +def set_response_content_attributes(span, llm_request_type, response): if not span.is_recording(): return + if should_send_prompts(): if llm_request_type == LLMRequestTypeValues.CHAT: _set_span_chat_response(span, response) @@ -67,22 +137,28 @@ def set_response_attributes(span, llm_request_type, response): _set_span_generations_response(span, response) elif llm_request_type == LLMRequestTypeValues.RERANK: _set_span_rerank_response(span, response) - span.set_status(Status(StatusCode.OK)) +@dont_throw def set_span_request_attributes(span, kwargs): if not span.is_recording(): return - _set_span_attribute(span, SpanAttributes.LLM_REQUEST_MODEL, kwargs.get("model")) + _set_span_attribute(span, GEN_AI_REQUEST_MODEL, kwargs.get("model")) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_MAX_TOKENS, kwargs.get("max_tokens_to_sample") + span, GEN_AI_REQUEST_MAX_TOKENS, kwargs.get("max_tokens_to_sample") ) _set_span_attribute( - span, SpanAttributes.LLM_REQUEST_TEMPERATURE, kwargs.get("temperature") + span, GEN_AI_REQUEST_TEMPERATURE, kwargs.get("temperature") ) - _set_span_attribute(span, SpanAttributes.LLM_REQUEST_TOP_P, kwargs.get("top_p")) + _set_span_attribute(span, GEN_AI_REQUEST_TOP_P, kwargs.get("p", kwargs.get("top_p"))) + _set_span_attribute(span, GEN_AI_REQUEST_TOP_K, kwargs.get("k", kwargs.get("top_k"))) + + if stop_sequences := kwargs.get("stop_sequences", []): + _set_span_attribute(span, GEN_AI_REQUEST_STOP_SEQUENCES, dump_object(stop_sequences)) + + # TODO: Migrate to GEN_AI_REQUEST_FREQUENCY_PENALTY and GEN_AI_REQUEST_PRESENCE_PENALTY _set_span_attribute( span, SpanAttributes.LLM_FREQUENCY_PENALTY, kwargs.get("frequency_penalty") ) @@ -91,35 +167,71 @@ def set_span_request_attributes(span, kwargs): ) -def _set_span_chat_response(span, response): - index = 0 - prefix = f"{SpanAttributes.LLM_COMPLETIONS}.{index}" - _set_span_attribute(span, f"{prefix}.content", response.text) - _set_span_attribute(span, GEN_AI_RESPONSE_ID, response.response_id) +@dont_throw +def set_span_response_attributes(span, response): + if not span.is_recording(): + return + + response_dict = to_dict(response) + # Cohere API v1 + if (response_dict.get("response_id")): + _set_span_attribute(span, GEN_AI_RESPONSE_ID, response_dict.get("response_id")) + # Cohere API v2 + elif (response_dict.get("id")): + _set_span_attribute(span, GEN_AI_RESPONSE_ID, response_dict.get("id")) # Cohere v4 - if hasattr(response, "token_count"): + if token_count := response_dict.get("token_count"): + token_count_dict = to_dict(token_count) _set_span_attribute( span, SpanAttributes.LLM_USAGE_TOTAL_TOKENS, - response.token_count.get("total_tokens"), + token_count_dict.get("total_tokens"), ) _set_span_attribute( span, SpanAttributes.LLM_USAGE_COMPLETION_TOKENS, - response.token_count.get("response_tokens"), + token_count_dict.get("response_tokens"), ) _set_span_attribute( span, SpanAttributes.LLM_USAGE_PROMPT_TOKENS, - response.token_count.get("prompt_tokens"), + token_count_dict.get("prompt_tokens"), ) # Cohere v5 - if hasattr(response, "meta") and hasattr(response.meta, "billed_units"): - input_tokens = response.meta.billed_units.input_tokens - output_tokens = response.meta.billed_units.output_tokens + if response_dict.get("meta"): + meta_dict = to_dict(response_dict.get("meta", {})) + billed_units = meta_dict.get("billed_units", {}) + billed_units_dict = to_dict(billed_units) + input_tokens = billed_units_dict.get("input_tokens", 0) + output_tokens = billed_units_dict.get("output_tokens", 0) + + _set_span_attribute( + span, + SpanAttributes.LLM_USAGE_TOTAL_TOKENS, + input_tokens + output_tokens, + ) + _set_span_attribute( + span, + SpanAttributes.LLM_USAGE_COMPLETION_TOKENS, + output_tokens, + ) + _set_span_attribute( + span, + SpanAttributes.LLM_USAGE_PROMPT_TOKENS, + input_tokens, + ) + # Cohere API v2 + if response_dict.get("usage"): + # usage also has usage.tokens of type UsageTokens. This usually + # has the same number of output tokens, but many more input tokens + # (possibly pre-prompted)") + usage_dict = to_dict(response_dict.get("usage", {})) + billed_units_dict = to_dict(usage_dict.get("billed_units", {})) + input_tokens = billed_units_dict.get("input_tokens", 0) + output_tokens = billed_units_dict.get("output_tokens", 0) _set_span_attribute( span, SpanAttributes.LLM_USAGE_TOTAL_TOKENS, @@ -137,6 +249,50 @@ def _set_span_chat_response(span, response): ) +def _set_span_chat_response(span, response): + index = 0 + prefix = f"{GEN_AI_COMPLETION}.{index}" + _set_span_attribute(span, f"{prefix}.role", "assistant") + + response_dict = to_dict(response) + + if finish_reason := response_dict.get("finish_reason"): + _set_span_attribute(span, GEN_AI_RESPONSE_FINISH_REASONS, [finish_reason]) + + # Cohere API v1 + if text := response_dict.get("text"): + _set_span_attribute(span, f"{prefix}.content", text) + # Cohere API v2 + elif message := response_dict.get("message"): + message_dict = to_dict(message) + content = message_dict.get("content") or [] + if tool_plan := message_dict.get("tool_plan"): + content.append({ + "type": "text", + "text": tool_plan, + }) + # TODO: Add citations, similarly to tool_plan + _set_span_attribute(span, f"{prefix}.content", dump_object(content)) + if tool_calls := message_dict.get("tool_calls"): + tool_call_index = 0 + for tool_call in tool_calls: + if not tool_call.get("function"): + continue + function = tool_call.get("function") + if tool_call.get("id"): + _set_span_attribute(span, f"{prefix}.tool_calls.{tool_call_index}.id", tool_call.get("id")) + if function.get("name"): + _set_span_attribute(span, f"{prefix}.tool_calls.{tool_call_index}.name", function.get("name")) + if function.get("arguments"): + # no dump_object here, since it's already a string (OpenAI-like) + _set_span_attribute( + span, + f"{prefix}.tool_calls.{tool_call_index}.arguments", + function.get("arguments"), + ) + tool_call_index += 1 + + def _set_span_generations_response(span, response): _set_span_attribute(span, GEN_AI_RESPONSE_ID, response.id) if hasattr(response, "generations"): @@ -156,7 +312,7 @@ def _set_span_rerank_response(span, response): prefix = f"{SpanAttributes.LLM_COMPLETIONS}.{idx}" _set_span_attribute(span, f"{prefix}.role", "assistant") content = f"Doc {doc.index}, Score: {doc.relevance_score}" - if doc.document: + if hasattr(doc, "document") and doc.document: if hasattr(doc.document, "text"): content += f"\n{doc.document.text}" else: diff --git a/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/streaming.py b/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/streaming.py new file mode 100644 index 0000000000..3378854820 --- /dev/null +++ b/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/streaming.py @@ -0,0 +1,176 @@ +from opentelemetry.instrumentation.cohere.event_emitter import emit_response_events +from opentelemetry.instrumentation.cohere.utils import ( + dont_throw, + should_send_prompts, + to_dict, + should_emit_events, +) +from opentelemetry.instrumentation.cohere.span_utils import set_span_response_attributes, _set_span_chat_response +from opentelemetry.semconv_ai import SpanAttributes +from opentelemetry.trace.status import Status, StatusCode + +DEFAULT_MESSAGE = { + "content": [], + "role": "assistant", + "tool_calls": [], + "tool_plan": "", + # TODO: Add citations +} + + +def process_chat_v1_streaming_response(span, event_logger, llm_request_type, response): + # This naive version assumes we've always successfully streamed till the end + # and have received a StreamEndChatResponse, which includes the full response + final_response = None + for item in response: + span.add_event(name=f"{SpanAttributes.LLM_CONTENT_COMPLETION_CHUNK}") + + item_to_yield = item + if getattr(item, "event_type", None) == "stream-end" and hasattr(item, "response"): + final_response = item.response + + yield item_to_yield + + set_span_response_attributes(span, final_response) + if should_emit_events(): + emit_response_events(event_logger, llm_request_type, final_response) + elif should_send_prompts(): + _set_span_chat_response(span, final_response) + span.set_status(Status(StatusCode.OK)) + span.end() + + +async def aprocess_chat_v1_streaming_response(span, event_logger, llm_request_type, response): + # This naive version assumes we've always successfully streamed till the end + # and have received a StreamEndChatResponse, which includes the full response + final_response = None + async for item in response: + span.add_event(name=f"{SpanAttributes.LLM_CONTENT_COMPLETION_CHUNK}") + + item_to_yield = item + if getattr(item, "event_type", None) == "stream-end" and hasattr(item, "response"): + final_response = item.response + + yield item_to_yield + + set_span_response_attributes(span, final_response) + if should_emit_events(): + emit_response_events(event_logger, llm_request_type, final_response) + elif should_send_prompts(): + _set_span_chat_response(span, final_response) + span.set_status(Status(StatusCode.OK)) + span.end() + + +@dont_throw +def process_chat_v2_streaming_response(span, event_logger, llm_request_type, response): + final_response = { + "finish_reason": None, + "message": DEFAULT_MESSAGE, + "usage": {}, + "id": "", + "error": None, + } + current_content_item = {} + current_tool_call_item = {} + for item in response: + span.add_event(name=f"{SpanAttributes.LLM_CONTENT_COMPLETION_CHUNK}") + item_to_yield = item + try: + _accumulate_stream_item(item, current_content_item, current_tool_call_item, final_response) + except Exception: + pass + yield item_to_yield + + print(f"final_response: {final_response}") + set_span_response_attributes(span, final_response) + if should_emit_events(): + emit_response_events(event_logger, llm_request_type, final_response) + elif should_send_prompts(): + _set_span_chat_response(span, final_response) + + if final_response.get("error"): + span.set_status(Status(StatusCode.ERROR, final_response.get("error"))) + span.record_exception(final_response.get("error")) + else: + span.set_status(Status(StatusCode.OK)) + span.end() + + +@dont_throw +async def aprocess_chat_v2_streaming_response(span, event_logger, llm_request_type, response): + final_response = { + "finish_reason": None, + "message": DEFAULT_MESSAGE, + "usage": {}, + "id": "", + "error": None, + } + current_content_item = {"type": "text", "thinking": None, "text": ""} + current_tool_call_item = { + "id": "", + "type": "function", + "function": {"name": "", "arguments": "", "description": ""}, + } + async for item in response: + span.add_event(name=f"{SpanAttributes.LLM_CONTENT_COMPLETION_CHUNK}") + item_to_yield = item + try: + _accumulate_stream_item(item, current_content_item, current_tool_call_item, final_response) + except Exception: + pass + yield item_to_yield + + set_span_response_attributes(span, final_response) + if should_emit_events(): + emit_response_events(event_logger, llm_request_type, final_response) + elif should_send_prompts(): + _set_span_chat_response(span, final_response) + if final_response.get("error"): + span.set_status(Status(StatusCode.ERROR, final_response.get("error"))) + span.record_exception(final_response.get("error")) + else: + span.set_status(Status(StatusCode.OK)) + span.end() + + +# accumulated items are passed in by reference +def _accumulate_stream_item(item, current_content_item, current_tool_call_item, final_response): + item_dict = to_dict(item) + if item_dict.get("type") == "message-start": + final_response["message"] = (item_dict.get("delta") or {}).get("message") or DEFAULT_MESSAGE + final_response["id"] = item_dict.get("id") + elif item_dict.get("type") == "content-start": + new_content_item = ((item_dict.get("delta") or {}).get("message") or {}).get("content") + current_content_item.clear() + current_content_item.update(new_content_item or {}) + elif item_dict.get("type") == "content-delta": + new_thinking = (((item_dict.get("delta") or {}).get("message") or {}).get("content") or {}).get("thinking") + if new_thinking: + existing_thinking = current_content_item.get("thinking") + current_content_item["thinking"] = (existing_thinking or "") + new_thinking + new_text = (((item_dict.get("delta") or {}).get("message") or {}).get("content") or {}).get("text") + if new_text: + existing_text = current_content_item.get("text") + current_content_item["text"] = (existing_text or "") + new_text + elif item_dict.get("type") == "content-end": + final_response["message"]["content"].append(current_content_item) + elif item_dict.get("type") == "tool-plan-delta": + new_tool_plan = ((item_dict.get("delta") or {}).get("message") or {}).get("tool_plan") + if new_tool_plan: + existing_tool_plan = final_response["message"].get("tool_plan") + final_response["message"]["tool_plan"] = (existing_tool_plan or "") + new_tool_plan + elif item_dict.get("type") == "tool-call-start": + new_tool_call_item = ((item_dict.get("delta") or {}).get("message") or {}).get("tool_calls") + current_tool_call_item.update(new_tool_call_item or {}) + elif item_dict.get("type") == "tool-call-delta": + message = (item_dict.get("delta") or {}).get("message") or {} + new_arguments = ((message.get("tool_calls") or {}).get("function") or {}).get("arguments") + if new_arguments: + existing_arguments = (current_tool_call_item.get("function") or {}).get("arguments") + current_tool_call_item["function"]["arguments"] = (existing_arguments or "") + new_arguments + elif item_dict.get("type") == "tool-call-end": + final_response["message"]["tool_calls"].append({**current_tool_call_item}) + elif item_dict.get("type") == "message-end": + final_response["usage"] = (item_dict.get("delta") or {}).get("usage") or {} + final_response["finish_reason"] = (item_dict.get("delta") or {}).get("finish_reason") diff --git a/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/utils.py b/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/utils.py index 4a8e85b06d..2ed13915cd 100644 --- a/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/utils.py +++ b/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/utils.py @@ -1,3 +1,5 @@ +import dataclasses +import json import logging import os import traceback @@ -45,3 +47,31 @@ def should_emit_events() -> bool: and if the event logger is not None. """ return not Config.use_legacy_attributes + + +def dump_object(obj): + try: + if hasattr(obj, "model_dump_json") and callable(obj.model_dump_json): + return obj.model_dump_json() + except Exception: + pass + try: + return json.dumps(obj) + except Exception: + return "" + + +def to_dict(obj): + try: + if hasattr(obj, "model_dump") and callable(obj.model_dump): + return obj.model_dump() + except Exception: + pass + if isinstance(obj, dict): + return obj + if dataclasses.is_dataclass(obj): + return dataclasses.asdict(obj) + try: + return dict(obj) + except Exception: + return obj diff --git a/packages/opentelemetry-instrumentation-cohere/poetry.lock b/packages/opentelemetry-instrumentation-cohere/poetry.lock index d71adf50cf..b43d1890af 100644 --- a/packages/opentelemetry-instrumentation-cohere/poetry.lock +++ b/packages/opentelemetry-instrumentation-cohere/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 2.1.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.1.4 and should not be changed by hand. [[package]] name = "annotated-types" @@ -52,48 +52,18 @@ pycodestyle = ">=2.11.0" tomli = {version = "*", markers = "python_version < \"3.11\""} [[package]] -name = "boto3" -version = "1.34.145" -description = "The AWS SDK for Python" +name = "backports-asyncio-runner" +version = "1.2.0" +description = "Backport of asyncio.Runner, a context manager that controls event loop life cycle." optional = false -python-versions = ">=3.8" -groups = ["test"] -files = [ - {file = "boto3-1.34.145-py3-none-any.whl", hash = "sha256:69d5afb7a017d07dd6bdfb680d2912d5d369b3fafa0a45161207d9f393b14d7e"}, - {file = "boto3-1.34.145.tar.gz", hash = "sha256:ac770fb53dde1743aec56bd8e56b7ee2e2f5ad42a37825968ec4ff8428822640"}, -] - -[package.dependencies] -botocore = ">=1.34.145,<1.35.0" -jmespath = ">=0.7.1,<2.0.0" -s3transfer = ">=0.10.0,<0.11.0" - -[package.extras] -crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] - -[[package]] -name = "botocore" -version = "1.34.145" -description = "Low-level, data-driven core of boto 3." -optional = false -python-versions = ">=3.8" +python-versions = "<3.11,>=3.8" groups = ["test"] +markers = "python_version < \"3.11\"" files = [ - {file = "botocore-1.34.145-py3-none-any.whl", hash = "sha256:2e72e262de02adcb0264ac2bac159a28f55dbba8d9e52aa0308773a42950dff5"}, - {file = "botocore-1.34.145.tar.gz", hash = "sha256:edf0fb4c02186ae29b76263ac5fda18b0a085d334a310551c9984407cf1079e6"}, + {file = "backports_asyncio_runner-1.2.0-py3-none-any.whl", hash = "sha256:0da0a936a8aeb554eccb426dc55af3ba63bcdc69fa1a600b5bb305413a4477b5"}, + {file = "backports_asyncio_runner-1.2.0.tar.gz", hash = "sha256:a5aa7b2b7d8f8bfcaa2b57313f70792df84e32a2a746f585213373f900b42162"}, ] -[package.dependencies] -jmespath = ">=0.7.1,<2.0.0" -python-dateutil = ">=2.1,<3.0.0" -urllib3 = [ - {version = ">=1.25.4,<2.2.0 || >2.2.0,<3", markers = "python_version >= \"3.10\""}, - {version = ">=1.25.4,<1.27", markers = "python_version < \"3.10\""}, -] - -[package.extras] -crt = ["awscrt (==0.20.11)"] - [[package]] name = "certifi" version = "2024.7.4" @@ -208,23 +178,22 @@ files = [ [[package]] name = "cohere" -version = "5.6.1" +version = "5.18.0" description = "" optional = false -python-versions = "<4.0,>=3.8" +python-versions = "<4.0,>=3.9" groups = ["test"] files = [ - {file = "cohere-5.6.1-py3-none-any.whl", hash = "sha256:1c8bcd39a54622d64b83cafb865f102cd2565ce091b0856fd5ce11bf7169109a"}, - {file = "cohere-5.6.1.tar.gz", hash = "sha256:5d7efda64f0e512d4cc35aa04b17a6f74b3d8c175a99f2797991a7f31dfac349"}, + {file = "cohere-5.18.0-py3-none-any.whl", hash = "sha256:885e7be360206418db39425faa60dbcd7f38e39e7f84b824ee68442e6a436e93"}, + {file = "cohere-5.18.0.tar.gz", hash = "sha256:93a7753458a45cd30c796300182d22bb1889eadc510727e1de3d8342cb2bc0bf"}, ] [package.dependencies] -boto3 = ">=1.34.0,<2.0.0" fastavro = ">=1.9.4,<2.0.0" httpx = ">=0.21.2" -httpx-sse = ">=0.4.0,<0.5.0" -parameterized = ">=0.9.0,<0.10.0" +httpx-sse = "0.4.0" pydantic = ">=1.9.2" +pydantic-core = ">=2.18.2,<3.0.0" requests = ">=2.0.0,<3.0.0" tokenizers = ">=0.15,<1" types-requests = ">=2.0.0,<3.0.0" @@ -268,7 +237,7 @@ description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" groups = ["dev", "test"] -markers = "platform_python_implementation == \"PyPy\" and python_version < \"3.11\" or python_version <= \"3.10\"" +markers = "python_version < \"3.11\"" files = [ {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, @@ -548,18 +517,6 @@ files = [ {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, ] -[[package]] -name = "jmespath" -version = "1.0.1" -description = "JSON Matching Expressions" -optional = false -python-versions = ">=3.7" -groups = ["test"] -files = [ - {file = "jmespath-1.0.1-py3-none-any.whl", hash = "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980"}, - {file = "jmespath-1.0.1.tar.gz", hash = "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe"}, -] - [[package]] name = "mccabe" version = "0.7.0" @@ -763,21 +720,6 @@ files = [ {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, ] -[[package]] -name = "parameterized" -version = "0.9.0" -description = "Parameterized testing with any Python test framework" -optional = false -python-versions = ">=3.7" -groups = ["test"] -files = [ - {file = "parameterized-0.9.0-py2.py3-none-any.whl", hash = "sha256:4e0758e3d41bea3bbd05ec14fc2c24736723f243b28d702081aef438c9372b1b"}, - {file = "parameterized-0.9.0.tar.gz", hash = "sha256:7fc905272cefa4f364c1a3429cbbe9c0f98b793988efb5bf90aac80f08db09b1"}, -] - -[package.extras] -dev = ["jinja2"] - [[package]] name = "pluggy" version = "1.5.0" @@ -966,6 +908,27 @@ tomli = {version = ">=1", markers = "python_version < \"3.11\""} [package.extras] dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] +[[package]] +name = "pytest-asyncio" +version = "1.2.0" +description = "Pytest support for asyncio" +optional = false +python-versions = ">=3.9" +groups = ["test"] +files = [ + {file = "pytest_asyncio-1.2.0-py3-none-any.whl", hash = "sha256:8e17ae5e46d8e7efe51ab6494dd2010f4ca8dae51652aa3c8d55acf50bfb2e99"}, + {file = "pytest_asyncio-1.2.0.tar.gz", hash = "sha256:c609a64a2a8768462d0c99811ddb8bd2583c33fd33cf7f21af1c142e824ffb57"}, +] + +[package.dependencies] +backports-asyncio-runner = {version = ">=1.1,<2", markers = "python_version < \"3.11\""} +pytest = ">=8.2,<9" +typing-extensions = {version = ">=4.12", markers = "python_version < \"3.13\""} + +[package.extras] +docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1)"] +testing = ["coverage (>=6.2)", "hypothesis (>=5.7.1)"] + [[package]] name = "pytest-recording" version = "0.13.2" @@ -1006,21 +969,6 @@ termcolor = ">=2.1.0" [package.extras] dev = ["black", "flake8", "pre-commit"] -[[package]] -name = "python-dateutil" -version = "2.9.0.post0" -description = "Extensions to the standard Python datetime module" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -groups = ["test"] -files = [ - {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, - {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, -] - -[package.dependencies] -six = ">=1.5" - [[package]] name = "pyyaml" version = "6.0.1" @@ -1104,36 +1052,6 @@ urllib3 = ">=1.21.1,<3" socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] -[[package]] -name = "s3transfer" -version = "0.10.2" -description = "An Amazon S3 Transfer Manager" -optional = false -python-versions = ">=3.8" -groups = ["test"] -files = [ - {file = "s3transfer-0.10.2-py3-none-any.whl", hash = "sha256:eca1c20de70a39daee580aef4986996620f365c4e0fda6a86100231d62f1bf69"}, - {file = "s3transfer-0.10.2.tar.gz", hash = "sha256:0711534e9356d3cc692fdde846b4a1e4b0cb6519971860796e6bc4c7aea00ef6"}, -] - -[package.dependencies] -botocore = ">=1.33.2,<2.0a.0" - -[package.extras] -crt = ["botocore[crt] (>=1.33.2,<2.0a.0)"] - -[[package]] -name = "six" -version = "1.16.0" -description = "Python 2 and 3 compatibility utilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -groups = ["test"] -files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, -] - [[package]] name = "sniffio" version = "1.3.1" @@ -1286,7 +1204,7 @@ description = "A lil' TOML parser" optional = false python-versions = ">=3.7" groups = ["dev", "test"] -markers = "platform_python_implementation == \"PyPy\" and python_version < \"3.11\" or python_version <= \"3.10\"" +markers = "python_version < \"3.11\"" files = [ {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, @@ -1596,4 +1514,4 @@ instruments = [] [metadata] lock-version = "2.1" python-versions = ">=3.9,<4" -content-hash = "1e5f0035bb4dc783b0fc695063777ce5433386dce4d81136f664144b26dc7384" +content-hash = "5eb954d1b5d573471a1307c02f3f5f307660bc84e66f6fbe051ab802415150fe" diff --git a/packages/opentelemetry-instrumentation-cohere/pyproject.toml b/packages/opentelemetry-instrumentation-cohere/pyproject.toml index e6d2653ea8..730b2806a3 100644 --- a/packages/opentelemetry-instrumentation-cohere/pyproject.toml +++ b/packages/opentelemetry-instrumentation-cohere/pyproject.toml @@ -36,12 +36,13 @@ pytest = "^8.2.2" pytest-sugar = "1.0.0" [tool.poetry.group.test.dependencies] -cohere = "^5.3.3" +cohere = "^5.18.0" pytest = "^8.2.2" pytest-sugar = "1.0.0" vcrpy = "^6.0.1" pytest-recording = "^0.13.1" opentelemetry-sdk = "^1.27.0" +pytest-asyncio = "^1.2.0" [build-system] requires = ["poetry-core"] diff --git a/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_chat_legacy_async.yaml b/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_chat_legacy_async.yaml new file mode 100644 index 0000000000..2125d4396a --- /dev/null +++ b/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_chat_legacy_async.yaml @@ -0,0 +1,81 @@ +interactions: +- request: + body: '{"message": "Tell me a joke, pirate style", "model": "command", "stream": + false}' + headers: + accept: + - '*/*' + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '80' + content-type: + - application/json + host: + - api.cohere.com + user-agent: + - python-httpx/0.27.0 + x-fern-language: + - Python + x-fern-sdk-name: + - cohere + x-fern-sdk-version: + - 5.6.1 + method: POST + uri: https://api.cohere.com/v1/chat + response: + body: + string: '{"response_id":"ea2d074c-4f25-47cb-bef8-b00dc2ae991b","text":"Arrrr, + matey! Shiver me timbers, here''s a pirate-style joke for ye: \n\nI spoke + with an astronomer and argh, matey, she told me the Sun would be blowin'' + up! But cheer up, me hearties, it''ll happen in five billion years. We''ve + got plenty of time to find a new treasure trove before then!","generation_id":"41bd7ae5-511d-449f-a64d-dd54e5d697e4","chat_history":[{"role":"USER","message":"Tell + me a joke, pirate style"},{"role":"CHATBOT","message":"Arrrr, matey! Shiver + me timbers, here''s a pirate-style joke for ye: \n\nI spoke with an astronomer + and argh, matey, she told me the Sun would be blowin'' up! But cheer up, me + hearties, it''ll happen in five billion years. We''ve got plenty of time to + find a new treasure trove before then!"}],"finish_reason":"COMPLETE","meta":{"api_version":{"version":"1"},"warnings":["model + ''command'' is deprecated and will be removed September 15 2025. Please consider + upgrading to a newer model to avoid future service disruptions"],"billed_units":{"input_tokens":7,"output_tokens":80},"tokens":{"input_tokens":69,"output_tokens":81}}}' + headers: + Alt-Svc: + - h3=":443"; ma=2592000,h3-29=":443"; ma=2592000 + Content-Length: + - '1127' + Via: + - 1.1 google + access-control-expose-headers: + - X-Debug-Trace-ID + cache-control: + - no-cache, no-store, no-transform, must-revalidate, private, max-age=0 + content-type: + - application/json + date: + - Sun, 14 Sep 2025 01:23:07 GMT + expires: + - Thu, 01 Jan 1970 00:00:00 GMT + num_chars: + - '324' + num_tokens: + - '87' + pragma: + - no-cache + server: + - envoy + vary: + - Origin + x-accel-expires: + - '0' + x-api-warning: + - model 'command' is deprecated and will be removed September 15 2025. Please + consider upgrading to a newer model to avoid future service disruptions + x-debug-trace-id: + - 37d8ceb858f86160192181d6ece63b36 + x-envoy-upstream-service-time: + - '2401' + status: + code: 200 + message: OK +version: 1 diff --git a/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_chat_legacy_with_streaming.yaml b/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_chat_legacy_with_streaming.yaml new file mode 100644 index 0000000000..7355ab09df --- /dev/null +++ b/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_chat_legacy_with_streaming.yaml @@ -0,0 +1,299 @@ +interactions: +- request: + body: '{"message": "Tell me a joke, pirate style", "model": "command", "stream": + true}' + headers: + accept: + - '*/*' + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '79' + content-type: + - application/json + host: + - api.cohere.com + user-agent: + - python-httpx/0.27.0 + x-fern-language: + - Python + x-fern-sdk-name: + - cohere + x-fern-sdk-version: + - 5.6.1 + method: POST + uri: https://api.cohere.com/v1/chat + response: + body: + string: '{"is_finished":false,"event_type":"stream-start","generation_id":"a7cd9d01-255f-44a2-a186-834f942bf61e"} + + {"is_finished":false,"event_type":"text-generation","text":"Ar"} + + {"is_finished":false,"event_type":"text-generation","text":"rr"} + + {"is_finished":false,"event_type":"text-generation","text":"r"} + + {"is_finished":false,"event_type":"text-generation","text":","} + + {"is_finished":false,"event_type":"text-generation","text":" mate"} + + {"is_finished":false,"event_type":"text-generation","text":"y"} + + {"is_finished":false,"event_type":"text-generation","text":"!"} + + {"is_finished":false,"event_type":"text-generation","text":" Sh"} + + {"is_finished":false,"event_type":"text-generation","text":"iver"} + + {"is_finished":false,"event_type":"text-generation","text":" me"} + + {"is_finished":false,"event_type":"text-generation","text":" tim"} + + {"is_finished":false,"event_type":"text-generation","text":"bers"} + + {"is_finished":false,"event_type":"text-generation","text":","} + + {"is_finished":false,"event_type":"text-generation","text":" here"} + + {"is_finished":false,"event_type":"text-generation","text":"''s"} + + {"is_finished":false,"event_type":"text-generation","text":" a"} + + {"is_finished":false,"event_type":"text-generation","text":" pirate"} + + {"is_finished":false,"event_type":"text-generation","text":"-"} + + {"is_finished":false,"event_type":"text-generation","text":"themed"} + + {"is_finished":false,"event_type":"text-generation","text":" joke"} + + {"is_finished":false,"event_type":"text-generation","text":" for"} + + {"is_finished":false,"event_type":"text-generation","text":" ye"} + + {"is_finished":false,"event_type":"text-generation","text":":"} + + {"is_finished":false,"event_type":"text-generation","text":"\n\nWhy"} + + {"is_finished":false,"event_type":"text-generation","text":" did"} + + {"is_finished":false,"event_type":"text-generation","text":" the"} + + {"is_finished":false,"event_type":"text-generation","text":" pirate"} + + {"is_finished":false,"event_type":"text-generation","text":" go"} + + {"is_finished":false,"event_type":"text-generation","text":" to"} + + {"is_finished":false,"event_type":"text-generation","text":" the"} + + {"is_finished":false,"event_type":"text-generation","text":" dentist"} + + {"is_finished":false,"event_type":"text-generation","text":"?"} + + {"is_finished":false,"event_type":"text-generation","text":"\n\nA"} + + {"is_finished":false,"event_type":"text-generation","text":":"} + + {"is_finished":false,"event_type":"text-generation","text":" Because"} + + {"is_finished":false,"event_type":"text-generation","text":" he"} + + {"is_finished":false,"event_type":"text-generation","text":" wanted"} + + {"is_finished":false,"event_type":"text-generation","text":" to"} + + {"is_finished":false,"event_type":"text-generation","text":" find"} + + {"is_finished":false,"event_type":"text-generation","text":" some"} + + {"is_finished":false,"event_type":"text-generation","text":" treasure"} + + {"is_finished":false,"event_type":"text-generation","text":"!"} + + {"is_finished":false,"event_type":"text-generation","text":" AR"} + + {"is_finished":false,"event_type":"text-generation","text":"RR"} + + {"is_finished":false,"event_type":"text-generation","text":"RR"} + + {"is_finished":false,"event_type":"text-generation","text":"!!!"} + + {"is_finished":false,"event_type":"text-generation","text":" \n\nP"} + + {"is_finished":false,"event_type":"text-generation","text":"irates"} + + {"is_finished":false,"event_type":"text-generation","text":" love"} + + {"is_finished":false,"event_type":"text-generation","text":" loot"} + + {"is_finished":false,"event_type":"text-generation","text":"in"} + + {"is_finished":false,"event_type":"text-generation","text":"''"} + + {"is_finished":false,"event_type":"text-generation","text":" gold"} + + {"is_finished":false,"event_type":"text-generation","text":","} + + {"is_finished":false,"event_type":"text-generation","text":" and"} + + {"is_finished":false,"event_type":"text-generation","text":" sometimes"} + + {"is_finished":false,"event_type":"text-generation","text":" forget"} + + {"is_finished":false,"event_type":"text-generation","text":" to"} + + {"is_finished":false,"event_type":"text-generation","text":" take"} + + {"is_finished":false,"event_type":"text-generation","text":" care"} + + {"is_finished":false,"event_type":"text-generation","text":" of"} + + {"is_finished":false,"event_type":"text-generation","text":" their"} + + {"is_finished":false,"event_type":"text-generation","text":" teeth"} + + {"is_finished":false,"event_type":"text-generation","text":","} + + {"is_finished":false,"event_type":"text-generation","text":" so"} + + {"is_finished":false,"event_type":"text-generation","text":" I"} + + {"is_finished":false,"event_type":"text-generation","text":" hope"} + + {"is_finished":false,"event_type":"text-generation","text":" ye"} + + {"is_finished":false,"event_type":"text-generation","text":" appreciate"} + + {"is_finished":false,"event_type":"text-generation","text":" me"} + + {"is_finished":false,"event_type":"text-generation","text":" pirate"} + + {"is_finished":false,"event_type":"text-generation","text":"-"} + + {"is_finished":false,"event_type":"text-generation","text":"themed"} + + {"is_finished":false,"event_type":"text-generation","text":" joke"} + + {"is_finished":false,"event_type":"text-generation","text":" there"} + + {"is_finished":false,"event_type":"text-generation","text":","} + + {"is_finished":false,"event_type":"text-generation","text":" ye"} + + {"is_finished":false,"event_type":"text-generation","text":" sc"} + + {"is_finished":false,"event_type":"text-generation","text":"ur"} + + {"is_finished":false,"event_type":"text-generation","text":"vy"} + + {"is_finished":false,"event_type":"text-generation","text":" dog"} + + {"is_finished":false,"event_type":"text-generation","text":"!"} + + {"is_finished":false,"event_type":"text-generation","text":" \n\nIf"} + + {"is_finished":false,"event_type":"text-generation","text":" ye"} + + {"is_finished":false,"event_type":"text-generation","text":" want"} + + {"is_finished":false,"event_type":"text-generation","text":" more"} + + {"is_finished":false,"event_type":"text-generation","text":" pirate"} + + {"is_finished":false,"event_type":"text-generation","text":" humor"} + + {"is_finished":false,"event_type":"text-generation","text":","} + + {"is_finished":false,"event_type":"text-generation","text":" let"} + + {"is_finished":false,"event_type":"text-generation","text":" me"} + + {"is_finished":false,"event_type":"text-generation","text":" know"} + + {"is_finished":false,"event_type":"text-generation","text":" and"} + + {"is_finished":false,"event_type":"text-generation","text":" I"} + + {"is_finished":false,"event_type":"text-generation","text":"''ll"} + + {"is_finished":false,"event_type":"text-generation","text":" be"} + + {"is_finished":false,"event_type":"text-generation","text":" happy"} + + {"is_finished":false,"event_type":"text-generation","text":" to"} + + {"is_finished":false,"event_type":"text-generation","text":" sail"} + + {"is_finished":false,"event_type":"text-generation","text":" through"} + + {"is_finished":false,"event_type":"text-generation","text":" some"} + + {"is_finished":false,"event_type":"text-generation","text":" more"} + + {"is_finished":false,"event_type":"text-generation","text":" pirate"} + + {"is_finished":false,"event_type":"text-generation","text":"-"} + + {"is_finished":false,"event_type":"text-generation","text":"y"} + + {"is_finished":false,"event_type":"text-generation","text":" comedy"} + + {"is_finished":false,"event_type":"text-generation","text":"!"} + + {"is_finished":true,"event_type":"stream-end","response":{"response_id":"12c00d26-e3bb-48c0-8c49-262155b57d64","text":"Arrrr, + matey! Shiver me timbers, here''s a pirate-themed joke for ye:\n\nWhy did + the pirate go to the dentist?\n\nA: Because he wanted to find some treasure! + ARRRRR!!! \n\nPirates love lootin'' gold, and sometimes forget to take care + of their teeth, so I hope ye appreciate me pirate-themed joke there, ye scurvy + dog! \n\nIf ye want more pirate humor, let me know and I''ll be happy to sail + through some more pirate-y comedy!","generation_id":"a7cd9d01-255f-44a2-a186-834f942bf61e","chat_history":[{"role":"USER","message":"Tell + me a joke, pirate style"},{"role":"CHATBOT","message":"Arrrr, matey! Shiver + me timbers, here''s a pirate-themed joke for ye:\n\nWhy did the pirate go + to the dentist?\n\nA: Because he wanted to find some treasure! ARRRRR!!! \n\nPirates + love lootin'' gold, and sometimes forget to take care of their teeth, so I + hope ye appreciate me pirate-themed joke there, ye scurvy dog! \n\nIf ye want + more pirate humor, let me know and I''ll be happy to sail through some more + pirate-y comedy!"}],"finish_reason":"COMPLETE","meta":{"api_version":{"version":"1"},"warnings":["model + ''command'' is deprecated and will be removed September 15 2025. Please consider + upgrading to a newer model to avoid future service disruptions"],"billed_units":{"input_tokens":7,"output_tokens":115},"tokens":{"input_tokens":69,"output_tokens":116}}},"finish_reason":"COMPLETE"} + + ' + headers: + Alt-Svc: + - h3=":443"; ma=2592000,h3-29=":443"; ma=2592000 + Transfer-Encoding: + - chunked + Via: + - 1.1 google + access-control-expose-headers: + - X-Debug-Trace-ID + cache-control: + - no-cache, no-store, no-transform, must-revalidate, private, max-age=0 + content-type: + - application/stream+json + date: + - Sun, 14 Sep 2025 01:29:39 GMT + expires: + - Thu, 01 Jan 1970 00:00:00 GMT + pragma: + - no-cache + server: + - envoy + vary: + - Origin + x-accel-expires: + - '0' + x-api-warning: + - model 'command' is deprecated and will be removed September 15 2025. Please + consider upgrading to a newer model to avoid future service disruptions + x-debug-trace-id: + - 2a0bada75306984d0beeabdf7afde1ac + x-envoy-upstream-service-time: + - '79' + status: + code: 200 + message: OK +version: 1 diff --git a/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_chat_legacy_with_streaming_async.yaml b/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_chat_legacy_with_streaming_async.yaml new file mode 100644 index 0000000000..dc708e9857 --- /dev/null +++ b/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_chat_legacy_with_streaming_async.yaml @@ -0,0 +1,375 @@ +interactions: +- request: + body: '{"message": "Tell me a joke, pirate style", "model": "command", "stream": + true}' + headers: + accept: + - '*/*' + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '79' + content-type: + - application/json + host: + - api.cohere.com + user-agent: + - python-httpx/0.27.0 + x-fern-language: + - Python + x-fern-sdk-name: + - cohere + x-fern-sdk-version: + - 5.6.1 + method: POST + uri: https://api.cohere.com/v1/chat + response: + body: + string: '{"is_finished":false,"event_type":"stream-start","generation_id":"613783cf-5a8b-4d4e-b34e-d6c2223a3387"} + + {"is_finished":false,"event_type":"text-generation","text":"Ar"} + + {"is_finished":false,"event_type":"text-generation","text":"rr"} + + {"is_finished":false,"event_type":"text-generation","text":"r"} + + {"is_finished":false,"event_type":"text-generation","text":","} + + {"is_finished":false,"event_type":"text-generation","text":" mate"} + + {"is_finished":false,"event_type":"text-generation","text":"y"} + + {"is_finished":false,"event_type":"text-generation","text":"!"} + + {"is_finished":false,"event_type":"text-generation","text":" Sh"} + + {"is_finished":false,"event_type":"text-generation","text":"iver"} + + {"is_finished":false,"event_type":"text-generation","text":" me"} + + {"is_finished":false,"event_type":"text-generation","text":" tim"} + + {"is_finished":false,"event_type":"text-generation","text":"bers"} + + {"is_finished":false,"event_type":"text-generation","text":","} + + {"is_finished":false,"event_type":"text-generation","text":" here"} + + {"is_finished":false,"event_type":"text-generation","text":"''s"} + + {"is_finished":false,"event_type":"text-generation","text":" a"} + + {"is_finished":false,"event_type":"text-generation","text":" pirate"} + + {"is_finished":false,"event_type":"text-generation","text":"-"} + + {"is_finished":false,"event_type":"text-generation","text":"style"} + + {"is_finished":false,"event_type":"text-generation","text":" joke"} + + {"is_finished":false,"event_type":"text-generation","text":" for"} + + {"is_finished":false,"event_type":"text-generation","text":" ye"} + + {"is_finished":false,"event_type":"text-generation","text":":"} + + {"is_finished":false,"event_type":"text-generation","text":" \n\nI"} + + {"is_finished":false,"event_type":"text-generation","text":" asked"} + + {"is_finished":false,"event_type":"text-generation","text":" the"} + + {"is_finished":false,"event_type":"text-generation","text":" captain"} + + {"is_finished":false,"event_type":"text-generation","text":" if"} + + {"is_finished":false,"event_type":"text-generation","text":" we"} + + {"is_finished":false,"event_type":"text-generation","text":" could"} + + {"is_finished":false,"event_type":"text-generation","text":" go"} + + {"is_finished":false,"event_type":"text-generation","text":" and"} + + {"is_finished":false,"event_type":"text-generation","text":" get"} + + {"is_finished":false,"event_type":"text-generation","text":" ourselves"} + + {"is_finished":false,"event_type":"text-generation","text":" a"} + + {"is_finished":false,"event_type":"text-generation","text":" snack"} + + {"is_finished":false,"event_type":"text-generation","text":"."} + + {"is_finished":false,"event_type":"text-generation","text":" He"} + + {"is_finished":false,"event_type":"text-generation","text":" looked"} + + {"is_finished":false,"event_type":"text-generation","text":" at"} + + {"is_finished":false,"event_type":"text-generation","text":" me"} + + {"is_finished":false,"event_type":"text-generation","text":","} + + {"is_finished":false,"event_type":"text-generation","text":" all"} + + {"is_finished":false,"event_type":"text-generation","text":" seas"} + + {"is_finished":false,"event_type":"text-generation","text":"ick"} + + {"is_finished":false,"event_type":"text-generation","text":" and"} + + {"is_finished":false,"event_type":"text-generation","text":" green"} + + {"is_finished":false,"event_type":"text-generation","text":","} + + {"is_finished":false,"event_type":"text-generation","text":" and"} + + {"is_finished":false,"event_type":"text-generation","text":" yelled"} + + {"is_finished":false,"event_type":"text-generation","text":":"} + + {"is_finished":false,"event_type":"text-generation","text":" \""} + + {"is_finished":false,"event_type":"text-generation","text":"A"} + + {"is_finished":false,"event_type":"text-generation","text":"ye"} + + {"is_finished":false,"event_type":"text-generation","text":","} + + {"is_finished":false,"event_type":"text-generation","text":" mate"} + + {"is_finished":false,"event_type":"text-generation","text":"y"} + + {"is_finished":false,"event_type":"text-generation","text":"!\""} + + {"is_finished":false,"event_type":"text-generation","text":" \n\nThis"} + + {"is_finished":false,"event_type":"text-generation","text":" classic"} + + {"is_finished":false,"event_type":"text-generation","text":" pirate"} + + {"is_finished":false,"event_type":"text-generation","text":" pun"} + + {"is_finished":false,"event_type":"text-generation","text":" combines"} + + {"is_finished":false,"event_type":"text-generation","text":" elements"} + + {"is_finished":false,"event_type":"text-generation","text":" of"} + + {"is_finished":false,"event_type":"text-generation","text":" pirate"} + + {"is_finished":false,"event_type":"text-generation","text":" vocabulary"} + + {"is_finished":false,"event_type":"text-generation","text":" and"} + + {"is_finished":false,"event_type":"text-generation","text":" humor"} + + {"is_finished":false,"event_type":"text-generation","text":":"} + + {"is_finished":false,"event_type":"text-generation","text":" using"} + + {"is_finished":false,"event_type":"text-generation","text":" the"} + + {"is_finished":false,"event_type":"text-generation","text":" pirate"} + + {"is_finished":false,"event_type":"text-generation","text":"-"} + + {"is_finished":false,"event_type":"text-generation","text":"esque"} + + {"is_finished":false,"event_type":"text-generation","text":" expression"} + + {"is_finished":false,"event_type":"text-generation","text":" \""} + + {"is_finished":false,"event_type":"text-generation","text":"A"} + + {"is_finished":false,"event_type":"text-generation","text":"ye"} + + {"is_finished":false,"event_type":"text-generation","text":","} + + {"is_finished":false,"event_type":"text-generation","text":" mate"} + + {"is_finished":false,"event_type":"text-generation","text":"y"} + + {"is_finished":false,"event_type":"text-generation","text":"\""} + + {"is_finished":false,"event_type":"text-generation","text":" to"} + + {"is_finished":false,"event_type":"text-generation","text":" express"} + + {"is_finished":false,"event_type":"text-generation","text":" agreement"} + + {"is_finished":false,"event_type":"text-generation","text":","} + + {"is_finished":false,"event_type":"text-generation","text":" while"} + + {"is_finished":false,"event_type":"text-generation","text":" also"} + + {"is_finished":false,"event_type":"text-generation","text":" playing"} + + {"is_finished":false,"event_type":"text-generation","text":" on"} + + {"is_finished":false,"event_type":"text-generation","text":" the"} + + {"is_finished":false,"event_type":"text-generation","text":" phrase"} + + {"is_finished":false,"event_type":"text-generation","text":" to"} + + {"is_finished":false,"event_type":"text-generation","text":" highlight"} + + {"is_finished":false,"event_type":"text-generation","text":" the"} + + {"is_finished":false,"event_type":"text-generation","text":" captain"} + + {"is_finished":false,"event_type":"text-generation","text":"''s"} + + {"is_finished":false,"event_type":"text-generation","text":" discomfort"} + + {"is_finished":false,"event_type":"text-generation","text":"ing"} + + {"is_finished":false,"event_type":"text-generation","text":" sea"} + + {"is_finished":false,"event_type":"text-generation","text":" sickness"} + + {"is_finished":false,"event_type":"text-generation","text":"."} + + {"is_finished":false,"event_type":"text-generation","text":" \n\nI"} + + {"is_finished":false,"event_type":"text-generation","text":" hope"} + + {"is_finished":false,"event_type":"text-generation","text":" ye"} + + {"is_finished":false,"event_type":"text-generation","text":" find"} + + {"is_finished":false,"event_type":"text-generation","text":" this"} + + {"is_finished":false,"event_type":"text-generation","text":" joke"} + + {"is_finished":false,"event_type":"text-generation","text":" to"} + + {"is_finished":false,"event_type":"text-generation","text":" be"} + + {"is_finished":false,"event_type":"text-generation","text":" a"} + + {"is_finished":false,"event_type":"text-generation","text":" fun"} + + {"is_finished":false,"event_type":"text-generation","text":" little"} + + {"is_finished":false,"event_type":"text-generation","text":" treasure"} + + {"is_finished":false,"event_type":"text-generation","text":","} + + {"is_finished":false,"event_type":"text-generation","text":" and"} + + {"is_finished":false,"event_type":"text-generation","text":" if"} + + {"is_finished":false,"event_type":"text-generation","text":" ye"} + + {"is_finished":false,"event_type":"text-generation","text":" be"} + + {"is_finished":false,"event_type":"text-generation","text":" want"} + + {"is_finished":false,"event_type":"text-generation","text":"in"} + + {"is_finished":false,"event_type":"text-generation","text":"''"} + + {"is_finished":false,"event_type":"text-generation","text":" more"} + + {"is_finished":false,"event_type":"text-generation","text":","} + + {"is_finished":false,"event_type":"text-generation","text":" let"} + + {"is_finished":false,"event_type":"text-generation","text":" me"} + + {"is_finished":false,"event_type":"text-generation","text":" know"} + + {"is_finished":false,"event_type":"text-generation","text":","} + + {"is_finished":false,"event_type":"text-generation","text":" and"} + + {"is_finished":false,"event_type":"text-generation","text":" I"} + + {"is_finished":false,"event_type":"text-generation","text":" shall"} + + {"is_finished":false,"event_type":"text-generation","text":" provide"} + + {"is_finished":false,"event_type":"text-generation","text":" ye"} + + {"is_finished":false,"event_type":"text-generation","text":" with"} + + {"is_finished":false,"event_type":"text-generation","text":" a"} + + {"is_finished":false,"event_type":"text-generation","text":" bounty"} + + {"is_finished":false,"event_type":"text-generation","text":" of"} + + {"is_finished":false,"event_type":"text-generation","text":" pirate"} + + {"is_finished":false,"event_type":"text-generation","text":"-"} + + {"is_finished":false,"event_type":"text-generation","text":"themed"} + + {"is_finished":false,"event_type":"text-generation","text":" humor"} + + {"is_finished":false,"event_type":"text-generation","text":"!"} + + {"is_finished":true,"event_type":"stream-end","response":{"response_id":"dcdb9a85-a8dc-4f4c-9779-f7c1801248f3","text":"Arrrr, + matey! Shiver me timbers, here''s a pirate-style joke for ye: \n\nI asked + the captain if we could go and get ourselves a snack. He looked at me, all + seasick and green, and yelled: \"Aye, matey!\" \n\nThis classic pirate pun + combines elements of pirate vocabulary and humor: using the pirate-esque expression + \"Aye, matey\" to express agreement, while also playing on the phrase to highlight + the captain''s discomforting sea sickness. \n\nI hope ye find this joke to + be a fun little treasure, and if ye be wantin'' more, let me know, and I shall + provide ye with a bounty of pirate-themed humor!","generation_id":"613783cf-5a8b-4d4e-b34e-d6c2223a3387","chat_history":[{"role":"USER","message":"Tell + me a joke, pirate style"},{"role":"CHATBOT","message":"Arrrr, matey! Shiver + me timbers, here''s a pirate-style joke for ye: \n\nI asked the captain if + we could go and get ourselves a snack. He looked at me, all seasick and green, + and yelled: \"Aye, matey!\" \n\nThis classic pirate pun combines elements + of pirate vocabulary and humor: using the pirate-esque expression \"Aye, matey\" + to express agreement, while also playing on the phrase to highlight the captain''s + discomforting sea sickness. \n\nI hope ye find this joke to be a fun little + treasure, and if ye be wantin'' more, let me know, and I shall provide ye + with a bounty of pirate-themed humor!"}],"finish_reason":"COMPLETE","meta":{"api_version":{"version":"1"},"warnings":["model + ''command'' is deprecated and will be removed September 15 2025. Please consider + upgrading to a newer model to avoid future service disruptions"],"billed_units":{"input_tokens":7,"output_tokens":149},"tokens":{"input_tokens":69,"output_tokens":150}}},"finish_reason":"COMPLETE"} + + ' + headers: + Alt-Svc: + - h3=":443"; ma=2592000,h3-29=":443"; ma=2592000 + Transfer-Encoding: + - chunked + Via: + - 1.1 google + access-control-expose-headers: + - X-Debug-Trace-ID + cache-control: + - no-cache, no-store, no-transform, must-revalidate, private, max-age=0 + content-type: + - application/stream+json + date: + - Sun, 14 Sep 2025 01:46:21 GMT + expires: + - Thu, 01 Jan 1970 00:00:00 GMT + pragma: + - no-cache + server: + - envoy + vary: + - Origin + x-accel-expires: + - '0' + x-api-warning: + - model 'command' is deprecated and will be removed September 15 2025. Please + consider upgrading to a newer model to avoid future service disruptions + x-debug-trace-id: + - 421516367f70f3860d54828ee98b1718 + x-envoy-upstream-service-time: + - '79' + status: + code: 200 + message: OK +version: 1 diff --git a/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_chat_with_events_with_content_async.yaml b/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_chat_with_events_with_content_async.yaml new file mode 100644 index 0000000000..be1d50789a --- /dev/null +++ b/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_chat_with_events_with_content_async.yaml @@ -0,0 +1,83 @@ +interactions: +- request: + body: '{"message": "Tell me a joke, pirate style", "model": "command", "stream": + false}' + headers: + accept: + - '*/*' + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '80' + content-type: + - application/json + host: + - api.cohere.com + user-agent: + - python-httpx/0.27.0 + x-fern-language: + - Python + x-fern-sdk-name: + - cohere + x-fern-sdk-version: + - 5.6.1 + method: POST + uri: https://api.cohere.com/v1/chat + response: + body: + string: '{"response_id":"e17775dc-ffad-456f-a239-48d8329428bf","text":"Arrrr, + matey! Shiver me timbers, here''s a pirate-style joke for ye: \n\nI asked + the captain if we could go and get ourselves a snack. He looked at me, scowlin'' + and said, \"You snooze, you lose!\" Aargh, it would seem I am the pirate who + snores after all me rum! \n\nPirates chuckled and laughed, they did, and ye + will too! \n\nArrrr!","generation_id":"73b9bc6c-7620-4cf5-9c76-4a1518da3e6e","chat_history":[{"role":"USER","message":"Tell + me a joke, pirate style"},{"role":"CHATBOT","message":"Arrrr, matey! Shiver + me timbers, here''s a pirate-style joke for ye: \n\nI asked the captain if + we could go and get ourselves a snack. He looked at me, scowlin'' and said, + \"You snooze, you lose!\" Aargh, it would seem I am the pirate who snores + after all me rum! \n\nPirates chuckled and laughed, they did, and ye will + too! \n\nArrrr!"}],"finish_reason":"COMPLETE","meta":{"api_version":{"version":"1"},"warnings":["model + ''command'' is deprecated and will be removed September 15 2025. Please consider + upgrading to a newer model to avoid future service disruptions"],"billed_units":{"input_tokens":7,"output_tokens":100},"tokens":{"input_tokens":69,"output_tokens":101}}}' + headers: + Alt-Svc: + - h3=":443"; ma=2592000,h3-29=":443"; ma=2592000 + Content-Length: + - '1223' + Via: + - 1.1 google + access-control-expose-headers: + - X-Debug-Trace-ID + cache-control: + - no-cache, no-store, no-transform, must-revalidate, private, max-age=0 + content-type: + - application/json + date: + - Sun, 14 Sep 2025 01:23:12 GMT + expires: + - Thu, 01 Jan 1970 00:00:00 GMT + num_chars: + - '324' + num_tokens: + - '107' + pragma: + - no-cache + server: + - envoy + vary: + - Origin + x-accel-expires: + - '0' + x-api-warning: + - model 'command' is deprecated and will be removed September 15 2025. Please + consider upgrading to a newer model to avoid future service disruptions + x-debug-trace-id: + - 48d68a3c9e1310932498b50f0824b055 + x-envoy-upstream-service-time: + - '5508' + status: + code: 200 + message: OK +version: 1 diff --git a/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_chat_with_events_with_no_content_async.yaml b/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_chat_with_events_with_no_content_async.yaml new file mode 100644 index 0000000000..02b9a9f612 --- /dev/null +++ b/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_chat_with_events_with_no_content_async.yaml @@ -0,0 +1,83 @@ +interactions: +- request: + body: '{"message": "Tell me a joke, pirate style", "model": "command", "stream": + false}' + headers: + accept: + - '*/*' + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '80' + content-type: + - application/json + host: + - api.cohere.com + user-agent: + - python-httpx/0.27.0 + x-fern-language: + - Python + x-fern-sdk-name: + - cohere + x-fern-sdk-version: + - 5.6.1 + method: POST + uri: https://api.cohere.com/v1/chat + response: + body: + string: '{"response_id":"c0b03212-d862-46a1-aa94-2fa6f491fd17","text":"Arrrr, + matey! Shiver me timbers, here''s a pirate-style joke for ye: \n\nI asked + the pirate captain how he lost his leg. He said, \"I was just a kid, matey!\" + \n\nArrrr, matey! Now ye squiggly little skeleton and walk the plank laughing + like a pirate! \n\nIf ye want more pirate jokes, I can make ye walk the plank + and whip ye with me cannonball launcher!","generation_id":"a3203475-c8f3-488d-8682-f6da563cd1d7","chat_history":[{"role":"USER","message":"Tell + me a joke, pirate style"},{"role":"CHATBOT","message":"Arrrr, matey! Shiver + me timbers, here''s a pirate-style joke for ye: \n\nI asked the pirate captain + how he lost his leg. He said, \"I was just a kid, matey!\" \n\nArrrr, matey! + Now ye squiggly little skeleton and walk the plank laughing like a pirate! + \n\nIf ye want more pirate jokes, I can make ye walk the plank and whip ye + with me cannonball launcher!"}],"finish_reason":"COMPLETE","meta":{"api_version":{"version":"1"},"warnings":["model + ''command'' is deprecated and will be removed September 15 2025. Please consider + upgrading to a newer model to avoid future service disruptions"],"billed_units":{"input_tokens":7,"output_tokens":99},"tokens":{"input_tokens":69,"output_tokens":100}}}' + headers: + Alt-Svc: + - h3=":443"; ma=2592000,h3-29=":443"; ma=2592000 + Content-Length: + - '1264' + Via: + - 1.1 google + access-control-expose-headers: + - X-Debug-Trace-ID + cache-control: + - no-cache, no-store, no-transform, must-revalidate, private, max-age=0 + content-type: + - application/json + date: + - Sun, 14 Sep 2025 01:23:16 GMT + expires: + - Thu, 01 Jan 1970 00:00:00 GMT + num_chars: + - '324' + num_tokens: + - '106' + pragma: + - no-cache + server: + - envoy + vary: + - Origin + x-accel-expires: + - '0' + x-api-warning: + - model 'command' is deprecated and will be removed September 15 2025. Please + consider upgrading to a newer model to avoid future service disruptions + x-debug-trace-id: + - c3f40eb96fedb33840b13a84344b7f6e + x-envoy-upstream-service-time: + - '2980' + status: + code: 200 + message: OK +version: 1 diff --git a/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_v2_chat_legacy.yaml b/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_v2_chat_legacy.yaml new file mode 100644 index 0000000000..bf2fa69496 --- /dev/null +++ b/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_v2_chat_legacy.yaml @@ -0,0 +1,74 @@ +interactions: +- request: + body: '{"model": "command", "messages": [{"role": "user", "content": "Tell me + a joke, pirate style"}], "stream": false}' + headers: + accept: + - '*/*' + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '112' + content-type: + - application/json + host: + - api.cohere.com + user-agent: + - cohere/5.18.0 + x-fern-language: + - Python + x-fern-sdk-name: + - cohere + x-fern-sdk-version: + - 5.18.0 + method: POST + uri: https://api.cohere.com/v2/chat + response: + body: + string: "{\"id\":\"83e3e297-264b-478e-9b22-5058386292ed\",\"message\":{\"role\":\"assistant\",\"content\":[{\"type\":\"text\",\"text\":\"Arrrr, + matey! Shiver me timbers, here\u2019s a pirate-themed joke for ye: \\n\\nI + stumbled upon a shipwreck on the ocean floor,\\nBut instead of gold or silver, + all I found was dough.\\nI couldn\u2019t believe me peepers, so I rubbed me + eyes,\\nBut it was just a pizza restaurant, and I couldn\u2019t help but cry.\"}]},\"finish_reason\":\"COMPLETE\",\"usage\":{\"billed_units\":{\"input_tokens\":7,\"output_tokens\":88},\"tokens\":{\"input_tokens\":69,\"output_tokens\":89}}}" + headers: + Alt-Svc: + - h3=":443"; ma=2592000,h3-29=":443"; ma=2592000 + Content-Length: + - '552' + Via: + - 1.1 google + access-control-expose-headers: + - X-Debug-Trace-ID + cache-control: + - no-cache, no-store, no-transform, must-revalidate, private, max-age=0 + content-type: + - application/json + date: + - Sun, 14 Sep 2025 01:50:19 GMT + expires: + - Thu, 01 Jan 1970 00:00:00 GMT + num_chars: + - '324' + num_tokens: + - '95' + pragma: + - no-cache + server: + - envoy + vary: + - Origin + x-accel-expires: + - '0' + x-api-warning: + - model 'command' is deprecated and will be removed September 15 2025. Please + consider upgrading to a newer model to avoid future service disruptions + x-debug-trace-id: + - 3ea490a581ea0c90e48fbdccabff104b + x-envoy-upstream-service-time: + - '2637' + status: + code: 200 + message: OK +version: 1 diff --git a/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_v2_chat_legacy_with_streaming.yaml b/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_v2_chat_legacy_with_streaming.yaml new file mode 100644 index 0000000000..77de902e11 --- /dev/null +++ b/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_v2_chat_legacy_with_streaming.yaml @@ -0,0 +1,658 @@ +interactions: +- request: + body: '{"model": "command", "messages": [{"role": "user", "content": "Tell me + a joke, pirate style"}], "stream": true}' + headers: + accept: + - '*/*' + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '111' + content-type: + - application/json + host: + - api.cohere.com + user-agent: + - cohere/5.18.0 + x-fern-language: + - Python + x-fern-sdk-name: + - cohere + x-fern-sdk-version: + - 5.18.0 + method: POST + uri: https://api.cohere.com/v2/chat + response: + body: + string: 'event: message-start + + data: {"id":"6cd6ce61-bb3b-46f6-907e-fcfab45e51b6","type":"message-start","delta":{"message":{"role":"assistant","content":[],"tool_plan":"","tool_calls":[],"citations":[]}}} + + + event: content-start + + data: {"type":"content-start","index":0,"delta":{"message":{"content":{"type":"text","text":""}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"Ar"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"rr"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"r"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":","}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + mate"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"y"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"!"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + Sh"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"iver"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + me"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + tim"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"bers"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":","}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + here"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"''s"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + a"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + pirate"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"-"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"style"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + joke"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + for"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + ye"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":":"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"\n\nWhy"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + did"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + the"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + pirate"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + want"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + to"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + go"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + to"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + the"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + dentist"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"?"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + \n\nA"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":":"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + Because"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + he"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + was"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + looking"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + for"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + a"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + treasure"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + chest"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"!"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + \n\nAr"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"rr"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"r"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":","}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + mate"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"y"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":","}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + I"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + hope"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + ye"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + laughed"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + ye"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + arr"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"r"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"rs"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + off"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"!"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + \n\nIf"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + ye"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + want"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + more"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + pirate"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + jokes"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":","}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + I"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"''ll"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + be"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + happy"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + to"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + make"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + ye"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + walk"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + the"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + plank"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + with"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + more"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + hilarious"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + tales"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"."}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + \n\n Let"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + me"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + know"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + if"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + ye"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + want"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + me"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + to"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + sail"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + through"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + more"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + pirate"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"-"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"themed"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + humor"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"!"}}}} + + + event: content-end + + data: {"type":"content-end","index":0} + + + event: message-end + + data: {"type":"message-end","delta":{"finish_reason":"COMPLETE","usage":{"billed_units":{"input_tokens":7,"output_tokens":109},"tokens":{"input_tokens":69,"output_tokens":110}}}} + + + data: [DONE] + + + ' + headers: + Alt-Svc: + - h3=":443"; ma=2592000,h3-29=":443"; ma=2592000 + Transfer-Encoding: + - chunked + Via: + - 1.1 google + access-control-expose-headers: + - X-Debug-Trace-ID + cache-control: + - no-cache, no-store, no-transform, must-revalidate, private, max-age=0 + content-type: + - text/event-stream + date: + - Sun, 14 Sep 2025 01:59:14 GMT + expires: + - Thu, 01 Jan 1970 00:00:00 GMT + pragma: + - no-cache + server: + - envoy + vary: + - Origin + x-accel-expires: + - '0' + x-api-warning: + - model 'command' is deprecated and will be removed September 15 2025. Please + consider upgrading to a newer model to avoid future service disruptions + x-debug-trace-id: + - 936e9f001e13e2cbf9988a12da8ca483 + x-envoy-upstream-service-time: + - '70' + status: + code: 200 + message: OK +version: 1 diff --git a/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_v2_chat_legacy_with_streaming_async.yaml b/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_v2_chat_legacy_with_streaming_async.yaml new file mode 100644 index 0000000000..2f98a1c60c --- /dev/null +++ b/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_v2_chat_legacy_with_streaming_async.yaml @@ -0,0 +1,551 @@ +interactions: +- request: + body: '{"model": "command", "messages": [{"role": "user", "content": "Tell me + a joke, pirate style"}], "stream": true}' + headers: + accept: + - '*/*' + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '111' + content-type: + - application/json + host: + - api.cohere.com + user-agent: + - cohere/5.18.0 + x-fern-language: + - Python + x-fern-sdk-name: + - cohere + x-fern-sdk-version: + - 5.18.0 + method: POST + uri: https://api.cohere.com/v2/chat + response: + body: + string: 'event: message-start + + data: {"id":"599ae0aa-0ef6-49e4-b7f4-e2fafc40ca2c","type":"message-start","delta":{"message":{"role":"assistant","content":[],"tool_plan":"","tool_calls":[],"citations":[]}}} + + + event: content-start + + data: {"type":"content-start","index":0,"delta":{"message":{"content":{"type":"text","text":""}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"Ar"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"rr"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"r"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":","}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + mate"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"y"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"!"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + Sh"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"iver"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + me"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + tim"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"bers"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":","}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + here"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"''s"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + a"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + pirate"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"-"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"style"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + joke"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + for"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + ye"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":":"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"\n\nWhy"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + did"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + the"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + pirate"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + want"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + to"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + join"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + the"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + circus"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"?"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + \n\nAr"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"rr"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"r"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":","}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + because"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + he"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + wanted"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + to"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + be"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + a"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + tra"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"pe"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"ze"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + arr"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"rr"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"r"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"rc"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"at"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"!"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + \n\nHo"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + ho"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + ho"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":","}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + ye"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + sc"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"ur"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"vy"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + dog"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":","}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + ye"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + like"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + it"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"?"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + These"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + pirate"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + jokes"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + sh"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"an"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"''t"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + be"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + sc"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"upp"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"ering"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + ye"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + any"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + time"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + soon"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"."}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":" + Avast"}}}} + + + event: content-delta + + data: {"type":"content-delta","index":0,"delta":{"message":{"content":{"text":"!"}}}} + + + event: content-end + + data: {"type":"content-end","index":0} + + + event: message-end + + data: {"type":"message-end","delta":{"finish_reason":"COMPLETE","usage":{"billed_units":{"input_tokens":7,"output_tokens":89},"tokens":{"input_tokens":69,"output_tokens":89}}}} + + + data: [DONE] + + + ' + headers: + Alt-Svc: + - h3=":443"; ma=2592000,h3-29=":443"; ma=2592000 + Transfer-Encoding: + - chunked + Via: + - 1.1 google + access-control-expose-headers: + - X-Debug-Trace-ID + cache-control: + - no-cache, no-store, no-transform, must-revalidate, private, max-age=0 + content-type: + - text/event-stream + date: + - Sun, 14 Sep 2025 02:19:39 GMT + expires: + - Thu, 01 Jan 1970 00:00:00 GMT + pragma: + - no-cache + server: + - envoy + vary: + - Origin + x-accel-expires: + - '0' + x-api-warning: + - model 'command' is deprecated and will be removed September 15 2025. Please + consider upgrading to a newer model to avoid future service disruptions + x-debug-trace-id: + - bc877ec6699cd83aa9c7d1952c3fbb20 + x-envoy-upstream-service-time: + - '81' + status: + code: 200 + message: OK +version: 1 diff --git a/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_v2_chat_legacy_with_tool_calls_and_history.yaml b/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_v2_chat_legacy_with_tool_calls_and_history.yaml new file mode 100644 index 0000000000..3658fc44e5 --- /dev/null +++ b/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_v2_chat_legacy_with_tool_calls_and_history.yaml @@ -0,0 +1,164 @@ +interactions: +- request: + body: '{"model": "command-r", "messages": [{"role": "user", "content": "What is + the weather and current time in Tokyo?"}], "tools": [{"type": "function", "function": + {"name": "get_weather", "description": "Get the current weather in a given location", + "parameters": {"type": "object", "properties": {"location": {"type": "string", + "description": "The city and state, e.g. San Francisco, CA"}}, "required": ["location"]}}}, + {"type": "function", "function": {"name": "get_time", "description": "Get the + current time in a given location", "parameters": {"type": "object", "properties": + {"location": {"type": "string", "description": "The city and state, e.g. San + Francisco, CA"}}, "required": ["location"]}}}], "stream": false}' + headers: + accept: + - '*/*' + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '717' + content-type: + - application/json + host: + - api.cohere.com + user-agent: + - cohere/5.18.0 + x-fern-language: + - Python + x-fern-sdk-name: + - cohere + x-fern-sdk-version: + - 5.18.0 + method: POST + uri: https://api.cohere.com/v2/chat + response: + body: + string: '{"id":"965405bb-b9da-4dc5-b329-e708a795e188","message":{"role":"assistant","tool_plan":"I + will search for the current time and weather in Tokyo.","tool_calls":[{"id":"get_time_dp3men9jrvhf","type":"function","function":{"name":"get_time","arguments":"{\"location\":\"Tokyo\"}"}},{"id":"get_weather_d7arjgsc96yf","type":"function","function":{"name":"get_weather","arguments":"{\"location\":\"Tokyo\"}"}}]},"finish_reason":"TOOL_CALL","usage":{"billed_units":{"input_tokens":62,"output_tokens":28},"tokens":{"input_tokens":968,"output_tokens":83}}}' + headers: + Alt-Svc: + - h3=":443"; ma=2592000,h3-29=":443"; ma=2592000 + Content-Length: + - '547' + Via: + - 1.1 google + access-control-expose-headers: + - X-Debug-Trace-ID + cache-control: + - no-cache, no-store, no-transform, must-revalidate, private, max-age=0 + content-type: + - application/json + date: + - Sun, 14 Sep 2025 02:36:03 GMT + expires: + - Thu, 01 Jan 1970 00:00:00 GMT + num_chars: + - '4591' + num_tokens: + - '90' + pragma: + - no-cache + server: + - envoy + vary: + - Origin + x-accel-expires: + - '0' + x-api-warning: + - model 'command-r' is deprecated and will be removed September 15 2025. Please + consider upgrading to a newer model to avoid future service disruptions + x-debug-trace-id: + - 42d840ed9dd60e834b9f33cc4a811aa8 + x-envoy-upstream-service-time: + - '1761' + status: + code: 200 + message: OK +- request: + body: '{"model": "command-r", "messages": [{"role": "user", "content": "What is + the weather and current time in Tokyo?"}, {"role": "assistant", "content": null, + "tool_calls": [{"id": "get_time_dp3men9jrvhf", "type": "function", "function": + {"name": "get_time", "arguments": "{\"location\":\"Tokyo\"}"}}, {"id": "get_weather_d7arjgsc96yf", + "type": "function", "function": {"name": "get_weather", "arguments": "{\"location\":\"Tokyo\"}"}}]}, + {"role": "tool", "tool_call_id": "get_time_dp3men9jrvhf", "content": "4:20 PM"}, + {"role": "tool", "tool_call_id": "get_weather_d7arjgsc96yf", "content": "Sunny + 20 degrees Celsius"}], "tools": [{"type": "function", "function": {"name": "get_weather", + "description": "Get the current weather in a given location", "parameters": + {"type": "object", "properties": {"location": {"type": "string", "description": + "The city and state, e.g. San Francisco, CA"}}, "required": ["location"]}}}, + {"type": "function", "function": {"name": "get_time", "description": "Get the + current time in a given location", "parameters": {"type": "object", "properties": + {"location": {"type": "string", "description": "The city and state, e.g. San + Francisco, CA"}}, "required": ["location"]}}}], "stream": false}' + headers: + accept: + - '*/*' + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '1217' + content-type: + - application/json + host: + - api.cohere.com + user-agent: + - cohere/5.18.0 + x-fern-language: + - Python + x-fern-sdk-name: + - cohere + x-fern-sdk-version: + - 5.18.0 + method: POST + uri: https://api.cohere.com/v2/chat + response: + body: + string: "{\"id\":\"00f7ec58-cd22-4b62-b068-0e7ece6bbf67\",\"message\":{\"role\":\"assistant\",\"content\":[{\"type\":\"text\",\"text\":\"The + current time in Tokyo is 4:20 PM and the weather is sunny with a temperature + of 20\xB0C.\"}],\"citations\":[{\"start\":29,\"end\":36,\"text\":\"4:20 PM\",\"sources\":[{\"type\":\"tool\",\"id\":\"get_time_dp3men9jrvhf:0\",\"tool_output\":{\"content\":\"4:20 + PM\"}}],\"type\":\"TEXT_CONTENT\"},{\"start\":56,\"end\":89,\"text\":\"sunny + with a temperature of 20\xB0C.\",\"sources\":[{\"type\":\"tool\",\"id\":\"get_weather_d7arjgsc96yf:0\",\"tool_output\":{\"content\":\"Sunny + 20 degrees Celsius\"}}],\"type\":\"TEXT_CONTENT\"}]},\"finish_reason\":\"COMPLETE\",\"usage\":{\"billed_units\":{\"input_tokens\":94,\"output_tokens\":27},\"tokens\":{\"input_tokens\":1094,\"output_tokens\":102}}}" + headers: + Alt-Svc: + - h3=":443"; ma=2592000,h3-29=":443"; ma=2592000 + Content-Length: + - '719' + Via: + - 1.1 google + access-control-expose-headers: + - X-Debug-Trace-ID + cache-control: + - no-cache, no-store, no-transform, must-revalidate, private, max-age=0 + content-type: + - application/json + date: + - Sun, 14 Sep 2025 02:36:05 GMT + expires: + - Thu, 01 Jan 1970 00:00:00 GMT + num_chars: + - '5100' + num_tokens: + - '121' + pragma: + - no-cache + server: + - envoy + vary: + - Origin + x-accel-expires: + - '0' + x-api-warning: + - model 'command-r' is deprecated and will be removed September 15 2025. Please + consider upgrading to a newer model to avoid future service disruptions + x-debug-trace-id: + - f6bf3b4e64a9e3a3355b5c7050aa95fd + x-envoy-upstream-service-time: + - '1282' + status: + code: 200 + message: OK +version: 1 diff --git a/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_v2_chat_legacy_with_tool_calls_and_history_async.yaml b/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_v2_chat_legacy_with_tool_calls_and_history_async.yaml new file mode 100644 index 0000000000..4ddc1cdab3 --- /dev/null +++ b/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_v2_chat_legacy_with_tool_calls_and_history_async.yaml @@ -0,0 +1,163 @@ +interactions: +- request: + body: '{"model": "command-r7b-12-2024", "messages": [{"role": "user", "content": + "What is the weather and current time in Tokyo?"}], "tools": [{"type": "function", + "function": {"name": "get_weather", "description": "Get the current weather + in a given location", "parameters": {"type": "object", "properties": {"location": + {"type": "string", "description": "The city and state, e.g. San Francisco, CA"}}, + "required": ["location"]}}}, {"type": "function", "function": {"name": "get_time", + "description": "Get the current time in a given location", "parameters": {"type": + "object", "properties": {"location": {"type": "string", "description": "The + city and state, e.g. San Francisco, CA"}}, "required": ["location"]}}}], "stream": + false}' + headers: + accept: + - '*/*' + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '727' + content-type: + - application/json + host: + - api.cohere.com + user-agent: + - cohere/5.18.0 + x-fern-language: + - Python + x-fern-sdk-name: + - cohere + x-fern-sdk-version: + - 5.18.0 + method: POST + uri: https://api.cohere.com/v2/chat + response: + body: + string: '{"id":"b7391518-e53e-4486-98ea-fabffcde31c2","message":{"role":"assistant","tool_plan":"I + will use the get_weather and get_time tools to find the weather and current + time in Tokyo.","tool_calls":[{"id":"get_weather_mznfyh090g90","type":"function","function":{"name":"get_weather","arguments":"{\"location\":\"Tokyo\"}"}},{"id":"get_time_eksdqe8f9g4y","type":"function","function":{"name":"get_time","arguments":"{\"location\":\"Tokyo\"}"}}]},"finish_reason":"TOOL_CALL","usage":{"billed_units":{"input_tokens":62,"output_tokens":38},"tokens":{"input_tokens":1531,"output_tokens":89}}}' + headers: + Alt-Svc: + - h3=":443"; ma=2592000,h3-29=":443"; ma=2592000 + Content-Length: + - '584' + Via: + - 1.1 google + access-control-expose-headers: + - X-Debug-Trace-ID + cache-control: + - no-cache, no-store, no-transform, must-revalidate, private, max-age=0 + content-type: + - application/json + date: + - Sun, 14 Sep 2025 03:04:15 GMT + expires: + - Thu, 01 Jan 1970 00:00:00 GMT + num_chars: + - '7120' + num_tokens: + - '100' + pragma: + - no-cache + server: + - envoy + vary: + - Origin + x-accel-expires: + - '0' + x-debug-trace-id: + - 4b063f6ebf94617b855602c20dfb9f77 + x-envoy-upstream-service-time: + - '582' + status: + code: 200 + message: OK +- request: + body: '{"model": "command-r7b-12-2024", "messages": [{"role": "user", "content": + "What is the weather and current time in Tokyo?"}, {"role": "assistant", "content": + null, "tool_calls": [{"id": "get_weather_mznfyh090g90", "type": "function", + "function": {"name": "get_weather", "arguments": "{\"location\":\"Tokyo\"}"}}, + {"id": "get_time_eksdqe8f9g4y", "type": "function", "function": {"name": "get_time", + "arguments": "{\"location\":\"Tokyo\"}"}}]}, {"role": "tool", "tool_call_id": + "get_weather_mznfyh090g90", "content": "4:20 PM"}, {"role": "tool", "tool_call_id": + "get_time_eksdqe8f9g4y", "content": "Sunny 20 degrees Celsius"}], "tools": [{"type": + "function", "function": {"name": "get_weather", "description": "Get the current + weather in a given location", "parameters": {"type": "object", "properties": + {"location": {"type": "string", "description": "The city and state, e.g. San + Francisco, CA"}}, "required": ["location"]}}}, {"type": "function", "function": + {"name": "get_time", "description": "Get the current time in a given location", + "parameters": {"type": "object", "properties": {"location": {"type": "string", + "description": "The city and state, e.g. San Francisco, CA"}}, "required": ["location"]}}}], + "stream": false}' + headers: + accept: + - '*/*' + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '1227' + content-type: + - application/json + host: + - api.cohere.com + user-agent: + - cohere/5.18.0 + x-fern-language: + - Python + x-fern-sdk-name: + - cohere + x-fern-sdk-version: + - 5.18.0 + method: POST + uri: https://api.cohere.com/v2/chat + response: + body: + string: '{"id":"8289d4ee-a83b-4ce2-b7e1-245d9778fcf5","message":{"role":"assistant","content":[{"type":"text","text":"The + weather in Tokyo is currently sunny and 20 degrees Celsius. The current time + is 4:20 PM."}],"citations":[{"start":34,"end":39,"text":"sunny","sources":[{"type":"tool","id":"get_time_eksdqe8f9g4y:0","tool_output":{"content":"Sunny + 20 degrees Celsius"}}],"type":"TEXT_CONTENT"},{"start":44,"end":63,"text":"20 + degrees Celsius.","sources":[{"type":"tool","id":"get_time_eksdqe8f9g4y:0","tool_output":{"content":"Sunny + 20 degrees Celsius"}}],"type":"TEXT_CONTENT"},{"start":84,"end":92,"text":"4:20 + PM.","sources":[{"type":"tool","id":"get_weather_mznfyh090g90:0","tool_output":{"content":"4:20 + PM"}}],"type":"TEXT_CONTENT"}]},"finish_reason":"COMPLETE","usage":{"billed_units":{"input_tokens":78,"output_tokens":25},"tokens":{"input_tokens":1694,"output_tokens":57}}}' + headers: + Alt-Svc: + - h3=":443"; ma=2592000,h3-29=":443"; ma=2592000 + Content-Length: + - '877' + Via: + - 1.1 google + access-control-expose-headers: + - X-Debug-Trace-ID + cache-control: + - no-cache, no-store, no-transform, must-revalidate, private, max-age=0 + content-type: + - application/json + date: + - Sun, 14 Sep 2025 03:04:15 GMT + expires: + - Thu, 01 Jan 1970 00:00:00 GMT + num_chars: + - '7791' + num_tokens: + - '103' + pragma: + - no-cache + server: + - envoy + vary: + - Origin + x-accel-expires: + - '0' + x-debug-trace-id: + - 55736c33493297302f3e7a5baf0b265c + x-envoy-upstream-service-time: + - '393' + status: + code: 200 + message: OK +version: 1 diff --git a/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_v2_chat_legacy_with_tool_calls_and_streaming.yaml b/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_v2_chat_legacy_with_tool_calls_and_streaming.yaml new file mode 100644 index 0000000000..049e9c3d93 --- /dev/null +++ b/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_v2_chat_legacy_with_tool_calls_and_streaming.yaml @@ -0,0 +1,248 @@ +interactions: +- request: + body: '{"model": "command-r", "messages": [{"role": "user", "content": "What is + the weather and current time in Tokyo?"}], "tools": [{"type": "function", "function": + {"name": "get_weather", "description": "Get the current weather in a given location", + "parameters": {"type": "object", "properties": {"location": {"type": "string", + "description": "The city and state, e.g. San Francisco, CA"}}, "required": ["location"]}}}, + {"type": "function", "function": {"name": "get_time", "description": "Get the + current time in a given location", "parameters": {"type": "object", "properties": + {"location": {"type": "string", "description": "The city and state, e.g. San + Francisco, CA"}}, "required": ["location"]}}}], "stream": true}' + headers: + accept: + - '*/*' + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '716' + content-type: + - application/json + host: + - api.cohere.com + user-agent: + - cohere/5.18.0 + x-fern-language: + - Python + x-fern-sdk-name: + - cohere + x-fern-sdk-version: + - 5.18.0 + method: POST + uri: https://api.cohere.com/v2/chat + response: + body: + string: 'event: message-start + + data: {"id":"e6d757a9-f0f3-40fe-9b8a-44cdc3bd18a7","type":"message-start","delta":{"message":{"role":"assistant","content":[],"tool_plan":"","tool_calls":[],"citations":[]}}} + + + event: tool-plan-delta + + data: {"type":"tool-plan-delta","delta":{"message":{"tool_plan":"I"}}} + + + event: tool-plan-delta + + data: {"type":"tool-plan-delta","delta":{"message":{"tool_plan":" will"}}} + + + event: tool-plan-delta + + data: {"type":"tool-plan-delta","delta":{"message":{"tool_plan":" search"}}} + + + event: tool-plan-delta + + data: {"type":"tool-plan-delta","delta":{"message":{"tool_plan":" for"}}} + + + event: tool-plan-delta + + data: {"type":"tool-plan-delta","delta":{"message":{"tool_plan":" the"}}} + + + event: tool-plan-delta + + data: {"type":"tool-plan-delta","delta":{"message":{"tool_plan":" current"}}} + + + event: tool-plan-delta + + data: {"type":"tool-plan-delta","delta":{"message":{"tool_plan":" time"}}} + + + event: tool-plan-delta + + data: {"type":"tool-plan-delta","delta":{"message":{"tool_plan":" and"}}} + + + event: tool-plan-delta + + data: {"type":"tool-plan-delta","delta":{"message":{"tool_plan":" weather"}}} + + + event: tool-plan-delta + + data: {"type":"tool-plan-delta","delta":{"message":{"tool_plan":" in"}}} + + + event: tool-plan-delta + + data: {"type":"tool-plan-delta","delta":{"message":{"tool_plan":" Tokyo"}}} + + + event: tool-plan-delta + + data: {"type":"tool-plan-delta","delta":{"message":{"tool_plan":"."}}} + + + event: tool-call-start + + data: {"type":"tool-call-start","index":0,"delta":{"message":{"tool_calls":{"id":"get_time_dg5wwc00d8v5","type":"function","function":{"name":"get_time","arguments":""}}}}} + + + event: tool-call-delta + + data: {"type":"tool-call-delta","index":0,"delta":{"message":{"tool_calls":{"function":{"arguments":"{\n \""}}}}} + + + event: tool-call-delta + + data: {"type":"tool-call-delta","index":0,"delta":{"message":{"tool_calls":{"function":{"arguments":"location"}}}}} + + + event: tool-call-delta + + data: {"type":"tool-call-delta","index":0,"delta":{"message":{"tool_calls":{"function":{"arguments":"\":"}}}}} + + + event: tool-call-delta + + data: {"type":"tool-call-delta","index":0,"delta":{"message":{"tool_calls":{"function":{"arguments":" + \""}}}}} + + + event: tool-call-delta + + data: {"type":"tool-call-delta","index":0,"delta":{"message":{"tool_calls":{"function":{"arguments":"Tokyo"}}}}} + + + event: tool-call-delta + + data: {"type":"tool-call-delta","index":0,"delta":{"message":{"tool_calls":{"function":{"arguments":"\""}}}}} + + + event: tool-call-delta + + data: {"type":"tool-call-delta","index":0,"delta":{"message":{"tool_calls":{"function":{"arguments":"\n"}}}}} + + + event: tool-call-delta + + data: {"type":"tool-call-delta","index":0,"delta":{"message":{"tool_calls":{"function":{"arguments":"}"}}}}} + + + event: tool-call-end + + data: {"type":"tool-call-end","index":0} + + + event: tool-call-start + + data: {"type":"tool-call-start","index":1,"delta":{"message":{"tool_calls":{"id":"get_weather_bc8241gkqss5","type":"function","function":{"name":"get_weather","arguments":""}}}}} + + + event: tool-call-delta + + data: {"type":"tool-call-delta","index":1,"delta":{"message":{"tool_calls":{"function":{"arguments":"{\n \""}}}}} + + + event: tool-call-delta + + data: {"type":"tool-call-delta","index":1,"delta":{"message":{"tool_calls":{"function":{"arguments":"location"}}}}} + + + event: tool-call-delta + + data: {"type":"tool-call-delta","index":1,"delta":{"message":{"tool_calls":{"function":{"arguments":"\":"}}}}} + + + event: tool-call-delta + + data: {"type":"tool-call-delta","index":1,"delta":{"message":{"tool_calls":{"function":{"arguments":" + \""}}}}} + + + event: tool-call-delta + + data: {"type":"tool-call-delta","index":1,"delta":{"message":{"tool_calls":{"function":{"arguments":"Tokyo"}}}}} + + + event: tool-call-delta + + data: {"type":"tool-call-delta","index":1,"delta":{"message":{"tool_calls":{"function":{"arguments":"\""}}}}} + + + event: tool-call-delta + + data: {"type":"tool-call-delta","index":1,"delta":{"message":{"tool_calls":{"function":{"arguments":"\n"}}}}} + + + event: tool-call-delta + + data: {"type":"tool-call-delta","index":1,"delta":{"message":{"tool_calls":{"function":{"arguments":"}"}}}}} + + + event: tool-call-end + + data: {"type":"tool-call-end","index":1} + + + event: message-end + + data: {"type":"message-end","delta":{"finish_reason":"TOOL_CALL","usage":{"billed_units":{"input_tokens":62,"output_tokens":28},"tokens":{"input_tokens":968,"output_tokens":83}}}} + + + data: [DONE] + + + ' + headers: + Alt-Svc: + - h3=":443"; ma=2592000,h3-29=":443"; ma=2592000 + Transfer-Encoding: + - chunked + Via: + - 1.1 google + access-control-expose-headers: + - X-Debug-Trace-ID + cache-control: + - no-cache, no-store, no-transform, must-revalidate, private, max-age=0 + content-type: + - text/event-stream + date: + - Sun, 14 Sep 2025 02:50:46 GMT + expires: + - Thu, 01 Jan 1970 00:00:00 GMT + pragma: + - no-cache + server: + - envoy + vary: + - Origin + x-accel-expires: + - '0' + x-api-warning: + - model 'command-r' is deprecated and will be removed September 15 2025. Please + consider upgrading to a newer model to avoid future service disruptions + x-debug-trace-id: + - 356637ec837563f4f9042748f80d7d28 + x-envoy-upstream-service-time: + - '270' + status: + code: 200 + message: OK +version: 1 diff --git a/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_v2_chat_legacy_with_tool_calls_and_streaming_async.yaml b/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_v2_chat_legacy_with_tool_calls_and_streaming_async.yaml new file mode 100644 index 0000000000..d689d2137b --- /dev/null +++ b/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_chat/test_cohere_v2_chat_legacy_with_tool_calls_and_streaming_async.yaml @@ -0,0 +1,283 @@ +interactions: +- request: + body: '{"model": "command-r", "messages": [{"role": "user", "content": "What is + the weather and current time in Tokyo?"}], "tools": [{"type": "function", "function": + {"name": "get_weather", "description": "Get the current weather in a given location", + "parameters": {"type": "object", "properties": {"location": {"type": "string", + "description": "The city and state, e.g. San Francisco, CA"}}, "required": ["location"]}}}, + {"type": "function", "function": {"name": "get_time", "description": "Get the + current time in a given location", "parameters": {"type": "object", "properties": + {"location": {"type": "string", "description": "The city and state, e.g. San + Francisco, CA"}}, "required": ["location"]}}}], "stream": true}' + headers: + accept: + - '*/*' + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '716' + content-type: + - application/json + host: + - api.cohere.com + user-agent: + - cohere/5.18.0 + x-fern-language: + - Python + x-fern-sdk-name: + - cohere + x-fern-sdk-version: + - 5.18.0 + method: POST + uri: https://api.cohere.com/v2/chat + response: + body: + string: 'event: message-start + + data: {"id":"ce257b09-c6da-4aed-b722-6384504180f5","type":"message-start","delta":{"message":{"role":"assistant","content":[],"tool_plan":"","tool_calls":[],"citations":[]}}} + + + event: tool-plan-delta + + data: {"type":"tool-plan-delta","delta":{"message":{"tool_plan":"I"}}} + + + event: tool-plan-delta + + data: {"type":"tool-plan-delta","delta":{"message":{"tool_plan":" will"}}} + + + event: tool-plan-delta + + data: {"type":"tool-plan-delta","delta":{"message":{"tool_plan":" search"}}} + + + event: tool-plan-delta + + data: {"type":"tool-plan-delta","delta":{"message":{"tool_plan":" for"}}} + + + event: tool-plan-delta + + data: {"type":"tool-plan-delta","delta":{"message":{"tool_plan":" the"}}} + + + event: tool-plan-delta + + data: {"type":"tool-plan-delta","delta":{"message":{"tool_plan":" current"}}} + + + event: tool-plan-delta + + data: {"type":"tool-plan-delta","delta":{"message":{"tool_plan":" time"}}} + + + event: tool-plan-delta + + data: {"type":"tool-plan-delta","delta":{"message":{"tool_plan":" and"}}} + + + event: tool-plan-delta + + data: {"type":"tool-plan-delta","delta":{"message":{"tool_plan":" weather"}}} + + + event: tool-plan-delta + + data: {"type":"tool-plan-delta","delta":{"message":{"tool_plan":" in"}}} + + + event: tool-plan-delta + + data: {"type":"tool-plan-delta","delta":{"message":{"tool_plan":" Tokyo"}}} + + + event: tool-plan-delta + + data: {"type":"tool-plan-delta","delta":{"message":{"tool_plan":" and"}}} + + + event: tool-plan-delta + + data: {"type":"tool-plan-delta","delta":{"message":{"tool_plan":" relay"}}} + + + event: tool-plan-delta + + data: {"type":"tool-plan-delta","delta":{"message":{"tool_plan":" this"}}} + + + event: tool-plan-delta + + data: {"type":"tool-plan-delta","delta":{"message":{"tool_plan":" information"}}} + + + event: tool-plan-delta + + data: {"type":"tool-plan-delta","delta":{"message":{"tool_plan":" to"}}} + + + event: tool-plan-delta + + data: {"type":"tool-plan-delta","delta":{"message":{"tool_plan":" the"}}} + + + event: tool-plan-delta + + data: {"type":"tool-plan-delta","delta":{"message":{"tool_plan":" user"}}} + + + event: tool-plan-delta + + data: {"type":"tool-plan-delta","delta":{"message":{"tool_plan":"."}}} + + + event: tool-call-start + + data: {"type":"tool-call-start","index":0,"delta":{"message":{"tool_calls":{"id":"get_time_mp1131yrhbga","type":"function","function":{"name":"get_time","arguments":""}}}}} + + + event: tool-call-delta + + data: {"type":"tool-call-delta","index":0,"delta":{"message":{"tool_calls":{"function":{"arguments":"{\n \""}}}}} + + + event: tool-call-delta + + data: {"type":"tool-call-delta","index":0,"delta":{"message":{"tool_calls":{"function":{"arguments":"location"}}}}} + + + event: tool-call-delta + + data: {"type":"tool-call-delta","index":0,"delta":{"message":{"tool_calls":{"function":{"arguments":"\":"}}}}} + + + event: tool-call-delta + + data: {"type":"tool-call-delta","index":0,"delta":{"message":{"tool_calls":{"function":{"arguments":" + \""}}}}} + + + event: tool-call-delta + + data: {"type":"tool-call-delta","index":0,"delta":{"message":{"tool_calls":{"function":{"arguments":"Tokyo"}}}}} + + + event: tool-call-delta + + data: {"type":"tool-call-delta","index":0,"delta":{"message":{"tool_calls":{"function":{"arguments":"\""}}}}} + + + event: tool-call-delta + + data: {"type":"tool-call-delta","index":0,"delta":{"message":{"tool_calls":{"function":{"arguments":"\n"}}}}} + + + event: tool-call-delta + + data: {"type":"tool-call-delta","index":0,"delta":{"message":{"tool_calls":{"function":{"arguments":"}"}}}}} + + + event: tool-call-end + + data: {"type":"tool-call-end","index":0} + + + event: tool-call-start + + data: {"type":"tool-call-start","index":1,"delta":{"message":{"tool_calls":{"id":"get_weather_yxz1xx2m07cn","type":"function","function":{"name":"get_weather","arguments":""}}}}} + + + event: tool-call-delta + + data: {"type":"tool-call-delta","index":1,"delta":{"message":{"tool_calls":{"function":{"arguments":"{\n \""}}}}} + + + event: tool-call-delta + + data: {"type":"tool-call-delta","index":1,"delta":{"message":{"tool_calls":{"function":{"arguments":"location"}}}}} + + + event: tool-call-delta + + data: {"type":"tool-call-delta","index":1,"delta":{"message":{"tool_calls":{"function":{"arguments":"\":"}}}}} + + + event: tool-call-delta + + data: {"type":"tool-call-delta","index":1,"delta":{"message":{"tool_calls":{"function":{"arguments":" + \""}}}}} + + + event: tool-call-delta + + data: {"type":"tool-call-delta","index":1,"delta":{"message":{"tool_calls":{"function":{"arguments":"Tokyo"}}}}} + + + event: tool-call-delta + + data: {"type":"tool-call-delta","index":1,"delta":{"message":{"tool_calls":{"function":{"arguments":"\""}}}}} + + + event: tool-call-delta + + data: {"type":"tool-call-delta","index":1,"delta":{"message":{"tool_calls":{"function":{"arguments":"\n"}}}}} + + + event: tool-call-delta + + data: {"type":"tool-call-delta","index":1,"delta":{"message":{"tool_calls":{"function":{"arguments":"}"}}}}} + + + event: tool-call-end + + data: {"type":"tool-call-end","index":1} + + + event: message-end + + data: {"type":"message-end","delta":{"finish_reason":"TOOL_CALL","usage":{"billed_units":{"input_tokens":62,"output_tokens":35},"tokens":{"input_tokens":968,"output_tokens":90}}}} + + + data: [DONE] + + + ' + headers: + Alt-Svc: + - h3=":443"; ma=2592000,h3-29=":443"; ma=2592000 + Transfer-Encoding: + - chunked + Via: + - 1.1 google + access-control-expose-headers: + - X-Debug-Trace-ID + cache-control: + - no-cache, no-store, no-transform, must-revalidate, private, max-age=0 + content-type: + - text/event-stream + date: + - Sun, 14 Sep 2025 03:00:27 GMT + expires: + - Thu, 01 Jan 1970 00:00:00 GMT + pragma: + - no-cache + server: + - envoy + vary: + - Origin + x-accel-expires: + - '0' + x-api-warning: + - model 'command-r' is deprecated and will be removed September 15 2025. Please + consider upgrading to a newer model to avoid future service disruptions + x-debug-trace-id: + - 471c84acae7cecba8477f34ef53ed722 + x-envoy-upstream-service-time: + - '134' + status: + code: 200 + message: OK +version: 1 diff --git a/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_embed/test_cohere_v2_embed_legacy.yaml b/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_embed/test_cohere_v2_embed_legacy.yaml new file mode 100644 index 0000000000..22d5ddeb14 --- /dev/null +++ b/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_embed/test_cohere_v2_embed_legacy.yaml @@ -0,0 +1,92 @@ +interactions: +- request: + body: '{"texts": ["Carson City is the capital city of the American state of Nevada. + At the 2010 United States Census, Carson City had a population of 55,274.", + "The Commonwealth of the Northern Mariana Islands is a group of islands in the + Pacific Ocean that are a political division controlled by the United States. + Its capital is Saipan.", "Charlotte Amalie is the capital and largest city of + the United States Virgin Islands. It has about 20,000 people. The city is on + the island of Saint Thomas.", "Washington, D.C. (also known as simply Washington + or D.C., and officially as the District of Columbia) is the capital of the United + States. It is a federal district. ", "Capital punishment (the death penalty) + has existed in the United States since before the United States was a country. + As of 2017, capital punishment is legal in 30 of the 50 states.", "North Dakota + is a state in the United States. 672,591 people lived in North Dakota in the + year 2010. The capital and seat of government is Bismarck."], "model": "embed-english-light-v3.0", + "input_type": "search_document"}' + headers: + accept: + - '*/*' + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '1072' + content-type: + - application/json + host: + - api.cohere.com + user-agent: + - cohere/5.18.0 + x-fern-language: + - Python + x-fern-sdk-name: + - cohere + x-fern-sdk-version: + - 5.18.0 + method: POST + uri: https://api.cohere.com/v2/embed + response: + body: + string: '{"id":"74d7aae4-2939-4002-b4d4-352dfcca03cf","texts":["carson city + is the capital city of the american state of nevada. at the 2010 united states + census, carson city had a population of 55, 274.","the commonwealth of the + northern mariana islands is a group of islands in the pacific ocean that are + a political division controlled by the united states. its capital is saipan.","charlotte + amalie is the capital and largest city of the united states virgin islands. + it has about 20, 000 people. the city is on the island of saint thomas.","washington, + d. c. ( also known as simply washington or d. c., and officially as the district + of columbia ) is the capital of the united states. it is a federal district.","capital + punishment ( the death penalty ) has existed in the united states since before + the united states was a country. as of 2017, capital punishment is legal in + 30 of the 50 states.","north dakota is a state in the united states. 672, + 591 people lived in north dakota in the year 2010. the capital and seat of + government is bismarck."],"embeddings":{"float":[[0.032318115,-0.031188965,-0.06604004,0.028823853,-0.017730713,-0.07757568,0.02305603,0.008758545,-0.004558563,0.0725708,-0.112976074,-0.05142212,0.08526611,-0.11383057,-0.052337646,-0.010803223,0.02848816,-0.08453369,0.06365967,-0.0647583,-0.066467285,0.10449219,0.037841797,-0.01134491,-0.020523071,-0.15917969,-0.07720947,-0.015106201,-0.032836914,0.092041016,-0.018463135,-0.034179688,0.06137085,0.05404663,0.090270996,-0.061828613,0.058654785,-0.013000488,-0.046081543,0.0552063,0.022109985,0.12646484,0.0031318665,-0.083984375,-0.050231934,0.049804688,-0.059020996,-0.005924225,0.018157959,0.0066566467,0.07446289,0.015808105,0.014984131,0.050750732,-0.046936035,0.05807495,0.014465332,-0.038238525,-0.03869629,-0.017227173,-0.07739258,-0.015258789,-0.03845215,-0.056762695,0.006286621,0.061553955,0.035858154,-0.11004639,-0.011672974,-0.03036499,0.06286621,-0.1060791,-0.059020996,0.006324768,0.01586914,0.0066566467,-0.054748535,0.077819824,0.057861328,0.0647583,0.0703125,-0.039733887,-0.002840042,-0.05999756,-0.01676941,0.0871582,0.010658264,-0.0004172325,0.035980225,-0.033081055,0.03692627,0.007045746,-0.009506226,-0.06738281,-0.04168701,0.029342651,0.029571533,0.021896362,0.0037384033,-0.03656006,0.010749817,0.022064209,-0.028366089,-0.032226562,-0.076660156,-0.017486572,-0.013084412,0.09246826,-0.057495117,0.020462036,-0.054656982,0.040130615,0.0236969,-0.016052246,-0.0001552105,-0.019485474,0.0647583,-0.03112793,-0.055541992,-0.0025463104,0.008453369,-0.078308105,0.0211792,0.022064209,0.07940674,-0.016464233,-0.00052022934,-0.03543091,-0.00015723705,-0.0035209656,0.02571106,0.052093506,-0.016708374,0.00015437603,-0.02027893,-0.012313843,0.009552002,-0.08026123,-0.002363205,0.007045746,0.099731445,0.10467529,-0.009651184,-0.0029239655,-0.025146484,0.024047852,0.049987793,0.001156807,-0.03353882,0.06359863,0.04699707,0.068603516,-0.0064888,-0.03265381,-0.11920166,-0.024337769,0.076660156,-0.02432251,0.018936157,0.06915283,0.081726074,0.04827881,0.05166626,0.058532715,-0.024627686,0.12609863,-0.056396484,-0.0836792,-0.041503906,0.099853516,0.04751587,-0.053100586,-0.10449219,0.004146576,0.07098389,-0.019332886,-0.011924744,0.015197754,0.0034313202,0.10321045,-0.031341553,0.06750488,-0.015274048,0.01651001,-0.043792725,-0.05328369,-0.012451172,0.0074691772,0.015182495,-0.1126709,-0.0066566467,-0.044708252,0.0078125,-0.048095703,-0.042144775,0.04611206,0.02571106,0.039764404,0.13635254,-0.056488037,0.049194336,-0.000101327896,0.0090789795,0.011520386,0.05960083,0.0058059692,0.05392456,0.07324219,-0.031280518,0.021255493,0.028701782,0.015602112,0.08117676,-0.0814209,0.031677246,0.011810303,0.04449463,-0.0023326874,-0.055725098,0.020965576,0.02708435,-0.017166138,-0.02859497,0.050933838,-0.14575195,0.0072898865,0.011299133,-0.087524414,0.04525757,-0.05581665,0.08959961,0.017547607,-0.03250122,-0.013885498,0.016662598,0.058441162,0.0418396,-0.04449463,-0.04171753,0.0067481995,0.059692383,0.07330322,-0.05407715,0.052642822,-0.09564209,-0.06951904,-0.09051514,-0.06842041,0.041992188,-0.023101807,-0.12731934,-0.068603516,0.008605957,-0.024154663,-0.05618286,-0.0007596016,0.048858643,0.080322266,0.034332275,0.029922485,0.021591187,-0.060546875,0.0067863464,-0.032836914,0.0052452087,-0.0057868958,-0.066589355,0.03062439,-0.025802612,0.053100586,-0.04852295,-0.027313232,-0.082336426,0.059265137,0.010284424,0.006843567,-0.03491211,-0.007019043,0.03225708,0.043884277,0.0059394836,0.0015859604,0.055908203,-0.011398315,-0.027038574,-0.023956299,-0.023971558,0.030197144,-0.064697266,-0.035980225,-0.06097412,-0.08117676,-0.0066375732,0.02935791,0.014526367,-0.032836914,-0.023468018,0.02998352,-0.045776367,0.023529053,0.054870605,0.11138916,0.0970459,0.024261475,0.024993896,-0.042785645,0.05102539,0.042419434,-0.015396118,0.034576416,-0.013397217,-0.025054932,0.12060547,0.06756592,0.005558014,0.022003174,-0.037384033,-0.081970215,0.020751953,-0.00844574,0.096191406,-0.025253296,-0.029266357,0.06347656,0.026382446,0.041625977,0.033996582,0.0042800903,-0.06161499,0.05419922,-0.028427124,-0.0025024414,0.0035476685,0.01637268,-0.072509766,-0.039154053,0.0146102905,0.080444336,0.043914795,-0.055480957,-0.010917664,-0.08526611,-0.09661865,-0.011268616,-0.018676758,0.05532837,0.05255127,-0.005821228,-0.036895752,-0.026931763,0.05645752,-0.0440979,0.048095703,-0.07019043,0.053466797,-0.0007586479,-0.04925537,0.02911377,0.010520935,-0.04714966,0.021331787,-0.017669678,-0.02519226,-0.011955261,-0.0067100525,-0.072021484,-0.06890869,-0.021774292,-0.026809692,0.0053100586,0.030426025,0.07354736,0.059417725,0.03579712,0.0031528473,0.0541687,-0.049926758,-0.015083313,0.03427124,0.023666382,0.0014266968,0.048431396,-0.02142334,-0.046936035],[0.034454346,-0.03652954,0.121520996,-0.08618164,0.015960693,-0.0647583,0.07354736,0.061431885,0.020614624,0.0012788773,0.01612854,-0.06121826,-0.031555176,-0.012077332,0.011062622,0.028533936,-0.041137695,-0.0619812,-0.005203247,0.009513855,0.059814453,0.10748291,-0.10455322,-0.0046157837,0.07940674,-0.037994385,0.027359009,-0.013954163,0.03793335,-0.0154418945,-0.0038108826,-0.04257202,0.001666069,-0.023635864,0.04272461,0.0022354126,0.01902771,-0.033691406,0.04284668,-0.09857178,-0.047088623,0.046966553,0.04144287,0.056274414,0.0030555725,0.024154663,-0.089782715,-0.0038490295,-0.064941406,0.065979004,0.07495117,-0.07989502,-0.044799805,0.037628174,0.014404297,0.050598145,-0.0028591156,0.039276123,0.07159424,-0.005203247,0.03491211,0.04373169,-0.036956787,0.0014915466,0.016952515,0.032470703,0.047821045,0.048461914,-0.0126571655,-0.120666504,-0.053863525,0.0046463013,0.001964569,-0.0049324036,-0.008514404,0.013000488,0.02154541,-0.0019817352,0.0018005371,0.0032482147,0.06921387,0.0725708,0.010566711,-0.038726807,0.06774902,-0.029159546,-0.022445679,0.048980713,0.035858154,0.017593384,-0.023590088,0.029800415,0.11895752,-0.044555664,-0.030014038,0.10961914,-0.06185913,0.025619507,0.078552246,0.00066518784,0.018478394,0.09680176,0.029006958,-0.10253906,-0.09057617,0.10040283,0.02909851,0.019546509,0.09918213,0.038360596,-0.03149414,0.020339966,0.008979797,-0.05429077,0.015419006,-0.10192871,0.036010742,-0.032226562,-0.057800293,0.011566162,0.047302246,-0.10986328,0.032104492,-0.05227661,0.072509766,-0.025558472,-0.060333252,-0.0859375,0.058044434,-0.07659912,0.017227173,0.03225708,0.029953003,0.0049057007,0.066833496,-0.03881836,-0.093322754,-0.121398926,-0.049560547,0.04348755,0.081848145,0.017074585,0.06604004,0.012817383,0.076293945,0.017150879,0.05645752,-0.019622803,-0.011665344,0.059692383,-0.036132812,0.030273438,-0.026519775,-0.01612854,-0.0715332,-0.06964111,-0.00009262562,-0.04336548,-0.0076560974,-0.025924683,0.03741455,-0.017227173,-0.07318115,0.031280518,0.03692627,0.04373169,-0.00016987324,0.039978027,-0.06707764,0.056884766,0.01789856,0.020141602,0.040100098,0.00365448,-0.031982422,-0.06933594,0.014656067,0.08898926,-0.035949707,-0.0044441223,-0.070739746,-0.02696228,0.03866577,-0.055114746,-0.06756592,0.047912598,-0.04788208,0.009780884,0.05569458,-0.019882202,0.0050239563,0.00630188,-0.024841309,0.0670166,-0.06097412,-0.08166504,0.03845215,0.050842285,0.06524658,0.056243896,0.03942871,0.07824707,-0.039794922,0.028961182,0.01651001,0.022445679,-0.018295288,0.01234436,-0.012367249,-0.010047913,-0.05227661,-0.003730774,0.0065078735,-0.075805664,0.045715332,0.0054779053,-0.013648987,-0.012496948,-0.05001831,0.032409668,0.06311035,-0.06149292,0.01586914,0.042510986,-0.078063965,-0.090270996,-0.05392456,-0.080200195,-0.030578613,0.02947998,0.060333252,0.031921387,-0.051239014,-0.018066406,-0.075927734,-0.044281006,0.08831787,-0.020645142,-0.04043579,0.011634827,0.13012695,0.049804688,0.000052154064,0.02406311,-0.008621216,-0.052001953,0.016433716,-0.05758667,-0.010757446,-0.09307861,-0.038269043,-0.06121826,-0.0007548332,-0.026184082,-0.03793335,0.008018494,0.049468994,-0.074035645,-0.075683594,-0.11462402,-0.0032215118,-0.10650635,0.018737793,-0.010734558,0.052825928,-0.0647583,-0.011070251,0.11224365,-0.064331055,0.019821167,0.012611389,-0.013900757,-0.0869751,-0.024307251,-0.0055770874,-0.04748535,0.048431396,-0.009002686,0.06866455,0.01777649,-0.07507324,0.0012559891,0.053955078,0.01499176,-0.048217773,-0.076293945,-0.015792847,-0.0036640167,0.043518066,0.032806396,0.016662598,-0.0042800903,0.066589355,-0.03555298,0.08325195,-0.019073486,-0.0049057007,0.037994385,0.015975952,0.04800415,0.04434204,0.021896362,0.049346924,-0.029891968,0.041992188,-0.027038574,-0.03314209,-0.011871338,-0.0473938,0.039978027,0.013793945,-0.032684326,-0.10632324,-0.015365601,0.08276367,-0.13671875,0.017105103,-0.02003479,0.011482239,-0.021026611,0.026184082,-0.05117798,0.03289795,0.0026416779,0.005493164,0.0087509155,-0.06365967,-0.05126953,0.14074707,0.078552246,0.044189453,0.054351807,0.021331787,-0.04321289,0.05429077,0.012863159,-0.04675293,0.0647583,0.03717041,-0.015625,-0.007347107,-0.014808655,-0.019546509,0.08428955,-0.0018234253,0.0039978027,0.05596924,-0.05166626,0.0657959,0.010360718,-0.021240234,-0.013412476,-0.068481445,-0.0071907043,-0.035247803,0.1352539,0.00015163422,0.005306244,-0.004173279,-0.07537842,0.001042366,0.0970459,0.017227173,0.010757446,-0.0871582,-0.016784668,0.022140503,0.08355713,0.0060768127,0.020050049,-0.047088623,-0.04949951,-0.029464722,-0.060180664,-0.0748291,0.015022278,-0.113586426,0.02998352,-0.031280518,0.08190918,0.021072388,0.019744873,-0.046020508,-0.025680542],[-0.015945435,-0.07232666,0.059020996,-0.00674057,-0.022827148,-0.076049805,-0.0012760162,0.0026111603,-0.06463623,0.018249512,0.015525818,-0.0031166077,-0.05810547,-0.08911133,-0.047058105,0.06060791,0.010871887,-0.04232788,0.04763794,-0.027435303,0.036865234,-0.0010910034,-0.011474609,-0.082336426,0.03857422,-0.105895996,-0.04067993,-0.0033340454,-0.004055023,0.011619568,0.025878906,-0.09338379,0.03466797,0.101257324,-0.00484848,-0.030944824,0.08190918,0.030944824,0.09967041,-0.010047913,0.031158447,0.1307373,-0.030303955,0.054534912,-0.025772095,0.0362854,-0.093688965,0.0463562,-0.008277893,0.032196045,0.10046387,-0.047851562,-0.043914795,0.035064697,-0.0016546249,-0.079956055,-0.04046631,-0.059692383,-0.01184082,-0.052947998,0.05810547,-0.04827881,-0.013977051,0.0031147003,-0.007843018,0.008590698,0.021560669,0.045898438,0.010368347,-0.04776001,0.04031372,-0.047851562,-0.014808655,0.039276123,0.029846191,-0.015129089,-0.1194458,0.04776001,0.058624268,0.06890869,0.062408447,-0.024398804,0.027053833,-0.014198303,-0.015533447,0.004470825,-0.012992859,0.15161133,0.02558899,0.036010742,-0.04058838,-0.0042495728,-0.04788208,-0.053741455,-0.034454346,0.03302002,0.00013899803,0.02468872,-0.009315491,-0.01411438,0.009315491,0.09118652,0.043823242,0.008178711,-0.0063934326,0.1005249,0.055419922,-0.023025513,0.1673584,-0.025909424,-0.10070801,0.028579712,-0.02394104,-0.019042969,-0.037139893,-0.04446411,0.11053467,-0.046875,-0.125,-0.050964355,-0.044769287,-0.037628174,0.025314331,-0.01828003,-0.027877808,-0.024932861,0.02482605,-0.0149002075,-0.04626465,-0.028518677,0.0023345947,0.14550781,0.012290955,-0.005760193,-0.02168274,-0.0063972473,-0.0050964355,-0.17602539,-0.0635376,-0.011413574,0.06384277,0.057617188,0.06524658,-0.031707764,0.072509766,0.0049819946,-0.034301758,0.010658264,-0.0045547485,-0.012321472,-0.030151367,-0.003025055,-0.057403564,-0.0049858093,-0.0050239563,0.0096206665,0.07055664,-0.05923462,0.091308594,0.06109619,0.09655762,0.045288086,0.0072631836,0.024597168,0.012573242,-0.0038795471,-0.09234619,-0.005214691,-0.099365234,-0.051757812,0.016113281,-0.025222778,-0.01058197,0.02909851,0.004776001,-0.012046814,0.0592041,0.09832764,0.007411957,0.028213501,-0.07458496,0.06915283,-0.0044441223,0.08026123,0.031036377,-0.0017576218,0.008041382,-0.0037059784,-0.029693604,-0.11248779,0.057403564,-0.039398193,-0.021865845,0.013717651,-0.032714844,-0.00072050095,-0.015960693,0.070007324,0.041137695,-0.027008057,0.045410156,0.018798828,-0.011192322,0.058013916,0.0395813,-0.057037354,0.008903503,0.049926758,-0.05505371,-0.0058555603,-0.030090332,0.02835083,0.085754395,-0.09814453,-0.034210205,0.029205322,0.006828308,-0.035980225,0.030914307,-0.017730713,0.0637207,0.061309814,-0.06933594,-0.011940002,-0.085632324,-0.042907715,0.01927185,-0.069885254,0.026123047,0.03543091,0.07513428,0.024673462,-0.051483154,-0.057006836,-0.036621094,-0.0019521713,-0.04159546,-0.047058105,-0.03201294,-0.015533447,0.033172607,0.0063934326,0.0056266785,0.0061569214,-0.015838623,-0.035980225,0.0023937225,-0.052246094,0.0413208,-0.03387451,-0.0053901672,-0.055633545,-0.05267334,-0.0074386597,-0.05645752,-0.026367188,0.029922485,-0.001376152,-0.016860962,0.04257202,0.12609863,0.04421997,0.025680542,-0.05630493,0.02293396,0.026916504,-0.09680176,0.059143066,0.10864258,-0.011512756,0.029205322,-0.08605957,-0.08300781,0.027511597,-0.040283203,0.018295288,0.02822876,-0.009185791,0.020858765,0.034454346,-0.09637451,-0.029769897,0.044555664,-0.008552551,-0.043395996,-0.056793213,-0.086242676,0.05206299,-0.0016241074,0.0368042,0.025344849,0.00289917,-0.015350342,0.10571289,0.036590576,0.04510498,-0.07330322,0.026657104,-0.053863525,0.09020996,0.046447754,-0.0033073425,-0.02822876,-0.028503418,-0.0039100647,0.027770996,-0.103271484,0.0074882507,-0.043670654,0.03338623,0.062561035,-0.021209717,-0.022399902,0.058898926,-0.026611328,-0.15673828,-0.008369446,-0.07055664,0.033355713,-0.010986328,0.0158844,-0.04147339,-0.045410156,0.042663574,0.035247803,-0.03366089,0.012123108,-0.02999878,0.02168274,0.09649658,-0.064941406,0.011291504,0.002790451,-0.11151123,-0.012588501,-0.009407043,-0.0012493134,0.034118652,0.07318115,-0.0028057098,-0.004142761,-0.042510986,-0.03086853,-0.0309906,-0.008293152,-0.01158905,-0.0041542053,-0.04269409,-0.056610107,0.018310547,0.12670898,-0.015960693,0.061828613,-0.042907715,-0.042816162,0.012069702,-0.049041748,0.02168274,0.09411621,0.052642822,-0.044799805,0.002380371,-0.026168823,0.014884949,0.036621094,0.017715454,0.029510498,0.001452446,0.05593872,-0.013168335,0.016830444,0.033203125,0.03753662,0.09295654,0.001619339,-0.06555176,-0.06970215,0.07635498,0.10284424,0.06286621,0.03866577,-0.014808655,-0.030700684,0.011665344],[0.023895264,0.068847656,0.006034851,0.028060913,-0.05328369,-0.009185791,0.060424805,0.041656494,0.0046844482,0.053833008,-0.03933716,-0.10253906,0.035247803,-0.029067993,-0.046081543,-0.0692749,0.050323486,-0.014419556,-0.13452148,0.10430908,0.02848816,0.099121094,-0.030380249,-0.021591187,0.017044067,-0.05532837,0.020233154,0.03793335,-0.046081543,0.006538391,-0.017456055,-0.04333496,-0.0042381287,0.05114746,0.050872803,-0.06048584,-0.010108948,0.08874512,0.077819824,0.03842163,-0.03805542,0.012298584,-0.02230835,-0.049926758,-0.0637207,0.059783936,-0.061340332,-0.0005903244,-0.027633667,-0.0051002502,0.07897949,0.0128479,0.026153564,0.06109619,-0.010406494,0.07324219,-0.016204834,0.038238525,0.039093018,0.068603516,-0.04385376,0.013381958,-0.097717285,0.07714844,0.08972168,0.007522583,0.009849548,-0.008621216,-0.044281006,-0.08929443,0.020462036,0.02432251,-0.028198242,0.048309326,0.06036377,0.041656494,-0.03781128,-0.003484726,0.009277344,0.033325195,0.045837402,-0.013435364,-0.08917236,-0.018630981,-0.0053977966,-0.05496216,0.026687622,0.046325684,-0.0102005005,-0.083862305,-0.039916992,0.015853882,0.030349731,-0.053375244,-0.13916016,-0.07104492,0.011192322,0.02861023,-0.009750366,-0.0070228577,-0.020553589,0.026885986,-0.087768555,-0.03845215,-0.0037899017,0.011253357,0.039093018,0.050231934,0.06524658,-0.044769287,-0.12695312,0.064941406,0.082214355,-0.022003174,0.06335449,-0.060791016,-0.015823364,-0.08758545,-0.04940796,-0.054901123,0.011428833,-0.0602417,-0.0010309219,-0.05630493,0.025421143,-0.11773682,0.04623413,0.02230835,0.06970215,-0.010093689,0.07043457,-0.00032758713,0.032684326,0.027252197,-0.076049805,-0.009773254,-0.05834961,-0.03491211,0.046905518,0.072021484,0.047821045,0.046905518,0.013969421,-0.06402588,0.0259552,-0.0051193237,-0.068603516,0.045013428,-0.022644043,0.053619385,-0.024673462,-0.0970459,0.07287598,-0.00092840195,-0.047454834,0.0023727417,0.047424316,-0.038909912,0.05053711,-0.07910156,0.047973633,0.020111084,-0.018310547,0.056549072,0.043823242,0.028427124,0.033355713,-0.020828247,-0.022369385,-0.0044670105,-0.034484863,0.05606079,0.06689453,0.016448975,-0.0025863647,-0.033081055,0.027145386,0.017715454,0.06439209,0.023742676,0.02067566,0.0075531006,-0.032470703,0.00894928,0.032470703,-0.037963867,-0.05239868,-0.033355713,0.019210815,0.0075683594,-0.07324219,0.04699707,-0.062469482,-0.02432251,-0.022064209,0.06524658,0.031021118,0.028060913,0.06524658,-0.075683594,0.109558105,0.09075928,-0.06945801,0.057434082,0.028717041,0.014465332,0.06768799,0.07672119,-0.038482666,0.01939392,0.0006918907,0.028793335,0.023345947,-0.07287598,-0.0006403923,-0.05596924,0.037231445,-0.029510498,-0.13354492,0.0029182434,-0.036071777,-0.016586304,-0.022155762,-0.00012993813,-0.07324219,-0.07312012,-0.039642334,0.000323534,-0.07421875,-0.020431519,0.040130615,-0.0118637085,-0.031799316,0.05255127,-0.030349731,0.059753418,-0.00793457,0.04788208,0.013397217,0.03881836,0.087768555,0.008453369,-0.08496094,-0.0030136108,-0.042663574,-0.059448242,-0.10845947,-0.08081055,0.015449524,-0.031158447,-0.03111267,0.045013428,0.028274536,0.032196045,0.0040016174,0.003479004,-0.041992188,0.051879883,-0.041137695,0.015670776,0.087402344,-0.049957275,-0.030670166,0.03387451,-0.0082473755,-0.039733887,-0.026977539,0.17346191,0.016845703,-0.037261963,0.0395813,-0.0579834,-0.06329346,0.0211792,-0.034851074,0.009643555,-0.0022029877,-0.0018224716,0.0496521,0.043151855,-0.10510254,-0.112854004,-0.01625061,-0.06915283,-0.038482666,-0.06604004,0.02708435,-0.01411438,0.000036120415,-0.07312012,-0.031951904,-0.10949707,-0.034301758,-0.009742737,0.14343262,-0.05218506,-0.05496216,0.00089263916,0.012397766,0.09448242,0.061920166,-0.0008125305,-0.04559326,0.0340271,0.04260254,0.04714966,0.029953003,-0.011390686,-0.042175293,0.07940674,0.014419556,0.061676025,-0.056762695,0.027328491,-0.0032367706,-0.0501709,0.00919342,-0.047454834,0.026992798,-0.01638794,0.023635864,0.037109375,0.022262573,0.037841797,-0.020233154,0.02178955,0.078125,-0.027862549,-0.029037476,0.13830566,0.04107666,0.06124878,-0.038116455,-0.06970215,0.07836914,0.091552734,0.025848389,-0.010284424,-0.068115234,0.066589355,-0.06549072,0.017349243,-0.04434204,-0.028152466,0.037017822,0.024597168,0.07019043,0.028945923,0.032226562,0.041503906,-0.0132369995,0.06903076,-0.016159058,-0.025756836,0.1116333,-0.03491211,0.12097168,-0.026412964,-0.018936157,-0.020721436,-0.0090408325,0.02407837,-0.049713135,0.044006348,-0.06951904,-0.070617676,0.048950195,0.005092621,-0.039886475,-0.078430176,-0.015083313,-0.00013649464,0.07702637,-0.015701294,-0.020248413,0.00020170212,-0.014472961,-0.025680542,-0.043548584,-0.033447266,-0.028747559,0.039093018,0.028823853,0.0046157837],[0.00020253658,-0.041259766,-0.050048828,0.021270752,-0.0020771027,-0.026123047,0.01802063,0.01550293,0.11578369,-0.0039100647,-0.008293152,0.0049362183,-0.026031494,-0.0027580261,-0.07513428,-0.051116943,-0.026763916,-0.0104522705,-0.11810303,-0.021057129,0.04272461,0.10571289,-0.008979797,0.0209198,0.0748291,-0.009735107,0.01133728,-0.047912598,-0.052825928,0.022247314,-0.043304443,-0.0357666,-0.026672363,-0.037261963,-0.04522705,-0.125,0.05508423,0.02142334,-0.0035800934,0.033050537,-0.025878906,0.079711914,-0.015640259,-0.008049011,-0.06359863,-0.009727478,-0.07873535,-0.005443573,-0.011245728,-0.049804688,0.0005683899,0.01739502,0.06311035,0.021057129,0.020202637,-0.052490234,-0.022277832,0.03869629,0.049682617,0.011077881,-0.09802246,-0.03366089,-0.057739258,-0.02243042,0.012130737,-0.04171753,-0.0031795502,-0.06124878,0.023040771,-0.025024414,0.038238525,-0.015235901,0.013214111,0.11791992,-0.074157715,-0.00032138824,0.0096206665,0.046203613,0.0051994324,-0.013908386,0.047088623,-0.07318115,0.066345215,0.016143799,-0.033966064,-0.0052337646,-0.022735596,0.14147949,-0.018814087,-0.013504028,0.024902344,-0.0068855286,-0.029968262,-0.08685303,-0.08728027,0.0048599243,-0.04537964,0.07208252,-0.043823242,-0.01461792,0.018325806,-0.029037476,-0.10369873,0.004928589,0.0635376,0.061431885,0.001868248,0.04925537,0.022583008,0.08691406,-0.12536621,0.10986328,0.06890869,0.053833008,0.1418457,-0.029159546,0.011741638,-0.003332138,0.0131073,-0.0098724365,0.029006958,-0.07086182,-0.079589844,-0.057159424,0.09313965,-0.03930664,0.0395813,0.051940918,0.043273926,-0.10070801,0.008346558,0.0084991455,-0.07647705,0.00970459,-0.10217285,-0.017990112,0.022079468,-0.06756592,0.0025634766,-0.010353088,0.023956299,0.046203613,0.05618286,-0.067993164,0.01776123,-0.056427002,-0.031143188,0.00223732,-0.07293701,0.0012731552,-0.03050232,-0.100097656,-0.023529053,-0.026397705,-0.039367676,0.033081055,0.0340271,-0.047790527,0.03970337,0.020477295,-0.0016918182,0.054382324,-0.048217773,0.09008789,0.054016113,0.05206299,0.017654419,0.008979797,-0.013267517,0.06124878,0.03866577,-0.012138367,-0.043151855,0.010681152,0.052978516,-0.012451172,0.009094238,0.059814453,0.003967285,-0.004497528,0.011047363,-0.05819702,-0.04937744,0.051116943,-0.0209198,0.020355225,-0.04486084,0.056610107,-0.009933472,-0.0040245056,-0.040374756,0.009857178,-0.043304443,0.05419922,-0.043182373,0.06512451,-0.03543091,0.025131226,0.05026245,-0.053833008,0.03479004,-0.051116943,-0.019714355,-0.0025177002,0.07897949,-0.016677856,0.091796875,0.060028076,0.022583008,0.018447876,0.04864502,0.06512451,0.043762207,-0.06628418,0.02330017,-0.04574585,0.006755829,-0.063964844,-0.04748535,0.059417725,0.013061523,-0.020233154,0.016174316,-0.017227173,-0.083496094,-0.09301758,-0.06677246,0.009025574,0.03463745,-0.056854248,0.0035800934,0.011131287,-0.05038452,-0.04937744,-0.0075531006,0.018676758,0.109680176,0.13598633,0.060546875,-0.016799927,0.03857422,0.00573349,-0.056762695,-0.01965332,-0.07293701,-0.048919678,-0.04953003,0.03274536,-0.039245605,0.02645874,-0.06890869,0.035186768,0.00932312,0.006378174,-0.0062675476,0.07434082,-0.06323242,0.049072266,-0.052703857,-0.07659912,0.1295166,-0.0015335083,0.057739258,-0.00073337555,0.034820557,-0.046081543,-0.07696533,0.08215332,-0.05496216,-0.0072021484,0.044158936,-0.024627686,-0.029373169,0.027145386,-0.056488037,0.08190918,0.01889038,-0.049041748,-0.025009155,-0.02722168,-0.099975586,-0.029312134,0.0071258545,-0.030166626,0.027511597,0.000726223,0.01171875,0.066589355,0.12060547,0.0056114197,-0.040100098,-0.07513428,-0.092041016,-0.013175964,0.05734253,-0.036895752,-0.16882324,-0.004055023,0.060302734,0.009147644,0.0541687,-0.009407043,0.00356102,-0.021896362,0.059295654,0.014976501,-0.022521973,0.0026760101,-0.029922485,0.103637695,-0.020996094,0.04547119,0.00522995,0.013801575,-0.05770874,-0.056243896,-0.0025177002,-0.031585693,-0.010528564,0.0048713684,-0.020568848,0.015144348,0.072387695,0.053894043,-0.023666382,0.09265137,0.060302734,-0.037078857,0.0103302,0.095703125,-0.006515503,0.08087158,-0.02722168,-0.016525269,-0.00030183792,0.019454956,-0.070373535,0.007095337,-0.037017822,0.056549072,0.009063721,-0.007221222,-0.09069824,0.0058670044,0.08300781,-0.02154541,0.11328125,0.017944336,0.044067383,-0.014709473,0.045288086,0.08001709,0.008842468,0.024627686,0.048461914,-0.05255127,0.06970215,0.013076782,-0.010353088,-0.038085938,-0.05886841,-0.002796173,-0.0060691833,0.027328491,-0.031188965,-0.062805176,-0.06695557,0.09466553,-0.024383545,0.008201599,0.021728516,-0.0033035278,0.052368164,0.03466797,-0.023788452,0.08288574,0.07293701,-0.04611206,-0.011650085,-0.009521484,0.01838684,-0.12011719,0.11987305,-0.007411957],[-0.013893127,-0.002084732,0.037261963,-0.08105469,-0.034240723,-0.08312988,0.025115967,0.06695557,-0.03173828,0.040649414,0.0043296814,-0.023513794,0.076293945,-0.06854248,-0.060058594,-0.03942871,0.016357422,-0.04486084,-0.004180908,-0.01852417,0.0113220215,0.16430664,0.018630981,-0.012702942,0.12176514,-0.04437256,0.010147095,-0.033050537,0.012901306,-0.0018806458,0.014823914,-0.049926758,0.030334473,-0.026351929,0.033203125,-0.055358887,0.02268982,0.031097412,0.048980713,-0.006916046,-0.06488037,0.03604126,0.06201172,-0.08660889,-0.027572632,0.05206299,-0.072387695,0.005821228,-0.000016391277,-0.048828125,0.07635498,-0.035888672,0.030212402,0.05822754,0.08496094,-0.017715454,-0.05026245,-0.0118637085,0.019989014,-0.040649414,-0.04046631,-0.021240234,-0.023468018,-0.00036263466,0.107177734,0.06488037,-0.018203735,-0.0042915344,-0.030136108,-0.10467529,0.019592285,-0.0234375,0.013946533,0.02947998,-0.045410156,-0.022949219,-0.013221741,0.04220581,0.013641357,0.008865356,-0.0024337769,-0.025115967,-0.022064209,-0.0069999695,0.06304932,-0.0075531006,-0.082092285,0.082214355,0.029647827,0.020080566,0.0068473816,-0.020263672,0.018127441,-0.09661865,-0.037109375,0.023406982,0.010398865,0.08496094,0.032348633,0.000054836273,-0.035949707,0.03729248,-0.02557373,-0.0021400452,-0.079833984,-0.0018882751,-0.037017822,0.077941895,0.0053977966,0.0095825195,-0.10205078,-0.017364502,0.03781128,0.04675293,0.091796875,-0.1385498,0.066467285,-0.020751953,-0.053833008,0.026031494,-0.027938843,-0.09790039,-0.043060303,0.030227661,0.074645996,-0.042114258,0.052764893,-0.0062675476,0.014060974,0.0019102097,-0.02003479,0.036499023,-0.06933594,-0.03994751,-0.042510986,0.013015747,-0.021499634,-0.04751587,-0.045135498,0.020584106,0.028366089,0.10784912,0.059570312,-0.021331787,0.014564514,-0.024993896,0.11279297,-0.0657959,-0.026977539,0.059753418,-0.056518555,0.026611328,-0.034332275,-0.056396484,-0.019882202,-0.04006958,0.047027588,-0.0826416,-0.029586792,-0.04208374,0.07873535,-0.0045661926,0.0005311966,0.027572632,0.11395264,0.053466797,-0.08312988,-0.05340576,-0.013885498,0.017684937,-0.0053138733,-0.06149292,0.026809692,0.053863525,0.056243896,-0.034301758,-0.009902954,0.030227661,0.0256958,0.066833496,-0.008468628,-0.04333496,0.0056991577,0.020111084,-0.028366089,0.009506226,0.035095215,-0.020904541,-0.028900146,-0.06915283,0.016967773,-0.054534912,-0.03567505,0.058135986,-0.0435791,-0.015670776,0.03970337,0.057434082,0.049682617,-0.051330566,0.06488037,0.013900757,-0.030593872,0.06781006,0.12182617,0.024932861,0.02078247,0.14355469,0.06591797,0.0069351196,0.008773804,0.027557373,0.05633545,-0.10858154,-0.061920166,-0.053497314,-0.007835388,-0.019042969,0.015670776,0.0065994263,0.026275635,-0.03945923,-0.015182495,0.059417725,-0.096069336,-0.04989624,-0.06225586,-0.012916565,0.026153564,-0.008003235,0.14807129,0.015129089,-0.044555664,-0.041625977,-0.046325684,0.039611816,0.09887695,0.039611816,-0.08312988,-0.011375427,0.09454346,-0.0016365051,-0.07312012,-0.021469116,-0.028671265,-0.07897949,-0.124938965,-0.07318115,-0.06072998,-0.019561768,-0.09753418,0.003967285,0.037872314,0.0007991791,0.03479004,-0.023010254,-0.032470703,0.05606079,0.013221741,-0.048950195,0.042999268,-0.06542969,-0.07495117,-0.0552063,0.08892822,0.035888672,-0.06384277,0.08831787,-0.039001465,0.11834717,-0.02142334,-0.08483887,-0.09613037,0.03555298,-0.037628174,0.014678955,0.010017395,-0.038208008,-0.027572632,0.00856781,-0.06616211,-0.009941101,0.06335449,0.009796143,-0.06378174,-0.020233154,0.043395996,0.05706787,0.02230835,-0.014968872,-0.014030457,-0.109436035,-0.013519287,-0.0077552795,0.101135254,0.027709961,-0.11627197,0.020843506,0.06713867,0.022567749,0.059631348,0.031921387,0.02861023,0.0044021606,0.03567505,0.07446289,0.007621765,0.0054855347,-0.00060367584,0.034118652,0.014129639,-0.030197144,-0.0018558502,0.071777344,0.06100464,-0.054840088,-0.035949707,-0.020706177,0.070617676,-0.035217285,-0.0005097389,0.0013685226,0.017211914,0.07354736,0.0058670044,-0.050567627,0.010406494,-0.05316162,-0.021392822,0.1104126,0.017715454,0.02015686,0.017715454,-0.04611206,-0.03451538,-0.020584106,-0.014701843,0.0065994263,-0.044555664,-0.0680542,0.02571106,-0.06939697,-0.075927734,0.06982422,-0.026382446,0.020263672,0.12512207,0.058807373,-0.014953613,-0.10321045,0.02897644,0.027740479,-0.0033302307,-0.010604858,0.077941895,0.022720337,0.022537231,0.027252197,0.015716553,0.02279663,-0.026641846,0.043548584,0.029266357,0.041625977,-0.01802063,0.0024337769,0.0112838745,0.03665161,0.026550293,0.024658203,-0.013092041,0.004169464,0.044952393,0.06591797,-0.056488037,0.07647705,-0.051086426,-0.03955078,-0.09399414,0.016036987,-0.04309082,-0.05795288,-0.024536133,0.06549072]]},"meta":{"api_version":{"version":"2"},"billed_units":{"input_tokens":208}},"response_type":"embeddings_by_type"}' + headers: + Alt-Svc: + - h3=":443"; ma=2592000,h3-29=":443"; ma=2592000 + Transfer-Encoding: + - chunked + Via: + - 1.1 google + access-control-expose-headers: + - X-Debug-Trace-ID + cache-control: + - no-cache, no-store, no-transform, must-revalidate, private, max-age=0 + content-type: + - application/json + date: + - Sun, 14 Sep 2025 03:17:07 GMT + expires: + - Thu, 01 Jan 1970 00:00:00 GMT + num_chars: + - '967' + num_tokens: + - '208' + pragma: + - no-cache + server: + - envoy + vary: + - Origin + x-accel-expires: + - '0' + x-debug-trace-id: + - 5bf14e94670880a3e6e9ac76e2a6cba8 + x-envoy-upstream-service-time: + - '45' + status: + code: 200 + message: OK +version: 1 diff --git a/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_embed/test_cohere_v2_embed_legacy_async.yaml b/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_embed/test_cohere_v2_embed_legacy_async.yaml new file mode 100644 index 0000000000..d7215f0619 --- /dev/null +++ b/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_embed/test_cohere_v2_embed_legacy_async.yaml @@ -0,0 +1,92 @@ +interactions: +- request: + body: '{"texts": ["Carson City is the capital city of the American state of Nevada. + At the 2010 United States Census, Carson City had a population of 55,274.", + "The Commonwealth of the Northern Mariana Islands is a group of islands in the + Pacific Ocean that are a political division controlled by the United States. + Its capital is Saipan.", "Charlotte Amalie is the capital and largest city of + the United States Virgin Islands. It has about 20,000 people. The city is on + the island of Saint Thomas.", "Washington, D.C. (also known as simply Washington + or D.C., and officially as the District of Columbia) is the capital of the United + States. It is a federal district. ", "Capital punishment (the death penalty) + has existed in the United States since before the United States was a country. + As of 2017, capital punishment is legal in 30 of the 50 states.", "North Dakota + is a state in the United States. 672,591 people lived in North Dakota in the + year 2010. The capital and seat of government is Bismarck."], "model": "embed-english-light-v3.0", + "input_type": "search_document"}' + headers: + accept: + - '*/*' + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '1072' + content-type: + - application/json + host: + - api.cohere.com + user-agent: + - cohere/5.18.0 + x-fern-language: + - Python + x-fern-sdk-name: + - cohere + x-fern-sdk-version: + - 5.18.0 + method: POST + uri: https://api.cohere.com/v2/embed + response: + body: + string: '{"id":"3bc87f83-0534-4478-af7d-fee196c92758","texts":["carson city + is the capital city of the american state of nevada. at the 2010 united states + census, carson city had a population of 55, 274.","the commonwealth of the + northern mariana islands is a group of islands in the pacific ocean that are + a political division controlled by the united states. its capital is saipan.","charlotte + amalie is the capital and largest city of the united states virgin islands. + it has about 20, 000 people. the city is on the island of saint thomas.","washington, + d. c. ( also known as simply washington or d. c., and officially as the district + of columbia ) is the capital of the united states. it is a federal district.","capital + punishment ( the death penalty ) has existed in the united states since before + the united states was a country. as of 2017, capital punishment is legal in + 30 of the 50 states.","north dakota is a state in the united states. 672, + 591 people lived in north dakota in the year 2010. the capital and seat of + government is bismarck."],"embeddings":{"float":[[0.032318115,-0.031188965,-0.06604004,0.028823853,-0.017730713,-0.07757568,0.02305603,0.008758545,-0.004558563,0.0725708,-0.112976074,-0.05142212,0.08526611,-0.11383057,-0.052337646,-0.010803223,0.02848816,-0.08453369,0.06365967,-0.0647583,-0.066467285,0.10449219,0.037841797,-0.01134491,-0.020523071,-0.15917969,-0.07720947,-0.015106201,-0.032836914,0.092041016,-0.018463135,-0.034179688,0.06137085,0.05404663,0.090270996,-0.061828613,0.058654785,-0.013000488,-0.046081543,0.0552063,0.022109985,0.12646484,0.0031318665,-0.083984375,-0.050231934,0.049804688,-0.059020996,-0.005924225,0.018157959,0.0066566467,0.07446289,0.015808105,0.014984131,0.050750732,-0.046936035,0.05807495,0.014465332,-0.038238525,-0.03869629,-0.017227173,-0.07739258,-0.015258789,-0.03845215,-0.056762695,0.006286621,0.061553955,0.035858154,-0.11004639,-0.011672974,-0.03036499,0.06286621,-0.1060791,-0.059020996,0.006324768,0.01586914,0.0066566467,-0.054748535,0.077819824,0.057861328,0.0647583,0.0703125,-0.039733887,-0.002840042,-0.05999756,-0.01676941,0.0871582,0.010658264,-0.0004172325,0.035980225,-0.033081055,0.03692627,0.007045746,-0.009506226,-0.06738281,-0.04168701,0.029342651,0.029571533,0.021896362,0.0037384033,-0.03656006,0.010749817,0.022064209,-0.028366089,-0.032226562,-0.076660156,-0.017486572,-0.013084412,0.09246826,-0.057495117,0.020462036,-0.054656982,0.040130615,0.0236969,-0.016052246,-0.0001552105,-0.019485474,0.0647583,-0.03112793,-0.055541992,-0.0025463104,0.008453369,-0.078308105,0.0211792,0.022064209,0.07940674,-0.016464233,-0.00052022934,-0.03543091,-0.00015723705,-0.0035209656,0.02571106,0.052093506,-0.016708374,0.00015437603,-0.02027893,-0.012313843,0.009552002,-0.08026123,-0.002363205,0.007045746,0.099731445,0.10467529,-0.009651184,-0.0029239655,-0.025146484,0.024047852,0.049987793,0.001156807,-0.03353882,0.06359863,0.04699707,0.068603516,-0.0064888,-0.03265381,-0.11920166,-0.024337769,0.076660156,-0.02432251,0.018936157,0.06915283,0.081726074,0.04827881,0.05166626,0.058532715,-0.024627686,0.12609863,-0.056396484,-0.0836792,-0.041503906,0.099853516,0.04751587,-0.053100586,-0.10449219,0.004146576,0.07098389,-0.019332886,-0.011924744,0.015197754,0.0034313202,0.10321045,-0.031341553,0.06750488,-0.015274048,0.01651001,-0.043792725,-0.05328369,-0.012451172,0.0074691772,0.015182495,-0.1126709,-0.0066566467,-0.044708252,0.0078125,-0.048095703,-0.042144775,0.04611206,0.02571106,0.039764404,0.13635254,-0.056488037,0.049194336,-0.000101327896,0.0090789795,0.011520386,0.05960083,0.0058059692,0.05392456,0.07324219,-0.031280518,0.021255493,0.028701782,0.015602112,0.08117676,-0.0814209,0.031677246,0.011810303,0.04449463,-0.0023326874,-0.055725098,0.020965576,0.02708435,-0.017166138,-0.02859497,0.050933838,-0.14575195,0.0072898865,0.011299133,-0.087524414,0.04525757,-0.05581665,0.08959961,0.017547607,-0.03250122,-0.013885498,0.016662598,0.058441162,0.0418396,-0.04449463,-0.04171753,0.0067481995,0.059692383,0.07330322,-0.05407715,0.052642822,-0.09564209,-0.06951904,-0.09051514,-0.06842041,0.041992188,-0.023101807,-0.12731934,-0.068603516,0.008605957,-0.024154663,-0.05618286,-0.0007596016,0.048858643,0.080322266,0.034332275,0.029922485,0.021591187,-0.060546875,0.0067863464,-0.032836914,0.0052452087,-0.0057868958,-0.066589355,0.03062439,-0.025802612,0.053100586,-0.04852295,-0.027313232,-0.082336426,0.059265137,0.010284424,0.006843567,-0.03491211,-0.007019043,0.03225708,0.043884277,0.0059394836,0.0015859604,0.055908203,-0.011398315,-0.027038574,-0.023956299,-0.023971558,0.030197144,-0.064697266,-0.035980225,-0.06097412,-0.08117676,-0.0066375732,0.02935791,0.014526367,-0.032836914,-0.023468018,0.02998352,-0.045776367,0.023529053,0.054870605,0.11138916,0.0970459,0.024261475,0.024993896,-0.042785645,0.05102539,0.042419434,-0.015396118,0.034576416,-0.013397217,-0.025054932,0.12060547,0.06756592,0.005558014,0.022003174,-0.037384033,-0.081970215,0.020751953,-0.00844574,0.096191406,-0.025253296,-0.029266357,0.06347656,0.026382446,0.041625977,0.033996582,0.0042800903,-0.06161499,0.05419922,-0.028427124,-0.0025024414,0.0035476685,0.01637268,-0.072509766,-0.039154053,0.0146102905,0.080444336,0.043914795,-0.055480957,-0.010917664,-0.08526611,-0.09661865,-0.011268616,-0.018676758,0.05532837,0.05255127,-0.005821228,-0.036895752,-0.026931763,0.05645752,-0.0440979,0.048095703,-0.07019043,0.053466797,-0.0007586479,-0.04925537,0.02911377,0.010520935,-0.04714966,0.021331787,-0.017669678,-0.02519226,-0.011955261,-0.0067100525,-0.072021484,-0.06890869,-0.021774292,-0.026809692,0.0053100586,0.030426025,0.07354736,0.059417725,0.03579712,0.0031528473,0.0541687,-0.049926758,-0.015083313,0.03427124,0.023666382,0.0014266968,0.048431396,-0.02142334,-0.046936035],[0.034454346,-0.03652954,0.121520996,-0.08618164,0.015960693,-0.0647583,0.07354736,0.061431885,0.020614624,0.0012788773,0.01612854,-0.06121826,-0.031555176,-0.012077332,0.011062622,0.028533936,-0.041137695,-0.0619812,-0.005203247,0.009513855,0.059814453,0.10748291,-0.10455322,-0.0046157837,0.07940674,-0.037994385,0.027359009,-0.013954163,0.03793335,-0.0154418945,-0.0038108826,-0.04257202,0.001666069,-0.023635864,0.04272461,0.0022354126,0.01902771,-0.033691406,0.04284668,-0.09857178,-0.047088623,0.046966553,0.04144287,0.056274414,0.0030555725,0.024154663,-0.089782715,-0.0038490295,-0.064941406,0.065979004,0.07495117,-0.07989502,-0.044799805,0.037628174,0.014404297,0.050598145,-0.0028591156,0.039276123,0.07159424,-0.005203247,0.03491211,0.04373169,-0.036956787,0.0014915466,0.016952515,0.032470703,0.047821045,0.048461914,-0.0126571655,-0.120666504,-0.053863525,0.0046463013,0.001964569,-0.0049324036,-0.008514404,0.013000488,0.02154541,-0.0019817352,0.0018005371,0.0032482147,0.06921387,0.0725708,0.010566711,-0.038726807,0.06774902,-0.029159546,-0.022445679,0.048980713,0.035858154,0.017593384,-0.023590088,0.029800415,0.11895752,-0.044555664,-0.030014038,0.10961914,-0.06185913,0.025619507,0.078552246,0.00066518784,0.018478394,0.09680176,0.029006958,-0.10253906,-0.09057617,0.10040283,0.02909851,0.019546509,0.09918213,0.038360596,-0.03149414,0.020339966,0.008979797,-0.05429077,0.015419006,-0.10192871,0.036010742,-0.032226562,-0.057800293,0.011566162,0.047302246,-0.10986328,0.032104492,-0.05227661,0.072509766,-0.025558472,-0.060333252,-0.0859375,0.058044434,-0.07659912,0.017227173,0.03225708,0.029953003,0.0049057007,0.066833496,-0.03881836,-0.093322754,-0.121398926,-0.049560547,0.04348755,0.081848145,0.017074585,0.06604004,0.012817383,0.076293945,0.017150879,0.05645752,-0.019622803,-0.011665344,0.059692383,-0.036132812,0.030273438,-0.026519775,-0.01612854,-0.0715332,-0.06964111,-0.00009262562,-0.04336548,-0.0076560974,-0.025924683,0.03741455,-0.017227173,-0.07318115,0.031280518,0.03692627,0.04373169,-0.00016987324,0.039978027,-0.06707764,0.056884766,0.01789856,0.020141602,0.040100098,0.00365448,-0.031982422,-0.06933594,0.014656067,0.08898926,-0.035949707,-0.0044441223,-0.070739746,-0.02696228,0.03866577,-0.055114746,-0.06756592,0.047912598,-0.04788208,0.009780884,0.05569458,-0.019882202,0.0050239563,0.00630188,-0.024841309,0.0670166,-0.06097412,-0.08166504,0.03845215,0.050842285,0.06524658,0.056243896,0.03942871,0.07824707,-0.039794922,0.028961182,0.01651001,0.022445679,-0.018295288,0.01234436,-0.012367249,-0.010047913,-0.05227661,-0.003730774,0.0065078735,-0.075805664,0.045715332,0.0054779053,-0.013648987,-0.012496948,-0.05001831,0.032409668,0.06311035,-0.06149292,0.01586914,0.042510986,-0.078063965,-0.090270996,-0.05392456,-0.080200195,-0.030578613,0.02947998,0.060333252,0.031921387,-0.051239014,-0.018066406,-0.075927734,-0.044281006,0.08831787,-0.020645142,-0.04043579,0.011634827,0.13012695,0.049804688,0.000052154064,0.02406311,-0.008621216,-0.052001953,0.016433716,-0.05758667,-0.010757446,-0.09307861,-0.038269043,-0.06121826,-0.0007548332,-0.026184082,-0.03793335,0.008018494,0.049468994,-0.074035645,-0.075683594,-0.11462402,-0.0032215118,-0.10650635,0.018737793,-0.010734558,0.052825928,-0.0647583,-0.011070251,0.11224365,-0.064331055,0.019821167,0.012611389,-0.013900757,-0.0869751,-0.024307251,-0.0055770874,-0.04748535,0.048431396,-0.009002686,0.06866455,0.01777649,-0.07507324,0.0012559891,0.053955078,0.01499176,-0.048217773,-0.076293945,-0.015792847,-0.0036640167,0.043518066,0.032806396,0.016662598,-0.0042800903,0.066589355,-0.03555298,0.08325195,-0.019073486,-0.0049057007,0.037994385,0.015975952,0.04800415,0.04434204,0.021896362,0.049346924,-0.029891968,0.041992188,-0.027038574,-0.03314209,-0.011871338,-0.0473938,0.039978027,0.013793945,-0.032684326,-0.10632324,-0.015365601,0.08276367,-0.13671875,0.017105103,-0.02003479,0.011482239,-0.021026611,0.026184082,-0.05117798,0.03289795,0.0026416779,0.005493164,0.0087509155,-0.06365967,-0.05126953,0.14074707,0.078552246,0.044189453,0.054351807,0.021331787,-0.04321289,0.05429077,0.012863159,-0.04675293,0.0647583,0.03717041,-0.015625,-0.007347107,-0.014808655,-0.019546509,0.08428955,-0.0018234253,0.0039978027,0.05596924,-0.05166626,0.0657959,0.010360718,-0.021240234,-0.013412476,-0.068481445,-0.0071907043,-0.035247803,0.1352539,0.00015163422,0.005306244,-0.004173279,-0.07537842,0.001042366,0.0970459,0.017227173,0.010757446,-0.0871582,-0.016784668,0.022140503,0.08355713,0.0060768127,0.020050049,-0.047088623,-0.04949951,-0.029464722,-0.060180664,-0.0748291,0.015022278,-0.113586426,0.02998352,-0.031280518,0.08190918,0.021072388,0.019744873,-0.046020508,-0.025680542],[-0.015945435,-0.07232666,0.059020996,-0.00674057,-0.022827148,-0.076049805,-0.0012760162,0.0026111603,-0.06463623,0.018249512,0.015525818,-0.0031166077,-0.05810547,-0.08911133,-0.047058105,0.06060791,0.010871887,-0.04232788,0.04763794,-0.027435303,0.036865234,-0.0010910034,-0.011474609,-0.082336426,0.03857422,-0.105895996,-0.04067993,-0.0033340454,-0.004055023,0.011619568,0.025878906,-0.09338379,0.03466797,0.101257324,-0.00484848,-0.030944824,0.08190918,0.030944824,0.09967041,-0.010047913,0.031158447,0.1307373,-0.030303955,0.054534912,-0.025772095,0.0362854,-0.093688965,0.0463562,-0.008277893,0.032196045,0.10046387,-0.047851562,-0.043914795,0.035064697,-0.0016546249,-0.079956055,-0.04046631,-0.059692383,-0.01184082,-0.052947998,0.05810547,-0.04827881,-0.013977051,0.0031147003,-0.007843018,0.008590698,0.021560669,0.045898438,0.010368347,-0.04776001,0.04031372,-0.047851562,-0.014808655,0.039276123,0.029846191,-0.015129089,-0.1194458,0.04776001,0.058624268,0.06890869,0.062408447,-0.024398804,0.027053833,-0.014198303,-0.015533447,0.004470825,-0.012992859,0.15161133,0.02558899,0.036010742,-0.04058838,-0.0042495728,-0.04788208,-0.053741455,-0.034454346,0.03302002,0.00013899803,0.02468872,-0.009315491,-0.01411438,0.009315491,0.09118652,0.043823242,0.008178711,-0.0063934326,0.1005249,0.055419922,-0.023025513,0.1673584,-0.025909424,-0.10070801,0.028579712,-0.02394104,-0.019042969,-0.037139893,-0.04446411,0.11053467,-0.046875,-0.125,-0.050964355,-0.044769287,-0.037628174,0.025314331,-0.01828003,-0.027877808,-0.024932861,0.02482605,-0.0149002075,-0.04626465,-0.028518677,0.0023345947,0.14550781,0.012290955,-0.005760193,-0.02168274,-0.0063972473,-0.0050964355,-0.17602539,-0.0635376,-0.011413574,0.06384277,0.057617188,0.06524658,-0.031707764,0.072509766,0.0049819946,-0.034301758,0.010658264,-0.0045547485,-0.012321472,-0.030151367,-0.003025055,-0.057403564,-0.0049858093,-0.0050239563,0.0096206665,0.07055664,-0.05923462,0.091308594,0.06109619,0.09655762,0.045288086,0.0072631836,0.024597168,0.012573242,-0.0038795471,-0.09234619,-0.005214691,-0.099365234,-0.051757812,0.016113281,-0.025222778,-0.01058197,0.02909851,0.004776001,-0.012046814,0.0592041,0.09832764,0.007411957,0.028213501,-0.07458496,0.06915283,-0.0044441223,0.08026123,0.031036377,-0.0017576218,0.008041382,-0.0037059784,-0.029693604,-0.11248779,0.057403564,-0.039398193,-0.021865845,0.013717651,-0.032714844,-0.00072050095,-0.015960693,0.070007324,0.041137695,-0.027008057,0.045410156,0.018798828,-0.011192322,0.058013916,0.0395813,-0.057037354,0.008903503,0.049926758,-0.05505371,-0.0058555603,-0.030090332,0.02835083,0.085754395,-0.09814453,-0.034210205,0.029205322,0.006828308,-0.035980225,0.030914307,-0.017730713,0.0637207,0.061309814,-0.06933594,-0.011940002,-0.085632324,-0.042907715,0.01927185,-0.069885254,0.026123047,0.03543091,0.07513428,0.024673462,-0.051483154,-0.057006836,-0.036621094,-0.0019521713,-0.04159546,-0.047058105,-0.03201294,-0.015533447,0.033172607,0.0063934326,0.0056266785,0.0061569214,-0.015838623,-0.035980225,0.0023937225,-0.052246094,0.0413208,-0.03387451,-0.0053901672,-0.055633545,-0.05267334,-0.0074386597,-0.05645752,-0.026367188,0.029922485,-0.001376152,-0.016860962,0.04257202,0.12609863,0.04421997,0.025680542,-0.05630493,0.02293396,0.026916504,-0.09680176,0.059143066,0.10864258,-0.011512756,0.029205322,-0.08605957,-0.08300781,0.027511597,-0.040283203,0.018295288,0.02822876,-0.009185791,0.020858765,0.034454346,-0.09637451,-0.029769897,0.044555664,-0.008552551,-0.043395996,-0.056793213,-0.086242676,0.05206299,-0.0016241074,0.0368042,0.025344849,0.00289917,-0.015350342,0.10571289,0.036590576,0.04510498,-0.07330322,0.026657104,-0.053863525,0.09020996,0.046447754,-0.0033073425,-0.02822876,-0.028503418,-0.0039100647,0.027770996,-0.103271484,0.0074882507,-0.043670654,0.03338623,0.062561035,-0.021209717,-0.022399902,0.058898926,-0.026611328,-0.15673828,-0.008369446,-0.07055664,0.033355713,-0.010986328,0.0158844,-0.04147339,-0.045410156,0.042663574,0.035247803,-0.03366089,0.012123108,-0.02999878,0.02168274,0.09649658,-0.064941406,0.011291504,0.002790451,-0.11151123,-0.012588501,-0.009407043,-0.0012493134,0.034118652,0.07318115,-0.0028057098,-0.004142761,-0.042510986,-0.03086853,-0.0309906,-0.008293152,-0.01158905,-0.0041542053,-0.04269409,-0.056610107,0.018310547,0.12670898,-0.015960693,0.061828613,-0.042907715,-0.042816162,0.012069702,-0.049041748,0.02168274,0.09411621,0.052642822,-0.044799805,0.002380371,-0.026168823,0.014884949,0.036621094,0.017715454,0.029510498,0.001452446,0.05593872,-0.013168335,0.016830444,0.033203125,0.03753662,0.09295654,0.001619339,-0.06555176,-0.06970215,0.07635498,0.10284424,0.06286621,0.03866577,-0.014808655,-0.030700684,0.011665344],[0.023895264,0.068847656,0.006034851,0.028060913,-0.05328369,-0.009185791,0.060424805,0.041656494,0.0046844482,0.053833008,-0.03933716,-0.10253906,0.035247803,-0.029067993,-0.046081543,-0.0692749,0.050323486,-0.014419556,-0.13452148,0.10430908,0.02848816,0.099121094,-0.030380249,-0.021591187,0.017044067,-0.05532837,0.020233154,0.03793335,-0.046081543,0.006538391,-0.017456055,-0.04333496,-0.0042381287,0.05114746,0.050872803,-0.06048584,-0.010108948,0.08874512,0.077819824,0.03842163,-0.03805542,0.012298584,-0.02230835,-0.049926758,-0.0637207,0.059783936,-0.061340332,-0.0005903244,-0.027633667,-0.0051002502,0.07897949,0.0128479,0.026153564,0.06109619,-0.010406494,0.07324219,-0.016204834,0.038238525,0.039093018,0.068603516,-0.04385376,0.013381958,-0.097717285,0.07714844,0.08972168,0.007522583,0.009849548,-0.008621216,-0.044281006,-0.08929443,0.020462036,0.02432251,-0.028198242,0.048309326,0.06036377,0.041656494,-0.03781128,-0.003484726,0.009277344,0.033325195,0.045837402,-0.013435364,-0.08917236,-0.018630981,-0.0053977966,-0.05496216,0.026687622,0.046325684,-0.0102005005,-0.083862305,-0.039916992,0.015853882,0.030349731,-0.053375244,-0.13916016,-0.07104492,0.011192322,0.02861023,-0.009750366,-0.0070228577,-0.020553589,0.026885986,-0.087768555,-0.03845215,-0.0037899017,0.011253357,0.039093018,0.050231934,0.06524658,-0.044769287,-0.12695312,0.064941406,0.082214355,-0.022003174,0.06335449,-0.060791016,-0.015823364,-0.08758545,-0.04940796,-0.054901123,0.011428833,-0.0602417,-0.0010309219,-0.05630493,0.025421143,-0.11773682,0.04623413,0.02230835,0.06970215,-0.010093689,0.07043457,-0.00032758713,0.032684326,0.027252197,-0.076049805,-0.009773254,-0.05834961,-0.03491211,0.046905518,0.072021484,0.047821045,0.046905518,0.013969421,-0.06402588,0.0259552,-0.0051193237,-0.068603516,0.045013428,-0.022644043,0.053619385,-0.024673462,-0.0970459,0.07287598,-0.00092840195,-0.047454834,0.0023727417,0.047424316,-0.038909912,0.05053711,-0.07910156,0.047973633,0.020111084,-0.018310547,0.056549072,0.043823242,0.028427124,0.033355713,-0.020828247,-0.022369385,-0.0044670105,-0.034484863,0.05606079,0.06689453,0.016448975,-0.0025863647,-0.033081055,0.027145386,0.017715454,0.06439209,0.023742676,0.02067566,0.0075531006,-0.032470703,0.00894928,0.032470703,-0.037963867,-0.05239868,-0.033355713,0.019210815,0.0075683594,-0.07324219,0.04699707,-0.062469482,-0.02432251,-0.022064209,0.06524658,0.031021118,0.028060913,0.06524658,-0.075683594,0.109558105,0.09075928,-0.06945801,0.057434082,0.028717041,0.014465332,0.06768799,0.07672119,-0.038482666,0.01939392,0.0006918907,0.028793335,0.023345947,-0.07287598,-0.0006403923,-0.05596924,0.037231445,-0.029510498,-0.13354492,0.0029182434,-0.036071777,-0.016586304,-0.022155762,-0.00012993813,-0.07324219,-0.07312012,-0.039642334,0.000323534,-0.07421875,-0.020431519,0.040130615,-0.0118637085,-0.031799316,0.05255127,-0.030349731,0.059753418,-0.00793457,0.04788208,0.013397217,0.03881836,0.087768555,0.008453369,-0.08496094,-0.0030136108,-0.042663574,-0.059448242,-0.10845947,-0.08081055,0.015449524,-0.031158447,-0.03111267,0.045013428,0.028274536,0.032196045,0.0040016174,0.003479004,-0.041992188,0.051879883,-0.041137695,0.015670776,0.087402344,-0.049957275,-0.030670166,0.03387451,-0.0082473755,-0.039733887,-0.026977539,0.17346191,0.016845703,-0.037261963,0.0395813,-0.0579834,-0.06329346,0.0211792,-0.034851074,0.009643555,-0.0022029877,-0.0018224716,0.0496521,0.043151855,-0.10510254,-0.112854004,-0.01625061,-0.06915283,-0.038482666,-0.06604004,0.02708435,-0.01411438,0.000036120415,-0.07312012,-0.031951904,-0.10949707,-0.034301758,-0.009742737,0.14343262,-0.05218506,-0.05496216,0.00089263916,0.012397766,0.09448242,0.061920166,-0.0008125305,-0.04559326,0.0340271,0.04260254,0.04714966,0.029953003,-0.011390686,-0.042175293,0.07940674,0.014419556,0.061676025,-0.056762695,0.027328491,-0.0032367706,-0.0501709,0.00919342,-0.047454834,0.026992798,-0.01638794,0.023635864,0.037109375,0.022262573,0.037841797,-0.020233154,0.02178955,0.078125,-0.027862549,-0.029037476,0.13830566,0.04107666,0.06124878,-0.038116455,-0.06970215,0.07836914,0.091552734,0.025848389,-0.010284424,-0.068115234,0.066589355,-0.06549072,0.017349243,-0.04434204,-0.028152466,0.037017822,0.024597168,0.07019043,0.028945923,0.032226562,0.041503906,-0.0132369995,0.06903076,-0.016159058,-0.025756836,0.1116333,-0.03491211,0.12097168,-0.026412964,-0.018936157,-0.020721436,-0.0090408325,0.02407837,-0.049713135,0.044006348,-0.06951904,-0.070617676,0.048950195,0.005092621,-0.039886475,-0.078430176,-0.015083313,-0.00013649464,0.07702637,-0.015701294,-0.020248413,0.00020170212,-0.014472961,-0.025680542,-0.043548584,-0.033447266,-0.028747559,0.039093018,0.028823853,0.0046157837],[0.00020253658,-0.041259766,-0.050048828,0.021270752,-0.0020771027,-0.026123047,0.01802063,0.01550293,0.11578369,-0.0039100647,-0.008293152,0.0049362183,-0.026031494,-0.0027580261,-0.07513428,-0.051116943,-0.026763916,-0.0104522705,-0.11810303,-0.021057129,0.04272461,0.10571289,-0.008979797,0.0209198,0.0748291,-0.009735107,0.01133728,-0.047912598,-0.052825928,0.022247314,-0.043304443,-0.0357666,-0.026672363,-0.037261963,-0.04522705,-0.125,0.05508423,0.02142334,-0.0035800934,0.033050537,-0.025878906,0.079711914,-0.015640259,-0.008049011,-0.06359863,-0.009727478,-0.07873535,-0.005443573,-0.011245728,-0.049804688,0.0005683899,0.01739502,0.06311035,0.021057129,0.020202637,-0.052490234,-0.022277832,0.03869629,0.049682617,0.011077881,-0.09802246,-0.03366089,-0.057739258,-0.02243042,0.012130737,-0.04171753,-0.0031795502,-0.06124878,0.023040771,-0.025024414,0.038238525,-0.015235901,0.013214111,0.11791992,-0.074157715,-0.00032138824,0.0096206665,0.046203613,0.0051994324,-0.013908386,0.047088623,-0.07318115,0.066345215,0.016143799,-0.033966064,-0.0052337646,-0.022735596,0.14147949,-0.018814087,-0.013504028,0.024902344,-0.0068855286,-0.029968262,-0.08685303,-0.08728027,0.0048599243,-0.04537964,0.07208252,-0.043823242,-0.01461792,0.018325806,-0.029037476,-0.10369873,0.004928589,0.0635376,0.061431885,0.001868248,0.04925537,0.022583008,0.08691406,-0.12536621,0.10986328,0.06890869,0.053833008,0.1418457,-0.029159546,0.011741638,-0.003332138,0.0131073,-0.0098724365,0.029006958,-0.07086182,-0.079589844,-0.057159424,0.09313965,-0.03930664,0.0395813,0.051940918,0.043273926,-0.10070801,0.008346558,0.0084991455,-0.07647705,0.00970459,-0.10217285,-0.017990112,0.022079468,-0.06756592,0.0025634766,-0.010353088,0.023956299,0.046203613,0.05618286,-0.067993164,0.01776123,-0.056427002,-0.031143188,0.00223732,-0.07293701,0.0012731552,-0.03050232,-0.100097656,-0.023529053,-0.026397705,-0.039367676,0.033081055,0.0340271,-0.047790527,0.03970337,0.020477295,-0.0016918182,0.054382324,-0.048217773,0.09008789,0.054016113,0.05206299,0.017654419,0.008979797,-0.013267517,0.06124878,0.03866577,-0.012138367,-0.043151855,0.010681152,0.052978516,-0.012451172,0.009094238,0.059814453,0.003967285,-0.004497528,0.011047363,-0.05819702,-0.04937744,0.051116943,-0.0209198,0.020355225,-0.04486084,0.056610107,-0.009933472,-0.0040245056,-0.040374756,0.009857178,-0.043304443,0.05419922,-0.043182373,0.06512451,-0.03543091,0.025131226,0.05026245,-0.053833008,0.03479004,-0.051116943,-0.019714355,-0.0025177002,0.07897949,-0.016677856,0.091796875,0.060028076,0.022583008,0.018447876,0.04864502,0.06512451,0.043762207,-0.06628418,0.02330017,-0.04574585,0.006755829,-0.063964844,-0.04748535,0.059417725,0.013061523,-0.020233154,0.016174316,-0.017227173,-0.083496094,-0.09301758,-0.06677246,0.009025574,0.03463745,-0.056854248,0.0035800934,0.011131287,-0.05038452,-0.04937744,-0.0075531006,0.018676758,0.109680176,0.13598633,0.060546875,-0.016799927,0.03857422,0.00573349,-0.056762695,-0.01965332,-0.07293701,-0.048919678,-0.04953003,0.03274536,-0.039245605,0.02645874,-0.06890869,0.035186768,0.00932312,0.006378174,-0.0062675476,0.07434082,-0.06323242,0.049072266,-0.052703857,-0.07659912,0.1295166,-0.0015335083,0.057739258,-0.00073337555,0.034820557,-0.046081543,-0.07696533,0.08215332,-0.05496216,-0.0072021484,0.044158936,-0.024627686,-0.029373169,0.027145386,-0.056488037,0.08190918,0.01889038,-0.049041748,-0.025009155,-0.02722168,-0.099975586,-0.029312134,0.0071258545,-0.030166626,0.027511597,0.000726223,0.01171875,0.066589355,0.12060547,0.0056114197,-0.040100098,-0.07513428,-0.092041016,-0.013175964,0.05734253,-0.036895752,-0.16882324,-0.004055023,0.060302734,0.009147644,0.0541687,-0.009407043,0.00356102,-0.021896362,0.059295654,0.014976501,-0.022521973,0.0026760101,-0.029922485,0.103637695,-0.020996094,0.04547119,0.00522995,0.013801575,-0.05770874,-0.056243896,-0.0025177002,-0.031585693,-0.010528564,0.0048713684,-0.020568848,0.015144348,0.072387695,0.053894043,-0.023666382,0.09265137,0.060302734,-0.037078857,0.0103302,0.095703125,-0.006515503,0.08087158,-0.02722168,-0.016525269,-0.00030183792,0.019454956,-0.070373535,0.007095337,-0.037017822,0.056549072,0.009063721,-0.007221222,-0.09069824,0.0058670044,0.08300781,-0.02154541,0.11328125,0.017944336,0.044067383,-0.014709473,0.045288086,0.08001709,0.008842468,0.024627686,0.048461914,-0.05255127,0.06970215,0.013076782,-0.010353088,-0.038085938,-0.05886841,-0.002796173,-0.0060691833,0.027328491,-0.031188965,-0.062805176,-0.06695557,0.09466553,-0.024383545,0.008201599,0.021728516,-0.0033035278,0.052368164,0.03466797,-0.023788452,0.08288574,0.07293701,-0.04611206,-0.011650085,-0.009521484,0.01838684,-0.12011719,0.11987305,-0.007411957],[-0.013893127,-0.002084732,0.037261963,-0.08105469,-0.034240723,-0.08312988,0.025115967,0.06695557,-0.03173828,0.040649414,0.0043296814,-0.023513794,0.076293945,-0.06854248,-0.060058594,-0.03942871,0.016357422,-0.04486084,-0.004180908,-0.01852417,0.0113220215,0.16430664,0.018630981,-0.012702942,0.12176514,-0.04437256,0.010147095,-0.033050537,0.012901306,-0.0018806458,0.014823914,-0.049926758,0.030334473,-0.026351929,0.033203125,-0.055358887,0.02268982,0.031097412,0.048980713,-0.006916046,-0.06488037,0.03604126,0.06201172,-0.08660889,-0.027572632,0.05206299,-0.072387695,0.005821228,-0.000016391277,-0.048828125,0.07635498,-0.035888672,0.030212402,0.05822754,0.08496094,-0.017715454,-0.05026245,-0.0118637085,0.019989014,-0.040649414,-0.04046631,-0.021240234,-0.023468018,-0.00036263466,0.107177734,0.06488037,-0.018203735,-0.0042915344,-0.030136108,-0.10467529,0.019592285,-0.0234375,0.013946533,0.02947998,-0.045410156,-0.022949219,-0.013221741,0.04220581,0.013641357,0.008865356,-0.0024337769,-0.025115967,-0.022064209,-0.0069999695,0.06304932,-0.0075531006,-0.082092285,0.082214355,0.029647827,0.020080566,0.0068473816,-0.020263672,0.018127441,-0.09661865,-0.037109375,0.023406982,0.010398865,0.08496094,0.032348633,0.000054836273,-0.035949707,0.03729248,-0.02557373,-0.0021400452,-0.079833984,-0.0018882751,-0.037017822,0.077941895,0.0053977966,0.0095825195,-0.10205078,-0.017364502,0.03781128,0.04675293,0.091796875,-0.1385498,0.066467285,-0.020751953,-0.053833008,0.026031494,-0.027938843,-0.09790039,-0.043060303,0.030227661,0.074645996,-0.042114258,0.052764893,-0.0062675476,0.014060974,0.0019102097,-0.02003479,0.036499023,-0.06933594,-0.03994751,-0.042510986,0.013015747,-0.021499634,-0.04751587,-0.045135498,0.020584106,0.028366089,0.10784912,0.059570312,-0.021331787,0.014564514,-0.024993896,0.11279297,-0.0657959,-0.026977539,0.059753418,-0.056518555,0.026611328,-0.034332275,-0.056396484,-0.019882202,-0.04006958,0.047027588,-0.0826416,-0.029586792,-0.04208374,0.07873535,-0.0045661926,0.0005311966,0.027572632,0.11395264,0.053466797,-0.08312988,-0.05340576,-0.013885498,0.017684937,-0.0053138733,-0.06149292,0.026809692,0.053863525,0.056243896,-0.034301758,-0.009902954,0.030227661,0.0256958,0.066833496,-0.008468628,-0.04333496,0.0056991577,0.020111084,-0.028366089,0.009506226,0.035095215,-0.020904541,-0.028900146,-0.06915283,0.016967773,-0.054534912,-0.03567505,0.058135986,-0.0435791,-0.015670776,0.03970337,0.057434082,0.049682617,-0.051330566,0.06488037,0.013900757,-0.030593872,0.06781006,0.12182617,0.024932861,0.02078247,0.14355469,0.06591797,0.0069351196,0.008773804,0.027557373,0.05633545,-0.10858154,-0.061920166,-0.053497314,-0.007835388,-0.019042969,0.015670776,0.0065994263,0.026275635,-0.03945923,-0.015182495,0.059417725,-0.096069336,-0.04989624,-0.06225586,-0.012916565,0.026153564,-0.008003235,0.14807129,0.015129089,-0.044555664,-0.041625977,-0.046325684,0.039611816,0.09887695,0.039611816,-0.08312988,-0.011375427,0.09454346,-0.0016365051,-0.07312012,-0.021469116,-0.028671265,-0.07897949,-0.124938965,-0.07318115,-0.06072998,-0.019561768,-0.09753418,0.003967285,0.037872314,0.0007991791,0.03479004,-0.023010254,-0.032470703,0.05606079,0.013221741,-0.048950195,0.042999268,-0.06542969,-0.07495117,-0.0552063,0.08892822,0.035888672,-0.06384277,0.08831787,-0.039001465,0.11834717,-0.02142334,-0.08483887,-0.09613037,0.03555298,-0.037628174,0.014678955,0.010017395,-0.038208008,-0.027572632,0.00856781,-0.06616211,-0.009941101,0.06335449,0.009796143,-0.06378174,-0.020233154,0.043395996,0.05706787,0.02230835,-0.014968872,-0.014030457,-0.109436035,-0.013519287,-0.0077552795,0.101135254,0.027709961,-0.11627197,0.020843506,0.06713867,0.022567749,0.059631348,0.031921387,0.02861023,0.0044021606,0.03567505,0.07446289,0.007621765,0.0054855347,-0.00060367584,0.034118652,0.014129639,-0.030197144,-0.0018558502,0.071777344,0.06100464,-0.054840088,-0.035949707,-0.020706177,0.070617676,-0.035217285,-0.0005097389,0.0013685226,0.017211914,0.07354736,0.0058670044,-0.050567627,0.010406494,-0.05316162,-0.021392822,0.1104126,0.017715454,0.02015686,0.017715454,-0.04611206,-0.03451538,-0.020584106,-0.014701843,0.0065994263,-0.044555664,-0.0680542,0.02571106,-0.06939697,-0.075927734,0.06982422,-0.026382446,0.020263672,0.12512207,0.058807373,-0.014953613,-0.10321045,0.02897644,0.027740479,-0.0033302307,-0.010604858,0.077941895,0.022720337,0.022537231,0.027252197,0.015716553,0.02279663,-0.026641846,0.043548584,0.029266357,0.041625977,-0.01802063,0.0024337769,0.0112838745,0.03665161,0.026550293,0.024658203,-0.013092041,0.004169464,0.044952393,0.06591797,-0.056488037,0.07647705,-0.051086426,-0.03955078,-0.09399414,0.016036987,-0.04309082,-0.05795288,-0.024536133,0.06549072]]},"meta":{"api_version":{"version":"2"},"billed_units":{"input_tokens":208}},"response_type":"embeddings_by_type"}' + headers: + Alt-Svc: + - h3=":443"; ma=2592000,h3-29=":443"; ma=2592000 + Transfer-Encoding: + - chunked + Via: + - 1.1 google + access-control-expose-headers: + - X-Debug-Trace-ID + cache-control: + - no-cache, no-store, no-transform, must-revalidate, private, max-age=0 + content-type: + - application/json + date: + - Sun, 14 Sep 2025 03:17:07 GMT + expires: + - Thu, 01 Jan 1970 00:00:00 GMT + num_chars: + - '967' + num_tokens: + - '208' + pragma: + - no-cache + server: + - envoy + vary: + - Origin + x-accel-expires: + - '0' + x-debug-trace-id: + - 06931949a01aec81c801d99d17c414a1 + x-envoy-upstream-service-time: + - '48' + status: + code: 200 + message: OK +version: 1 diff --git a/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_rerank/test_cohere_v2_rerank_legacy.yaml b/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_rerank/test_cohere_v2_rerank_legacy.yaml new file mode 100644 index 0000000000..343223546e --- /dev/null +++ b/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_rerank/test_cohere_v2_rerank_legacy.yaml @@ -0,0 +1,76 @@ +interactions: +- request: + body: '{"model": "rerank-english-v3.0", "query": "What is the capital of the United + States?", "documents": ["Carson City is the capital city of the American state + of Nevada. At the 2010 United States Census, Carson City had a population of + 55,274.", "The Commonwealth of the Northern Mariana Islands is a group of islands + in the Pacific Ocean that are a political division controlled by the United + States. Its capital is Saipan.", "Charlotte Amalie is the capital and largest + city of the United States Virgin Islands. It has about 20,000 people. The city + is on the island of Saint Thomas.", "Washington, D.C. (also known as simply + Washington or D.C., and officially as the District of Columbia) is the capital + of the United States. It is a federal district. ", "Capital punishment (the + death penalty) has existed in the United States since before the United States + was a country. As of 2017, capital punishment is legal in 30 of the 50 states.", + "North Dakota is a state in the United States. 672,591 people lived in North + Dakota in the year 2010. The capital and seat of government is Bismarck."], + "top_n": 3}' + headers: + accept: + - '*/*' + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '1104' + content-type: + - application/json + host: + - api.cohere.com + user-agent: + - cohere/5.18.0 + x-fern-language: + - Python + x-fern-sdk-name: + - cohere + x-fern-sdk-version: + - 5.18.0 + method: POST + uri: https://api.cohere.com/v2/rerank + response: + body: + string: '{"id":"26c7d7a0-ca6f-49b3-a685-1e44a732603d","results":[{"index":3,"relevance_score":0.999071},{"index":4,"relevance_score":0.7779754},{"index":1,"relevance_score":0.08882029}],"meta":{"api_version":{"version":"2"},"billed_units":{"search_units":1}}}' + headers: + Alt-Svc: + - h3=":443"; ma=2592000,h3-29=":443"; ma=2592000 + Content-Length: + - '250' + Via: + - 1.1 google + access-control-expose-headers: + - X-Debug-Trace-ID + cache-control: + - no-cache, no-store, no-transform, must-revalidate, private, max-age=0 + content-type: + - application/json + date: + - Sun, 14 Sep 2025 03:08:05 GMT + expires: + - Thu, 01 Jan 1970 00:00:00 GMT + pragma: + - no-cache + server: + - envoy + vary: + - Origin + x-accel-expires: + - '0' + x-debug-trace-id: + - 67ff3eb8118c2ae80c643e001ecff172 + x-envoy-upstream-service-time: + - '44' + status: + code: 200 + message: OK +version: 1 diff --git a/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_rerank/test_cohere_v2_rerank_legacy_async.yaml b/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_rerank/test_cohere_v2_rerank_legacy_async.yaml new file mode 100644 index 0000000000..d2efd53969 --- /dev/null +++ b/packages/opentelemetry-instrumentation-cohere/tests/cassettes/test_rerank/test_cohere_v2_rerank_legacy_async.yaml @@ -0,0 +1,76 @@ +interactions: +- request: + body: '{"model": "rerank-english-v3.0", "query": "What is the capital of the United + States?", "documents": ["Carson City is the capital city of the American state + of Nevada. At the 2010 United States Census, Carson City had a population of + 55,274.", "The Commonwealth of the Northern Mariana Islands is a group of islands + in the Pacific Ocean that are a political division controlled by the United + States. Its capital is Saipan.", "Charlotte Amalie is the capital and largest + city of the United States Virgin Islands. It has about 20,000 people. The city + is on the island of Saint Thomas.", "Washington, D.C. (also known as simply + Washington or D.C., and officially as the District of Columbia) is the capital + of the United States. It is a federal district. ", "Capital punishment (the + death penalty) has existed in the United States since before the United States + was a country. As of 2017, capital punishment is legal in 30 of the 50 states.", + "North Dakota is a state in the United States. 672,591 people lived in North + Dakota in the year 2010. The capital and seat of government is Bismarck."], + "top_n": 3}' + headers: + accept: + - '*/*' + accept-encoding: + - gzip, deflate + connection: + - keep-alive + content-length: + - '1104' + content-type: + - application/json + host: + - api.cohere.com + user-agent: + - cohere/5.18.0 + x-fern-language: + - Python + x-fern-sdk-name: + - cohere + x-fern-sdk-version: + - 5.18.0 + method: POST + uri: https://api.cohere.com/v2/rerank + response: + body: + string: '{"id":"4a07fec0-e0d2-438d-a52a-986e465aa7bb","results":[{"index":3,"relevance_score":0.999071},{"index":4,"relevance_score":0.7779754},{"index":1,"relevance_score":0.08882029}],"meta":{"api_version":{"version":"2"},"billed_units":{"search_units":1}}}' + headers: + Alt-Svc: + - h3=":443"; ma=2592000,h3-29=":443"; ma=2592000 + Content-Length: + - '250' + Via: + - 1.1 google + access-control-expose-headers: + - X-Debug-Trace-ID + cache-control: + - no-cache, no-store, no-transform, must-revalidate, private, max-age=0 + content-type: + - application/json + date: + - Sun, 14 Sep 2025 03:08:05 GMT + expires: + - Thu, 01 Jan 1970 00:00:00 GMT + pragma: + - no-cache + server: + - envoy + vary: + - Origin + x-accel-expires: + - '0' + x-debug-trace-id: + - 7874a0d2c0ac809c78a02164b072f7f6 + x-envoy-upstream-service-time: + - '47' + status: + code: 200 + message: OK +version: 1 diff --git a/packages/opentelemetry-instrumentation-cohere/tests/conftest.py b/packages/opentelemetry-instrumentation-cohere/tests/conftest.py index 0d061f39dc..0b7758c092 100644 --- a/packages/opentelemetry-instrumentation-cohere/tests/conftest.py +++ b/packages/opentelemetry-instrumentation-cohere/tests/conftest.py @@ -52,6 +52,21 @@ def cohere_client(): return cohere.Client(os.environ.get("COHERE_API_KEY")) +@pytest.fixture +def async_cohere_client(): + return cohere.AsyncClient(os.environ.get("COHERE_API_KEY")) + + +@pytest.fixture +def cohere_client_v2(): + return cohere.ClientV2(os.environ.get("COHERE_API_KEY")) + + +@pytest.fixture +def async_cohere_client_v2(): + return cohere.AsyncClientV2(os.environ.get("COHERE_API_KEY")) + + @pytest.fixture(scope="function") def instrument_legacy(tracer_provider): instrumentor = CohereInstrumentor() diff --git a/packages/opentelemetry-instrumentation-cohere/tests/test_chat.py b/packages/opentelemetry-instrumentation-cohere/tests/test_chat.py index fd97cf45ce..ecbe200bd7 100644 --- a/packages/opentelemetry-instrumentation-cohere/tests/test_chat.py +++ b/packages/opentelemetry-instrumentation-cohere/tests/test_chat.py @@ -1,3 +1,4 @@ +import json import pytest from opentelemetry.sdk._logs import LogData from opentelemetry.semconv._incubating.attributes import ( @@ -9,6 +10,44 @@ from opentelemetry.semconv_ai import SpanAttributes +TOOLS = [ + { + "type": "function", + "function": { + "name": "get_weather", + "description": "Get the current weather in a given location", + "parameters": { + "type": "object", + "properties": { + "location": { + "type": "string", + "description": "The city and state, e.g. San Francisco, CA" + } + }, + "required": ["location"] + } + } + }, + { + "type": "function", + "function": { + "name": "get_time", + "description": "Get the current time in a given location", + "parameters": { + "type": "object", + "properties": { + "location": { + "type": "string", + "description": "The city and state, e.g. San Francisco, CA" + } + }, + "required": ["location"] + } + } + } +] + + @pytest.mark.vcr def test_cohere_chat_legacy( span_exporter, log_exporter, instrument_legacy, cohere_client @@ -46,6 +85,435 @@ def test_cohere_chat_legacy( ), "Assert that it doesn't emit logs when use_legacy_attributes is True" +@pytest.mark.vcr +def test_cohere_v2_chat_legacy( + span_exporter, log_exporter, instrument_legacy, cohere_client_v2 +): + res = cohere_client_v2.chat( + model="command", messages=[{"role": "user", "content": "Tell me a joke, pirate style"}] + ) + + spans = span_exporter.get_finished_spans() + cohere_span = spans[0] + assert cohere_span.name == "cohere.chat" + assert cohere_span.attributes.get(SpanAttributes.LLM_SYSTEM) == "Cohere" + assert cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_TYPE) == "chat" + assert cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_MODEL) == "command" + assert ( + cohere_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.0.content") + == "Tell me a joke, pirate style" + ) + assert ( + json.loads(cohere_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content")) + == [ + { + "type": "text", + "text": res.message.content[-1].text + } + ] + ) + assert cohere_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 7 + assert cohere_span.attributes.get( + SpanAttributes.LLM_USAGE_TOTAL_TOKENS + ) == cohere_span.attributes.get( + SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + ) + cohere_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) + assert ( + cohere_span.attributes.get("gen_ai.response.id") + == "83e3e297-264b-478e-9b22-5058386292ed" + ) + + logs = log_exporter.get_finished_logs() + assert ( + len(logs) == 0 + ), "Assert that it doesn't emit logs when use_legacy_attributes is True" + + +@pytest.mark.vcr +def test_cohere_chat_legacy_with_streaming( + span_exporter, log_exporter, instrument_legacy, cohere_client +): + stream = cohere_client.chat_stream(model="command", message="Tell me a joke, pirate style") + + res = "" + for chunk in stream: + if chunk.event_type == "text-generation": + res += chunk.text + + spans = span_exporter.get_finished_spans() + cohere_span = spans[0] + assert cohere_span.name == "cohere.chat" + assert cohere_span.attributes.get(SpanAttributes.LLM_SYSTEM) == "Cohere" + assert cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_TYPE) == "chat" + assert cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_MODEL) == "command" + assert ( + cohere_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.0.content") + == "Tell me a joke, pirate style" + ) + assert ( + cohere_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + == res + ) + assert cohere_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 7 + assert cohere_span.attributes.get( + SpanAttributes.LLM_USAGE_TOTAL_TOKENS + ) == cohere_span.attributes.get( + SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + ) + cohere_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) + assert ( + cohere_span.attributes.get("gen_ai.response.id") + == "12c00d26-e3bb-48c0-8c49-262155b57d64" + ) + + logs = log_exporter.get_finished_logs() + assert ( + len(logs) == 0 + ), "Assert that it doesn't emit logs when use_legacy_attributes is True" + + +@pytest.mark.vcr +def test_cohere_v2_chat_legacy_with_streaming( + span_exporter, log_exporter, instrument_legacy, cohere_client_v2 +): + stream = cohere_client_v2.chat_stream( + model="command", messages=[{"role": "user", "content": "Tell me a joke, pirate style"}] + ) + + res = "" + for chunk in stream: + if chunk.type == "content-delta": + res += chunk.delta.message.content.text + + spans = span_exporter.get_finished_spans() + cohere_span = spans[0] + assert cohere_span.name == "cohere.chat" + assert cohere_span.attributes.get(SpanAttributes.LLM_SYSTEM) == "Cohere" + assert cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_TYPE) == "chat" + assert cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_MODEL) == "command" + assert ( + cohere_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.0.content") + == "Tell me a joke, pirate style" + ) + assert ( + json.loads(cohere_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content")) + == [ + { + "type": "text", + "text": res, + "thinking": None + } + ] + ) + assert cohere_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 7 + assert cohere_span.attributes.get( + SpanAttributes.LLM_USAGE_TOTAL_TOKENS + ) == cohere_span.attributes.get( + SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + ) + cohere_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) + assert ( + cohere_span.attributes.get("gen_ai.response.id") + == "6cd6ce61-bb3b-46f6-907e-fcfab45e51b6" + ) + + logs = log_exporter.get_finished_logs() + assert ( + len(logs) == 0 + ), "Assert that it doesn't emit logs when use_legacy_attributes is True" + + +@pytest.mark.vcr +def test_cohere_v2_chat_legacy_with_tool_calls_and_history( + span_exporter, log_exporter, instrument_legacy, cohere_client_v2 +): + user_prompt = "What is the weather and current time in Tokyo?" + res1 = cohere_client_v2.chat( + model="command-r", + messages=[{"role": "user", "content": user_prompt}], + tools=TOOLS, + ) + res2 = cohere_client_v2.chat( + model="command-r", + messages=[ + {"role": "user", "content": user_prompt}, + { + "role": "assistant", + "content": res1.message.content, + "tool_calls": res1.message.tool_calls + }, + { + "role": "tool", + "tool_call_id": res1.message.tool_calls[0].id, + "content": "4:20 PM" + }, + { + "role": "tool", + "tool_call_id": res1.message.tool_calls[1].id, + "content": "Sunny 20 degrees Celsius" + }, + ], + tools=TOOLS, + ) + + spans = span_exporter.get_finished_spans() + assert len(spans) == 2 + sorted_spans = sorted(spans, key=lambda x: x.start_time) + span1 = sorted_spans[0] + span2 = sorted_spans[1] + assert span1.name == "cohere.chat" + assert span2.name == "cohere.chat" + assert span1.attributes.get(SpanAttributes.LLM_SYSTEM) == "Cohere" + assert span2.attributes.get(SpanAttributes.LLM_SYSTEM) == "Cohere" + assert span1.attributes.get(SpanAttributes.LLM_REQUEST_TYPE) == "chat" + assert span2.attributes.get(SpanAttributes.LLM_REQUEST_TYPE) == "chat" + assert span1.attributes.get(SpanAttributes.LLM_REQUEST_MODEL) == "command-r" + assert span2.attributes.get(SpanAttributes.LLM_REQUEST_MODEL) == "command-r" + + for span in [span1, span2]: + assert ( + span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.0.content") + == user_prompt + ) + assert span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.0.role") == "user" + assert ( + span.attributes.get(f"{SpanAttributes.LLM_REQUEST_FUNCTIONS}.0.name") + == TOOLS[0].get("function").get("name") + ) + assert ( + span.attributes.get(f"{SpanAttributes.LLM_REQUEST_FUNCTIONS}.0.description") + == TOOLS[0].get("function").get("description") + ) + assert ( + json.loads(span.attributes.get(f"{SpanAttributes.LLM_REQUEST_FUNCTIONS}.0.parameters")) + == TOOLS[0].get("function").get("parameters") + ) + assert ( + span.attributes.get(f"{SpanAttributes.LLM_REQUEST_FUNCTIONS}.1.name") + == TOOLS[1].get("function").get("name") + ) + assert ( + span.attributes.get(f"{SpanAttributes.LLM_REQUEST_FUNCTIONS}.1.description") + == TOOLS[1].get("function").get("description") + ) + assert ( + json.loads(span.attributes.get(f"{SpanAttributes.LLM_REQUEST_FUNCTIONS}.1.parameters")) + == TOOLS[1].get("function").get("parameters") + ) + assert ( + json.loads(span.attributes.get(f"{SpanAttributes.LLM_REQUEST_FUNCTIONS}.1.parameters")) + == TOOLS[1].get("function").get("parameters") + ) + + assert ( + json.loads(span1.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content")) + == [{ + "type": "text", + "text": res1.message.tool_plan + }] + ) + assert ( + span1.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.role") + == "assistant" + ) + assert ( + span1.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.id") + == res1.message.tool_calls[0].id + ) + assert ( + span1.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.name") + == res1.message.tool_calls[0].function.name + ) + assert ( + span1.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.arguments") + == res1.message.tool_calls[0].function.arguments + ) + assert ( + span1.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.1.id") + == res1.message.tool_calls[1].id + ) + assert ( + span1.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.1.name") + == res1.message.tool_calls[1].function.name + ) + assert ( + span1.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.1.arguments") + == res1.message.tool_calls[1].function.arguments + ) + + assert ( + span1.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.1.name") + == res1.message.tool_calls[1].function.name + ) + assert ( + span1.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.1.arguments") + == res1.message.tool_calls[1].function.arguments + ) + + assert ( + span1.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.id") + == res1.message.tool_calls[0].id + ) + assert ( + span1.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.name") + == res1.message.tool_calls[0].function.name + ) + assert ( + span1.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.arguments") + == res1.message.tool_calls[0].function.arguments + ) + assert ( + span1.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.1.id") + == res1.message.tool_calls[1].id + ) + assert ( + span1.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.1.name") + == res1.message.tool_calls[1].function.name + ) + assert ( + span1.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.1.arguments") + == res1.message.tool_calls[1].function.arguments + ) + + assert span2.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.1.content") == res1.message.content + assert span2.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.1.role") == "assistant" + assert span2.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.2.content") == "4:20 PM" + assert span2.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.2.role") == "tool" + assert span2.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.3.content") == "Sunny 20 degrees Celsius" + assert span2.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.3.role") == "tool" + + assert span2.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.role") == "assistant" + assert json.loads(span2.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content")) == [{ + "type": "text", + "text": res2.message.content[-1].text + }] + + assert span1.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 62 + assert span1.attributes.get( + SpanAttributes.LLM_USAGE_TOTAL_TOKENS + ) == span1.attributes.get( + SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + ) + span1.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) + assert ( + span1.attributes.get("gen_ai.response.id") + == "965405bb-b9da-4dc5-b329-e708a795e188" + ) + assert span2.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 94 + assert span2.attributes.get( + SpanAttributes.LLM_USAGE_TOTAL_TOKENS + ) == span2.attributes.get( + SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + ) + span2.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) + assert ( + span2.attributes.get("gen_ai.response.id") + == "00f7ec58-cd22-4b62-b068-0e7ece6bbf67" + ) + + logs = log_exporter.get_finished_logs() + assert ( + len(logs) == 0 + ), "Assert that it doesn't emit logs when use_legacy_attributes is True" + + +@pytest.mark.vcr +def test_cohere_v2_chat_legacy_with_tool_calls_and_streaming( + span_exporter, log_exporter, instrument_legacy, cohere_client_v2 +): + user_prompt = "What is the weather and current time in Tokyo?" + res1 = cohere_client_v2.chat_stream( + model="command-r", + messages=[{"role": "user", "content": user_prompt}], + tools=TOOLS, + ) + + plan = "" + for chunk in res1: + if chunk.type == "tool-plan-delta": + plan += chunk.delta.message.tool_plan + + spans = span_exporter.get_finished_spans() + assert len(spans) == 1 + span = spans[0] + assert span.name == "cohere.chat" + assert span.attributes.get(SpanAttributes.LLM_SYSTEM) == "Cohere" + assert span.attributes.get(SpanAttributes.LLM_REQUEST_TYPE) == "chat" + assert span.attributes.get(SpanAttributes.LLM_REQUEST_MODEL) == "command-r" + + assert ( + span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.0.content") + == user_prompt + ) + assert span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.0.role") == "user" + assert ( + span.attributes.get(f"{SpanAttributes.LLM_REQUEST_FUNCTIONS}.0.name") + == TOOLS[0].get("function").get("name") + ) + assert ( + span.attributes.get(f"{SpanAttributes.LLM_REQUEST_FUNCTIONS}.0.description") + == TOOLS[0].get("function").get("description") + ) + assert ( + json.loads(span.attributes.get(f"{SpanAttributes.LLM_REQUEST_FUNCTIONS}.0.parameters")) + == TOOLS[0].get("function").get("parameters") + ) + assert ( + span.attributes.get(f"{SpanAttributes.LLM_REQUEST_FUNCTIONS}.1.name") + == TOOLS[1].get("function").get("name") + ) + assert ( + span.attributes.get(f"{SpanAttributes.LLM_REQUEST_FUNCTIONS}.1.description") + == TOOLS[1].get("function").get("description") + ) + assert ( + json.loads(span.attributes.get(f"{SpanAttributes.LLM_REQUEST_FUNCTIONS}.1.parameters")) + == TOOLS[1].get("function").get("parameters") + ) + + assert ( + json.loads(span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content")) + == [{ + "type": "text", + "text": plan + }] + ) + assert span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.role") == "assistant" + assert ( + span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.id") + == "get_time_dg5wwc00d8v5" + ) + assert span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.name") == "get_time" + assert ( + json.loads(span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.arguments")) + == {"location": "Tokyo"} + ) + assert ( + span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.1.id") + == "get_weather_bc8241gkqss5" + ) + assert ( + span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.1.name") + == "get_weather" + ) + assert ( + json.loads(span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.1.arguments")) + == {"location": "Tokyo"} + ) + + assert span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 62 + assert span.attributes.get( + SpanAttributes.LLM_USAGE_TOTAL_TOKENS + ) == span.attributes.get( + SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + ) + span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) + assert ( + span.attributes.get("gen_ai.response.id") + == "e6d757a9-f0f3-40fe-9b8a-44cdc3bd18a7" + ) + + logs = log_exporter.get_finished_logs() + assert ( + len(logs) == 0 + ), "Assert that it doesn't emit logs when use_legacy_attributes is True" + + @pytest.mark.vcr def test_cohere_chat_with_events_with_content( span_exporter, log_exporter, instrument_with_content, cohere_client @@ -104,6 +572,452 @@ def test_cohere_chat_with_events_with_no_content( assert_message_in_logs(logs[1], "gen_ai.choice", choice_event) +@pytest.mark.vcr +@pytest.mark.asyncio +async def test_cohere_chat_legacy_async( + span_exporter, log_exporter, instrument_legacy, async_cohere_client +): + res = await async_cohere_client.chat(model="command", message="Tell me a joke, pirate style") + + spans = span_exporter.get_finished_spans() + cohere_span = spans[0] + assert cohere_span.name == "cohere.chat" + assert cohere_span.attributes.get(SpanAttributes.LLM_SYSTEM) == "Cohere" + assert cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_TYPE) == "chat" + assert cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_MODEL) == "command" + assert ( + cohere_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.0.content") + == "Tell me a joke, pirate style" + ) + assert ( + cohere_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + == res.text + ) + assert cohere_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 7 + assert cohere_span.attributes.get( + SpanAttributes.LLM_USAGE_TOTAL_TOKENS + ) == cohere_span.attributes.get( + SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + ) + cohere_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) + assert ( + cohere_span.attributes.get("gen_ai.response.id") + == "ea2d074c-4f25-47cb-bef8-b00dc2ae991b" + ) + + logs = log_exporter.get_finished_logs() + assert ( + len(logs) == 0 + ), "Assert that it doesn't emit logs when use_legacy_attributes is True" + + +@pytest.mark.vcr +@pytest.mark.asyncio +async def test_cohere_chat_with_events_with_content_async( + span_exporter, log_exporter, instrument_with_content, async_cohere_client +): + user_message = "Tell me a joke, pirate style" + res = await async_cohere_client.chat(model="command", message=user_message) + + spans = span_exporter.get_finished_spans() + cohere_span = spans[0] + assert cohere_span.name == "cohere.chat" + assert cohere_span.attributes.get(SpanAttributes.LLM_SYSTEM) == "Cohere" + assert cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_TYPE) == "chat" + assert cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_MODEL) == "command" + + logs = log_exporter.get_finished_logs() + assert len(logs) == 2 + + # Validate user message Event + assert_message_in_logs(logs[0], "gen_ai.user.message", {"content": user_message}) + + # Validate model response Event + choice_event = { + "index": 0, + "finish_reason": "COMPLETE", + "message": {"content": res.text}, + } + assert_message_in_logs(logs[1], "gen_ai.choice", choice_event) + + +@pytest.mark.vcr +@pytest.mark.asyncio +async def test_cohere_chat_with_events_with_no_content_async( + span_exporter, log_exporter, instrument_with_no_content, async_cohere_client +): + user_message = "Tell me a joke, pirate style" + await async_cohere_client.chat(model="command", message=user_message) + + spans = span_exporter.get_finished_spans() + cohere_span = spans[0] + assert cohere_span.name == "cohere.chat" + assert cohere_span.attributes.get(SpanAttributes.LLM_SYSTEM) == "Cohere" + assert cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_TYPE) == "chat" + assert cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_MODEL) == "command" + + logs = log_exporter.get_finished_logs() + assert len(logs) == 2 + + # Validate user message Event + assert_message_in_logs(logs[0], "gen_ai.user.message", {}) + + # Validate model response Event + choice_event = { + "index": 0, + "finish_reason": "COMPLETE", + "message": {}, + } + assert_message_in_logs(logs[1], "gen_ai.choice", choice_event) + + +@pytest.mark.vcr +@pytest.mark.asyncio +async def test_cohere_chat_legacy_with_streaming_async( + span_exporter, log_exporter, instrument_legacy, async_cohere_client +): + stream = async_cohere_client.chat_stream(model="command", message="Tell me a joke, pirate style") + + res = "" + async for chunk in stream: + if chunk.event_type == "text-generation": + res += chunk.text + + spans = span_exporter.get_finished_spans() + cohere_span = spans[0] + assert cohere_span.name == "cohere.chat" + assert cohere_span.attributes.get(SpanAttributes.LLM_SYSTEM) == "Cohere" + assert cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_TYPE) == "chat" + assert cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_MODEL) == "command" + assert ( + cohere_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.0.content") + == "Tell me a joke, pirate style" + ) + assert ( + cohere_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content") + == res + ) + assert cohere_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 7 + assert cohere_span.attributes.get( + SpanAttributes.LLM_USAGE_TOTAL_TOKENS + ) == cohere_span.attributes.get( + SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + ) + cohere_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) + assert ( + cohere_span.attributes.get("gen_ai.response.id") + == "dcdb9a85-a8dc-4f4c-9779-f7c1801248f3" + ) + + logs = log_exporter.get_finished_logs() + assert ( + len(logs) == 0 + ), "Assert that it doesn't emit logs when use_legacy_attributes is True" + + +@pytest.mark.vcr +@pytest.mark.asyncio +async def test_cohere_v2_chat_legacy_with_streaming_async( + span_exporter, log_exporter, instrument_legacy, async_cohere_client_v2 +): + stream = async_cohere_client_v2.chat_stream( + model="command", messages=[{"role": "user", "content": "Tell me a joke, pirate style"}] + ) + + res = "" + async for chunk in stream: + if chunk.type == "content-delta": + res += chunk.delta.message.content.text + + spans = span_exporter.get_finished_spans() + cohere_span = spans[0] + assert cohere_span.name == "cohere.chat" + assert cohere_span.attributes.get(SpanAttributes.LLM_SYSTEM) == "Cohere" + assert cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_TYPE) == "chat" + assert cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_MODEL) == "command" + assert ( + cohere_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.0.content") + == "Tell me a joke, pirate style" + ) + assert ( + json.loads(cohere_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content")) + == [ + { + "type": "text", + "text": res, + "thinking": None + } + ] + ) + assert cohere_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 7 + assert cohere_span.attributes.get( + SpanAttributes.LLM_USAGE_TOTAL_TOKENS + ) == cohere_span.attributes.get( + SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + ) + cohere_span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) + assert ( + cohere_span.attributes.get("gen_ai.response.id") + == "599ae0aa-0ef6-49e4-b7f4-e2fafc40ca2c" + ) + + logs = log_exporter.get_finished_logs() + assert ( + len(logs) == 0 + ), "Assert that it doesn't emit logs when use_legacy_attributes is True" + + +@pytest.mark.vcr +@pytest.mark.asyncio +async def test_cohere_v2_chat_legacy_with_tool_calls_and_history_async( + span_exporter, log_exporter, instrument_legacy, async_cohere_client_v2 +): + user_prompt = "What is the weather and current time in Tokyo?" + res1 = await async_cohere_client_v2.chat( + model="command-r7b-12-2024", + messages=[{"role": "user", "content": user_prompt}], + tools=TOOLS, + ) + res2 = await async_cohere_client_v2.chat( + model="command-r7b-12-2024", + messages=[ + {"role": "user", "content": user_prompt}, + { + "role": "assistant", + "content": res1.message.content, + "tool_calls": res1.message.tool_calls + }, + { + "role": "tool", + "tool_call_id": res1.message.tool_calls[0].id, + "content": "4:20 PM" + }, + { + "role": "tool", + "tool_call_id": res1.message.tool_calls[1].id, + "content": "Sunny 20 degrees Celsius" + }, + ], + tools=TOOLS, + ) + + spans = span_exporter.get_finished_spans() + assert len(spans) == 2 + sorted_spans = sorted(spans, key=lambda x: x.start_time) + span1 = sorted_spans[0] + span2 = sorted_spans[1] + assert span1.name == "cohere.chat" + assert span2.name == "cohere.chat" + assert span1.attributes.get(SpanAttributes.LLM_SYSTEM) == "Cohere" + assert span2.attributes.get(SpanAttributes.LLM_SYSTEM) == "Cohere" + assert span1.attributes.get(SpanAttributes.LLM_REQUEST_TYPE) == "chat" + assert span2.attributes.get(SpanAttributes.LLM_REQUEST_TYPE) == "chat" + assert span1.attributes.get(SpanAttributes.LLM_REQUEST_MODEL) == "command-r7b-12-2024" + assert span2.attributes.get(SpanAttributes.LLM_REQUEST_MODEL) == "command-r7b-12-2024" + + for span in [span1, span2]: + assert ( + span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.0.content") + == user_prompt + ) + assert span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.0.role") == "user" + assert ( + span.attributes.get(f"{SpanAttributes.LLM_REQUEST_FUNCTIONS}.0.name") + == TOOLS[0].get("function").get("name") + ) + assert ( + span.attributes.get(f"{SpanAttributes.LLM_REQUEST_FUNCTIONS}.0.description") + == TOOLS[0].get("function").get("description") + ) + assert ( + json.loads(span.attributes.get(f"{SpanAttributes.LLM_REQUEST_FUNCTIONS}.0.parameters")) + == TOOLS[0].get("function").get("parameters") + ) + assert ( + span.attributes.get(f"{SpanAttributes.LLM_REQUEST_FUNCTIONS}.1.name") + == TOOLS[1].get("function").get("name") + ) + assert ( + span.attributes.get(f"{SpanAttributes.LLM_REQUEST_FUNCTIONS}.1.description") + == TOOLS[1].get("function").get("description") + ) + assert ( + json.loads(span.attributes.get(f"{SpanAttributes.LLM_REQUEST_FUNCTIONS}.1.parameters")) + == TOOLS[1].get("function").get("parameters") + ) + + assert ( + json.loads(span1.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content")) + == [{ + "type": "text", + "text": res1.message.tool_plan + }] + ) + assert span1.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.role") == "assistant" + assert ( + span1.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.id") + == res1.message.tool_calls[0].id + ) + assert ( + span1.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.name") + == res1.message.tool_calls[0].function.name + ) + assert ( + span1.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.arguments") + == res1.message.tool_calls[0].function.arguments + ) + assert ( + span1.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.1.id") + == res1.message.tool_calls[1].id + ) + assert ( + span1.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.1.name") + == res1.message.tool_calls[1].function.name + ) + assert ( + span1.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.1.arguments") + == res1.message.tool_calls[1].function.arguments + ) + + assert span2.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.1.content") == res1.message.content + assert span2.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.1.role") == "assistant" + assert span2.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.2.content") == "4:20 PM" + assert span2.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.2.role") == "tool" + assert span2.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.3.content") == "Sunny 20 degrees Celsius" + assert span2.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.3.role") == "tool" + + assert span2.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.role") == "assistant" + assert json.loads(span2.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content")) == [{ + "type": "text", + "text": res2.message.content[-1].text + }] + + assert span1.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 62 + assert span1.attributes.get( + SpanAttributes.LLM_USAGE_TOTAL_TOKENS + ) == span1.attributes.get( + SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + ) + span1.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) + assert ( + span1.attributes.get("gen_ai.response.id") + == "b7391518-e53e-4486-98ea-fabffcde31c2" + ) + assert span2.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 78 + assert span2.attributes.get( + SpanAttributes.LLM_USAGE_TOTAL_TOKENS + ) == span2.attributes.get( + SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + ) + span2.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) + assert ( + span2.attributes.get("gen_ai.response.id") + == "8289d4ee-a83b-4ce2-b7e1-245d9778fcf5" + ) + + logs = log_exporter.get_finished_logs() + assert ( + len(logs) == 0 + ), "Assert that it doesn't emit logs when use_legacy_attributes is True" + + +@pytest.mark.vcr +@pytest.mark.asyncio +async def test_cohere_v2_chat_legacy_with_tool_calls_and_streaming_async( + span_exporter, log_exporter, instrument_legacy, async_cohere_client_v2 +): + user_prompt = "What is the weather and current time in Tokyo?" + res1 = async_cohere_client_v2.chat_stream( + model="command-r", + messages=[{"role": "user", "content": user_prompt}], + tools=TOOLS, + ) + + plan = "" + async for chunk in res1: + if chunk.type == "tool-plan-delta": + plan += chunk.delta.message.tool_plan + + spans = span_exporter.get_finished_spans() + assert len(spans) == 1 + span = spans[0] + assert span.name == "cohere.chat" + assert span.attributes.get(SpanAttributes.LLM_SYSTEM) == "Cohere" + assert span.attributes.get(SpanAttributes.LLM_REQUEST_TYPE) == "chat" + assert span.attributes.get(SpanAttributes.LLM_REQUEST_MODEL) == "command-r" + + assert ( + span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.0.content") + == user_prompt + ) + assert span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.0.role") == "user" + assert ( + span.attributes.get(f"{SpanAttributes.LLM_REQUEST_FUNCTIONS}.0.name") + == TOOLS[0].get("function").get("name") + ) + assert ( + span.attributes.get(f"{SpanAttributes.LLM_REQUEST_FUNCTIONS}.0.description") + == TOOLS[0].get("function").get("description") + ) + assert ( + json.loads(span.attributes.get(f"{SpanAttributes.LLM_REQUEST_FUNCTIONS}.0.parameters")) + == TOOLS[0].get("function").get("parameters") + ) + assert ( + span.attributes.get(f"{SpanAttributes.LLM_REQUEST_FUNCTIONS}.1.name") + == TOOLS[1].get("function").get("name") + ) + assert ( + span.attributes.get(f"{SpanAttributes.LLM_REQUEST_FUNCTIONS}.1.description") + == TOOLS[1].get("function").get("description") + ) + assert ( + json.loads(span.attributes.get(f"{SpanAttributes.LLM_REQUEST_FUNCTIONS}.1.parameters")) + == TOOLS[1].get("function").get("parameters") + ) + + assert ( + json.loads(span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content")) + == [{ + "type": "text", + "text": plan + }] + ) + assert span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.role") == "assistant" + assert ( + span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.id") + == "get_time_mp1131yrhbga" + ) + assert ( + span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.name") + == "get_time" + ) + assert ( + json.loads(span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.0.arguments")) + == {"location": "Tokyo"} + ) + assert ( + span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.1.id") + == "get_weather_yxz1xx2m07cn" + ) + assert span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.1.name") == "get_weather" + assert ( + json.loads(span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.tool_calls.1.arguments")) + == {"location": "Tokyo"} + ) + + assert span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) == 62 + assert span.attributes.get( + SpanAttributes.LLM_USAGE_TOTAL_TOKENS + ) == span.attributes.get( + SpanAttributes.LLM_USAGE_COMPLETION_TOKENS + ) + span.attributes.get(SpanAttributes.LLM_USAGE_PROMPT_TOKENS) + assert ( + span.attributes.get("gen_ai.response.id") + == "ce257b09-c6da-4aed-b722-6384504180f5" + ) + + logs = log_exporter.get_finished_logs() + assert ( + len(logs) == 0 + ), "Assert that it doesn't emit logs when use_legacy_attributes is True" + + def assert_message_in_logs(log: LogData, event_name: str, expected_content: dict): assert log.log_record.attributes.get(EventAttributes.EVENT_NAME) == event_name assert ( diff --git a/packages/opentelemetry-instrumentation-cohere/tests/test_embed.py b/packages/opentelemetry-instrumentation-cohere/tests/test_embed.py new file mode 100644 index 0000000000..ecf488756a --- /dev/null +++ b/packages/opentelemetry-instrumentation-cohere/tests/test_embed.py @@ -0,0 +1,120 @@ +import json +import pytest +from opentelemetry.semconv_ai import SpanAttributes + + +@pytest.mark.vcr +def test_cohere_v2_embed_legacy( + span_exporter, log_exporter, instrument_legacy, cohere_client_v2 +): + texts = [ + "Carson City is the capital city of the American state of Nevada." + + " At the 2010 United States Census, Carson City had a population of 55,274.", + "The Commonwealth of the Northern Mariana Islands is a group of islands" + + " in the Pacific Ocean that are a political division controlled by the " + + "United States. Its capital is Saipan.", + "Charlotte Amalie is the capital and largest city of the United States " + + "Virgin Islands. It has about 20,000 people. The city is on the island of Saint Thomas.", + "Washington, D.C. (also known as simply Washington or D.C., and officially " + + "as the District of Columbia) is the capital of the United States. It is a federal district. ", + "Capital punishment (the death penalty) has existed in the United States " + + "since before the United States was a country. As of 2017, capital " + + "punishment is legal in 30 of the 50 states.", + "North Dakota is a state in the United States. 672,591 people lived" + + " in North Dakota in the year 2010. The capital and seat of government is Bismarck.", + ] + + cohere_client_v2.embed( + input_type="search_document", + texts=texts, model="embed-english-light-v3.0" + ) + + spans = span_exporter.get_finished_spans() + assert len(spans) == 1 + cohere_span = spans[0] + assert cohere_span.name == "cohere.embed" + assert cohere_span.attributes.get(SpanAttributes.LLM_SYSTEM) == "Cohere" + assert cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_TYPE) == "embedding" + assert ( + cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_MODEL) + == "embed-english-light-v3.0" + ) + assert ( + cohere_span.attributes.get( + f"{SpanAttributes.LLM_PROMPTS}.0.role" + ) + == "user" + ) + assert json.loads(cohere_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.0.content")) == [{ + "type": "text", + "text": text + } for text in texts] + + assert ( + cohere_span.attributes.get("gen_ai.response.id") + == "74d7aae4-2939-4002-b4d4-352dfcca03cf" + ) + + logs = log_exporter.get_finished_logs() + assert ( + len(logs) == 0 + ), "Assert that it doesn't emit logs when use_legacy_attributes is True" + + +@pytest.mark.vcr +@pytest.mark.asyncio +async def test_cohere_v2_embed_legacy_async( + span_exporter, log_exporter, instrument_legacy, async_cohere_client_v2 +): + texts = [ + "Carson City is the capital city of the American state of Nevada." + + " At the 2010 United States Census, Carson City had a population of 55,274.", + "The Commonwealth of the Northern Mariana Islands is a group of islands" + + " in the Pacific Ocean that are a political division controlled by the " + + "United States. Its capital is Saipan.", + "Charlotte Amalie is the capital and largest city of the United States " + + "Virgin Islands. It has about 20,000 people. The city is on the island of Saint Thomas.", + "Washington, D.C. (also known as simply Washington or D.C., and officially " + + "as the District of Columbia) is the capital of the United States. It is a federal district. ", + "Capital punishment (the death penalty) has existed in the United States " + + "since before the United States was a country. As of 2017, capital " + + "punishment is legal in 30 of the 50 states.", + "North Dakota is a state in the United States. 672,591 people lived" + + " in North Dakota in the year 2010. The capital and seat of government is Bismarck.", + ] + + await async_cohere_client_v2.embed( + input_type="search_document", + texts=texts, model="embed-english-light-v3.0" + ) + + spans = span_exporter.get_finished_spans() + assert len(spans) == 1 + cohere_span = spans[0] + assert cohere_span.name == "cohere.embed" + assert cohere_span.attributes.get(SpanAttributes.LLM_SYSTEM) == "Cohere" + assert cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_TYPE) == "embedding" + assert ( + cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_MODEL) + == "embed-english-light-v3.0" + ) + assert ( + cohere_span.attributes.get( + f"{SpanAttributes.LLM_PROMPTS}.0.role" + ) + == "user" + ) + assert json.loads(cohere_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.0.content")) == [{ + "type": "text", + "text": text + } for text in texts] + + assert ( + cohere_span.attributes.get("gen_ai.response.id") + == "3bc87f83-0534-4478-af7d-fee196c92758" + ) + + logs = log_exporter.get_finished_logs() + assert ( + len(logs) == 0 + ), "Assert that it doesn't emit logs when use_legacy_attributes is True" diff --git a/packages/opentelemetry-instrumentation-cohere/tests/test_rerank.py b/packages/opentelemetry-instrumentation-cohere/tests/test_rerank.py index 3da05d7417..c6fb0d4261 100644 --- a/packages/opentelemetry-instrumentation-cohere/tests/test_rerank.py +++ b/packages/opentelemetry-instrumentation-cohere/tests/test_rerank.py @@ -204,6 +204,167 @@ def test_cohere_rerank_with_events_with_no_content( assert_message_in_logs(logs[1], "gen_ai.choice", choice_event) +@pytest.mark.vcr +def test_cohere_v2_rerank_legacy( + span_exporter, log_exporter, instrument_legacy, cohere_client_v2 +): + query = "What is the capital of the United States?" + documents = [ + "Carson City is the capital city of the American state of Nevada." + + " At the 2010 United States Census, Carson City had a population of 55,274.", + "The Commonwealth of the Northern Mariana Islands is a group of islands" + + " in the Pacific Ocean that are a political division controlled by the " + + "United States. Its capital is Saipan.", + "Charlotte Amalie is the capital and largest city of the United States " + + "Virgin Islands. It has about 20,000 people. The city is on the island of Saint Thomas.", + "Washington, D.C. (also known as simply Washington or D.C., and officially " + + "as the District of Columbia) is the capital of the United States. It is a federal district. ", + "Capital punishment (the death penalty) has existed in the United States " + + "since before the United States was a country. As of 2017, capital " + + "punishment is legal in 30 of the 50 states.", + "North Dakota is a state in the United States. 672,591 people lived" + + " in North Dakota in the year 2010. The capital and seat of government is Bismarck.", + ] + + response = cohere_client_v2.rerank( + query=query, documents=documents, top_n=3, model="rerank-english-v3.0" + ) + + spans = span_exporter.get_finished_spans() + cohere_span = spans[0] + assert cohere_span.name == "cohere.rerank" + assert cohere_span.attributes.get(SpanAttributes.LLM_SYSTEM) == "Cohere" + assert cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_TYPE) == "rerank" + assert ( + cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_MODEL) + == "rerank-english-v3.0" + ) + assert ( + cohere_span.attributes.get( + f"{SpanAttributes.LLM_PROMPTS}.{len(documents)}.role" + ) + == "user" + ) + assert ( + cohere_span.attributes.get( + f"{SpanAttributes.LLM_PROMPTS}.{len(documents)}.content" + ) + == query + ) + + for i, doc in enumerate(documents): + assert ( + cohere_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.{i}.role") + == "system" + ) + assert ( + cohere_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.{i}.content") + == doc + ) + + for idx, result in enumerate(response.results): + assert ( + cohere_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.{idx}.role") + == "assistant" + ) + assert ( + cohere_span.attributes.get( + f"{SpanAttributes.LLM_COMPLETIONS}.{idx}.content" + ) + == f"Doc {result.index}, Score: {result.relevance_score}" + ) + assert ( + cohere_span.attributes.get("gen_ai.response.id") + == "26c7d7a0-ca6f-49b3-a685-1e44a732603d" + ) + + logs = log_exporter.get_finished_logs() + assert ( + len(logs) == 0 + ), "Assert that it doesn't emit logs when use_legacy_attributes is True" + + +@pytest.mark.vcr +@pytest.mark.asyncio +async def test_cohere_v2_rerank_legacy_async( + span_exporter, log_exporter, instrument_legacy, async_cohere_client_v2 +): + query = "What is the capital of the United States?" + documents = [ + "Carson City is the capital city of the American state of Nevada." + + " At the 2010 United States Census, Carson City had a population of 55,274.", + "The Commonwealth of the Northern Mariana Islands is a group of islands" + + " in the Pacific Ocean that are a political division controlled by the " + + "United States. Its capital is Saipan.", + "Charlotte Amalie is the capital and largest city of the United States " + + "Virgin Islands. It has about 20,000 people. The city is on the island of Saint Thomas.", + "Washington, D.C. (also known as simply Washington or D.C., and officially " + + "as the District of Columbia) is the capital of the United States. It is a federal district. ", + "Capital punishment (the death penalty) has existed in the United States " + + "since before the United States was a country. As of 2017, capital " + + "punishment is legal in 30 of the 50 states.", + "North Dakota is a state in the United States. 672,591 people lived" + + " in North Dakota in the year 2010. The capital and seat of government is Bismarck.", + ] + + response = await async_cohere_client_v2.rerank( + query=query, documents=documents, top_n=3, model="rerank-english-v3.0" + ) + + spans = span_exporter.get_finished_spans() + cohere_span = spans[0] + assert cohere_span.name == "cohere.rerank" + assert cohere_span.attributes.get(SpanAttributes.LLM_SYSTEM) == "Cohere" + assert cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_TYPE) == "rerank" + assert ( + cohere_span.attributes.get(SpanAttributes.LLM_REQUEST_MODEL) + == "rerank-english-v3.0" + ) + assert ( + cohere_span.attributes.get( + f"{SpanAttributes.LLM_PROMPTS}.{len(documents)}.role" + ) + == "user" + ) + assert ( + cohere_span.attributes.get( + f"{SpanAttributes.LLM_PROMPTS}.{len(documents)}.content" + ) + == query + ) + + for i, doc in enumerate(documents): + assert ( + cohere_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.{i}.role") + == "system" + ) + assert ( + cohere_span.attributes.get(f"{SpanAttributes.LLM_PROMPTS}.{i}.content") + == doc + ) + + for idx, result in enumerate(response.results): + assert ( + cohere_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.{idx}.role") + == "assistant" + ) + assert ( + cohere_span.attributes.get( + f"{SpanAttributes.LLM_COMPLETIONS}.{idx}.content" + ) + == f"Doc {result.index}, Score: {result.relevance_score}" + ) + assert ( + cohere_span.attributes.get("gen_ai.response.id") + == "4a07fec0-e0d2-438d-a52a-986e465aa7bb" + ) + + logs = log_exporter.get_finished_logs() + assert ( + len(logs) == 0 + ), "Assert that it doesn't emit logs when use_legacy_attributes is True" + + def assert_message_in_logs(log: LogData, event_name: str, expected_content: dict): assert log.log_record.attributes.get(EventAttributes.EVENT_NAME) == event_name assert ( From 0c103c97de203e62baf5b45d468875ad811c9625 Mon Sep 17 00:00:00 2001 From: Din Date: Sun, 14 Sep 2025 04:36:32 +0100 Subject: [PATCH 2/4] fix bugs caught by ellipsis --- .../opentelemetry/instrumentation/cohere/__init__.py | 12 ------------ .../instrumentation/cohere/span_utils.py | 5 ----- .../instrumentation/cohere/streaming.py | 1 - 3 files changed, 18 deletions(-) diff --git a/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/__init__.py b/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/__init__.py index db88004aea..4fd671c53d 100644 --- a/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/__init__.py +++ b/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/__init__.py @@ -86,12 +86,6 @@ "span_name": "cohere.chat", "stream_process_func": process_chat_v2_streaming_response, }, - { - "module": "cohere.client_v2", - "object": "ClientV2", - "method": "generate", - "span_name": "cohere.embed", - }, { "module": "cohere.client_v2", "object": "ClientV2", @@ -146,12 +140,6 @@ "method": "embed", "span_name": "cohere.embed", }, - { - "module": "cohere.client_v2", - "object": "AsyncClientV2", - "method": "generate", - "span_name": "cohere.embed", - }, { "module": "cohere.client_v2", "object": "AsyncClientV2", diff --git a/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/span_utils.py b/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/span_utils.py index c01eaffe49..9429df5ce4 100644 --- a/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/span_utils.py +++ b/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/span_utils.py @@ -82,11 +82,6 @@ def set_input_content_attributes(span, llm_request_type, kwargs): f"{SpanAttributes.LLM_REQUEST_FUNCTIONS}.{index}.parameters", dump_object(function.get("parameters")), ) - _set_span_attribute( - span, - f"{SpanAttributes.LLM_REQUEST_FUNCTIONS}.{index}.parameters", - dump_object(function.get("parameters")), - ) elif llm_request_type == LLMRequestTypeValues.RERANK: for index, document in enumerate(kwargs.get("documents", [])): _set_span_attribute( diff --git a/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/streaming.py b/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/streaming.py index 3378854820..476fcf276e 100644 --- a/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/streaming.py +++ b/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/streaming.py @@ -82,7 +82,6 @@ def process_chat_v2_streaming_response(span, event_logger, llm_request_type, res pass yield item_to_yield - print(f"final_response: {final_response}") set_span_response_attributes(span, final_response) if should_emit_events(): emit_response_events(event_logger, llm_request_type, final_response) From 9169ec427d0901fc51e68749617df45a77d30d38 Mon Sep 17 00:00:00 2001 From: Din Date: Sun, 14 Sep 2025 04:48:44 +0100 Subject: [PATCH 3/4] fix rabbit suggestions --- .../instrumentation/cohere/__init__.py | 5 +- .../instrumentation/cohere/streaming.py | 115 ++++++++++-------- 2 files changed, 66 insertions(+), 54 deletions(-) diff --git a/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/__init__.py b/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/__init__.py index 4fd671c53d..9f2445a8cf 100644 --- a/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/__init__.py +++ b/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/__init__.py @@ -238,7 +238,7 @@ def _wrap( span.set_status(Status(StatusCode.ERROR, str(e))) span.record_exception(e) span.end() - raise + raise if to_wrap.get("stream_process_func"): return to_wrap.get("stream_process_func")(span, event_logger, llm_request_type, response) @@ -284,7 +284,8 @@ async def _awrap( if span.is_recording(): span.set_status(Status(StatusCode.ERROR, str(e))) span.record_exception(e) - raise + span.end() + raise set_span_response_attributes(span, response) _handle_response_content(span, event_logger, llm_request_type, response) diff --git a/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/streaming.py b/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/streaming.py index 476fcf276e..352f7d69dd 100644 --- a/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/streaming.py +++ b/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/streaming.py @@ -18,48 +18,53 @@ } +@dont_throw def process_chat_v1_streaming_response(span, event_logger, llm_request_type, response): # This naive version assumes we've always successfully streamed till the end # and have received a StreamEndChatResponse, which includes the full response final_response = None - for item in response: - span.add_event(name=f"{SpanAttributes.LLM_CONTENT_COMPLETION_CHUNK}") + try: + for item in response: + span.add_event(name=f"{SpanAttributes.LLM_CONTENT_COMPLETION_CHUNK}") - item_to_yield = item - if getattr(item, "event_type", None) == "stream-end" and hasattr(item, "response"): - final_response = item.response + item_to_yield = item + if getattr(item, "event_type", None) == "stream-end" and hasattr(item, "response"): + final_response = item.response - yield item_to_yield + yield item_to_yield - set_span_response_attributes(span, final_response) - if should_emit_events(): - emit_response_events(event_logger, llm_request_type, final_response) - elif should_send_prompts(): - _set_span_chat_response(span, final_response) - span.set_status(Status(StatusCode.OK)) - span.end() + set_span_response_attributes(span, final_response) + if should_emit_events(): + emit_response_events(event_logger, llm_request_type, final_response) + elif should_send_prompts(): + _set_span_chat_response(span, final_response) + span.set_status(Status(StatusCode.OK)) + finally: + span.end() +@dont_throw async def aprocess_chat_v1_streaming_response(span, event_logger, llm_request_type, response): # This naive version assumes we've always successfully streamed till the end # and have received a StreamEndChatResponse, which includes the full response final_response = None - async for item in response: - span.add_event(name=f"{SpanAttributes.LLM_CONTENT_COMPLETION_CHUNK}") - - item_to_yield = item - if getattr(item, "event_type", None) == "stream-end" and hasattr(item, "response"): - final_response = item.response - - yield item_to_yield - - set_span_response_attributes(span, final_response) - if should_emit_events(): - emit_response_events(event_logger, llm_request_type, final_response) - elif should_send_prompts(): - _set_span_chat_response(span, final_response) - span.set_status(Status(StatusCode.OK)) - span.end() + try: + async for item in response: + span.add_event(name=f"{SpanAttributes.LLM_CONTENT_COMPLETION_CHUNK}") + + item_to_yield = item + if getattr(item, "event_type", None) == "stream-end" and hasattr(item, "response"): + final_response = item.response + + yield item_to_yield + set_span_response_attributes(span, final_response) + if should_emit_events(): + emit_response_events(event_logger, llm_request_type, final_response) + elif should_send_prompts(): + _set_span_chat_response(span, final_response) + span.set_status(Status(StatusCode.OK)) + finally: + span.end() @dont_throw @@ -71,28 +76,34 @@ def process_chat_v2_streaming_response(span, event_logger, llm_request_type, res "id": "", "error": None, } - current_content_item = {} - current_tool_call_item = {} - for item in response: - span.add_event(name=f"{SpanAttributes.LLM_CONTENT_COMPLETION_CHUNK}") - item_to_yield = item - try: - _accumulate_stream_item(item, current_content_item, current_tool_call_item, final_response) - except Exception: - pass - yield item_to_yield - - set_span_response_attributes(span, final_response) - if should_emit_events(): - emit_response_events(event_logger, llm_request_type, final_response) - elif should_send_prompts(): - _set_span_chat_response(span, final_response) - - if final_response.get("error"): - span.set_status(Status(StatusCode.ERROR, final_response.get("error"))) - span.record_exception(final_response.get("error")) - else: - span.set_status(Status(StatusCode.OK)) + current_content_item = {"type": "text", "thinking": None, "text": ""} + current_tool_call_item = { + "id": "", + "type": "function", + "function": {"name": "", "arguments": "", "description": ""}, + } + try: + for item in response: + span.add_event(name=f"{SpanAttributes.LLM_CONTENT_COMPLETION_CHUNK}") + item_to_yield = item + try: + _accumulate_stream_item(item, current_content_item, current_tool_call_item, final_response) + except Exception: + pass + yield item_to_yield + + set_span_response_attributes(span, final_response) + if should_emit_events(): + emit_response_events(event_logger, llm_request_type, final_response) + elif should_send_prompts(): + _set_span_chat_response(span, final_response) + + if final_response.get("error"): + span.set_status(Status(StatusCode.ERROR, final_response.get("error"))) + span.record_exception(final_response.get("error")) + else: + span.set_status(Status(StatusCode.OK)) + finally: span.end() @@ -153,7 +164,7 @@ def _accumulate_stream_item(item, current_content_item, current_tool_call_item, existing_text = current_content_item.get("text") current_content_item["text"] = (existing_text or "") + new_text elif item_dict.get("type") == "content-end": - final_response["message"]["content"].append(current_content_item) + final_response["message"]["content"].append({**current_content_item}) elif item_dict.get("type") == "tool-plan-delta": new_tool_plan = ((item_dict.get("delta") or {}).get("message") or {}).get("tool_plan") if new_tool_plan: From 81cb8b68cd00a2cf1efb8a6eeea34c61347f5269 Mon Sep 17 00:00:00 2001 From: Din Date: Sun, 14 Sep 2025 04:54:59 +0100 Subject: [PATCH 4/4] copy default message --- .../opentelemetry/instrumentation/cohere/streaming.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/streaming.py b/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/streaming.py index 352f7d69dd..f0ad2d8d24 100644 --- a/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/streaming.py +++ b/packages/opentelemetry-instrumentation-cohere/opentelemetry/instrumentation/cohere/streaming.py @@ -148,7 +148,7 @@ async def aprocess_chat_v2_streaming_response(span, event_logger, llm_request_ty def _accumulate_stream_item(item, current_content_item, current_tool_call_item, final_response): item_dict = to_dict(item) if item_dict.get("type") == "message-start": - final_response["message"] = (item_dict.get("delta") or {}).get("message") or DEFAULT_MESSAGE + final_response["message"] = (item_dict.get("delta") or {}).get("message") or {**DEFAULT_MESSAGE} final_response["id"] = item_dict.get("id") elif item_dict.get("type") == "content-start": new_content_item = ((item_dict.get("delta") or {}).get("message") or {}).get("content")