From 8f5aba475c661bbbae828fb94f7b98288f4a0bb1 Mon Sep 17 00:00:00 2001 From: obinnascale3 <109410793+obinnascale3@users.noreply.github.com> Date: Wed, 14 May 2025 15:52:45 +0100 Subject: [PATCH 1/2] capture different types of google genai inputs (#534) Co-authored-by: Obinna Okafor --- .../instrumentation/google_genai/patch.py | 60 ++++++++++++++++--- src/langtrace_python_sdk/version.py | 2 +- 2 files changed, 54 insertions(+), 8 deletions(-) diff --git a/src/langtrace_python_sdk/instrumentation/google_genai/patch.py b/src/langtrace_python_sdk/instrumentation/google_genai/patch.py index 02cf9ef5..6fd2c9be 100644 --- a/src/langtrace_python_sdk/instrumentation/google_genai/patch.py +++ b/src/langtrace_python_sdk/instrumentation/google_genai/patch.py @@ -1,3 +1,4 @@ +import base64 from langtrace_python_sdk.utils.llm import ( get_langtrace_attributes, get_llm_request_attributes, @@ -14,20 +15,65 @@ from typing import Iterator +def capture_input_data(contents): + input_data = [] + + if isinstance(contents, list): + content_parts = [] + for content in contents: + if hasattr(content, 'parts'): + for part in content.parts: + if hasattr(part, 'text') and part.text: + content_parts.append({ + "type": "text", + "text": part.text + }) + if hasattr(part, 'inline_data') and part.inline_data: + content_parts.append({ + "type": "image_url", + "image_url": f"data:{part.inline_data.mime_type};base64,{base64.b64encode(part.inline_data.data).decode('utf-8')}" + }) + else: + if isinstance(content, str): + content_parts.append({ + "type": "text", + "text": content + }) + elif hasattr(content, 'text') and content.text: + content_parts.append({ + "type": "text", + "text": content.text + }) + elif hasattr(content, 'inline_data') and content.inline_data: + content_parts.append({ + "type": "image_url", + "image_url": f"data:{content.inline_data.mime_type};base64,{base64.b64encode(content.inline_data.data).decode('utf-8')}" + }) + else: + content_parts.append({ + "type": "text", + "text": content + }) + input_data.append({ + "role": "user", + "content": content_parts + }) + else: + input_data.append({ + "role": "user", + "content": contents + }) + + return input_data + def patch_google_genai(tracer: Tracer, version: str): def traced_method(wrapped, instance, args, kwargs): - prompt = [ - { - "role": "user", - "content": kwargs["contents"], - } - ] span_attributes = { **get_langtrace_attributes( service_provider="google_genai", version=version ), - **get_llm_request_attributes(kwargs=kwargs, prompts=prompt), + **get_llm_request_attributes(kwargs=kwargs, prompts=capture_input_data(kwargs["contents"])), } with tracer.start_as_current_span( name="google.genai.generate_content", diff --git a/src/langtrace_python_sdk/version.py b/src/langtrace_python_sdk/version.py index 24321519..91d803c2 100644 --- a/src/langtrace_python_sdk/version.py +++ b/src/langtrace_python_sdk/version.py @@ -1 +1 @@ -__version__ = "3.8.17" +__version__ = "3.8.18" From cc95a5ab897d7575620ffab9f9ea1430c987f068 Mon Sep 17 00:00:00 2001 From: obinnascale3 <109410793+obinnascale3@users.noreply.github.com> Date: Thu, 5 Jun 2025 17:02:17 +0100 Subject: [PATCH 2/2] Obinna/fix awsbedrock streaming response (#538) * fix aws bedrock streaming bug * bump version * add deprecated dependency * restrict current pinecone instrumentation to v6.0.2 * hard code boto3 dependency version --- pyproject.toml | 5 +++-- .../instrumentation/aws_bedrock/patch.py | 9 ++++++--- .../instrumentation/pinecone/instrumentation.py | 2 +- src/langtrace_python_sdk/version.py | 2 +- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index b1bf393d..260311b2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,8 +32,9 @@ dependencies = [ "transformers>=4.11.3", "sentry-sdk>=2.14.0", "ujson>=5.10.0", - "boto3", + "boto3==1.38.0", "setuptools", + "Deprecated==1.2.18", ] requires-python = ">=3.9" @@ -47,7 +48,7 @@ dev = [ "qdrant-client", "graphlit-client", "python-dotenv", - "pinecone", + "pinecone>=3.1.0,<=6.0.2", "langchain", "langchain-community", "langchain-openai", diff --git a/src/langtrace_python_sdk/instrumentation/aws_bedrock/patch.py b/src/langtrace_python_sdk/instrumentation/aws_bedrock/patch.py index 2f354d86..df938372 100644 --- a/src/langtrace_python_sdk/instrumentation/aws_bedrock/patch.py +++ b/src/langtrace_python_sdk/instrumentation/aws_bedrock/patch.py @@ -17,6 +17,7 @@ import json from wrapt import ObjectProxy +from itertools import tee from .stream_body_wrapper import BufferedStreamBody from functools import wraps from langtrace.trace_attributes import ( @@ -128,7 +129,9 @@ def traced_method(*args, **kwargs): response = original_method(*args, **kwargs) if span.is_recording(): - set_span_streaming_response(span, response) + stream1, stream2 = tee(response["stream"]) + set_span_streaming_response(span, stream1) + response["stream"] = stream2 return response return traced_method @@ -442,10 +445,10 @@ def _set_response_attributes(span, kwargs, result): ) -def set_span_streaming_response(span, response): +def set_span_streaming_response(span, response_stream): streaming_response = "" role = None - for event in response["stream"]: + for event in response_stream: if "messageStart" in event: role = event["messageStart"]["role"] elif "contentBlockDelta" in event: diff --git a/src/langtrace_python_sdk/instrumentation/pinecone/instrumentation.py b/src/langtrace_python_sdk/instrumentation/pinecone/instrumentation.py index 7608e901..8ad3f27b 100644 --- a/src/langtrace_python_sdk/instrumentation/pinecone/instrumentation.py +++ b/src/langtrace_python_sdk/instrumentation/pinecone/instrumentation.py @@ -33,7 +33,7 @@ class PineconeInstrumentation(BaseInstrumentor): The PineconeInstrumentation class represents the Pinecone instrumentation""" def instrumentation_dependencies(self) -> Collection[str]: - return ["pinecone >= 3.1.0"] + return ["pinecone >= 3.1.0", "pinecone <= 6.0.2"] def _instrument(self, **kwargs): tracer_provider = kwargs.get("tracer_provider") diff --git a/src/langtrace_python_sdk/version.py b/src/langtrace_python_sdk/version.py index 91d803c2..c10bada7 100644 --- a/src/langtrace_python_sdk/version.py +++ b/src/langtrace_python_sdk/version.py @@ -1 +1 @@ -__version__ = "3.8.18" +__version__ = "3.8.19"