diff --git a/.riot/requirements/159ccae.txt b/.riot/requirements/159ccae.txt new file mode 100644 index 00000000000..3a2a4b6d64c --- /dev/null +++ b/.riot/requirements/159ccae.txt @@ -0,0 +1,106 @@ +# +# This file is autogenerated by pip-compile with Python 3.12 +# by the following command: +# +# pip-compile --allow-unsafe --no-annotate .riot/requirements/159ccae.in +# +ai21==3.0.1 +ai21-tokenizer==0.12.0 +aiohappyeyeballs==2.4.4 +aiohttp==3.10.11 +aiosignal==1.3.2 +annotated-types==0.7.0 +anthropic==0.45.2 +anyio==4.8.0 +attrs==25.1.0 +boto3==1.36.13 +botocore==1.36.13 +certifi==2025.1.31 +charset-normalizer==3.4.1 +cohere==5.13.11 +coverage[toml]==7.6.10 +dataclasses-json==0.6.7 +defusedxml==0.7.1 +distro==1.9.0 +exceptiongroup==1.2.2 +fastavro==1.10.0 +filelock==3.17.0 +frozenlist==1.5.0 +fsspec==2025.2.0 +greenlet==3.0.3 +h11==0.14.0 +httpcore==1.0.7 +httpx==0.27.2 +httpx-sse==0.4.0 +huggingface-hub==0.28.1 +hypothesis==6.45.0 +idna==3.10 +iniconfig==2.0.0 +jiter==0.8.2 +jmespath==1.0.1 +jsonpatch==1.33 +jsonpointer==3.0.0 +langchain==0.3.17 +langchain-anthropic==0.3.5 +langchain-aws==0.2.12 +langchain-cohere==0.4.2 +langchain-community==0.3.16 +langchain-core==0.3.33 +langchain-openai==0.3.3 +langchain-pinecone==0.2.2 +langchain-tests==0.3.10 +langchain-text-splitters==0.3.5 +langsmith==0.3.5 +marshmallow==3.26.1 +mock==5.1.0 +multidict==6.1.0 +mypy-extensions==1.0.0 +numexpr==2.8.5 +numpy==1.26.4 +openai==1.61.0 +opentracing==2.4.0 +orjson==3.10.15 +packaging==24.2 +pinecone==5.4.2 +pinecone-client==4.1.2 +pinecone-plugin-inference==3.1.0 +pinecone-plugin-interface==0.0.7 +pluggy==1.5.0 +propcache==0.2.1 +psutil==6.1.1 +pydantic==2.10.6 +pydantic-core==2.27.2 +pydantic-settings==2.7.1 +pytest==8.3.4 +pytest-asyncio==0.23.7 +pytest-cov==6.0.0 +pytest-mock==3.14.0 +pytest-randomly==3.10.1 +pytest-socket==0.7.0 +python-dateutil==2.9.0.post0 +python-dotenv==1.0.1 +pyyaml==6.0.2 +regex==2024.11.6 +requests==2.32.3 +requests-toolbelt==1.0.0 +respx==0.22.0 +s3transfer==0.11.2 +sentencepiece==0.2.0 +six==1.17.0 +sniffio==1.3.1 +sortedcontainers==2.4.0 +sqlalchemy==2.0.37 +syrupy==4.8.1 +tenacity==8.5.0 +tiktoken==0.8.0 +tokenizers==0.21.0 +tqdm==4.67.1 +types-pyyaml==6.0.12.20241230 +types-requests==2.32.0.20241016 +typing-extensions==4.12.2 +typing-inspect==0.9.0 +urllib3==2.3.0 +vcrpy==7.0.0 +wrapt==1.17.2 +yarl==1.18.3 +zstandard==0.23.0 diff --git a/.riot/requirements/a69ef68.txt b/.riot/requirements/a69ef68.txt new file mode 100644 index 00000000000..4c102d8742d --- /dev/null +++ b/.riot/requirements/a69ef68.txt @@ -0,0 +1,97 @@ +# +# This file is autogenerated by pip-compile with Python 3.12 +# by the following command: +# +# pip-compile --allow-unsafe --no-annotate .riot/requirements/a69ef68.in +# +ai21==3.0.1 +ai21-tokenizer==0.12.0 +aiohappyeyeballs==2.4.4 +aiohttp==3.11.11 +aiosignal==1.3.2 +annotated-types==0.7.0 +anthropic==0.26.0 +anyio==4.8.0 +attrs==25.1.0 +boto3==1.34.51 +botocore==1.34.51 +certifi==2025.1.31 +charset-normalizer==3.4.1 +cohere==5.13.11 +coverage[toml]==7.6.10 +dataclasses-json==0.6.7 +defusedxml==0.7.1 +distro==1.9.0 +exceptiongroup==1.2.2 +fastavro==1.10.0 +filelock==3.17.0 +frozenlist==1.5.0 +fsspec==2025.2.0 +greenlet==3.0.3 +h11==0.14.0 +httpcore==1.0.7 +httpx==0.27.2 +httpx-sse==0.4.0 +huggingface-hub==0.28.1 +hypothesis==6.45.0 +idna==3.10 +iniconfig==2.0.0 +jiter==0.8.2 +jmespath==1.0.1 +jsonpatch==1.33 +jsonpointer==3.0.0 +langchain==0.2.0 +langchain-anthropic==0.1.13 +langchain-aws==0.1.6 +langchain-cohere==0.1.8 +langchain-core==0.2.0 +langchain-openai==0.1.7 +langchain-pinecone==0.1.3 +langchain-text-splitters==0.2.1 +langsmith==0.1.147 +marshmallow==3.26.1 +mock==5.1.0 +multidict==6.1.0 +mypy-extensions==1.0.0 +numexpr==2.8.5 +numpy==1.26.4 +openai==1.61.0 +opentracing==2.4.0 +orjson==3.10.15 +packaging==23.2 +pinecone-client==5.0.1 +pinecone-plugin-inference==1.1.0 +pinecone-plugin-interface==0.0.7 +pluggy==1.5.0 +propcache==0.2.1 +psutil==6.1.1 +pydantic==2.10.6 +pydantic-core==2.27.2 +pytest==8.3.4 +pytest-asyncio==0.23.7 +pytest-cov==6.0.0 +pytest-mock==3.14.0 +pytest-randomly==3.10.1 +python-dateutil==2.9.0.post0 +pyyaml==6.0.2 +regex==2024.11.6 +requests==2.32.3 +requests-toolbelt==1.0.0 +respx==0.22.0 +s3transfer==0.10.4 +sentencepiece==0.2.0 +six==1.17.0 +sniffio==1.3.1 +sortedcontainers==2.4.0 +sqlalchemy==2.0.37 +tenacity==8.5.0 +tiktoken==0.8.0 +tokenizers==0.21.0 +tqdm==4.67.1 +types-requests==2.32.0.20241016 +typing-extensions==4.12.2 +typing-inspect==0.9.0 +urllib3==2.0.7 +vcrpy==7.0.0 +wrapt==1.17.2 +yarl==1.18.3 diff --git a/tests/contrib/langchain/test_langchain.py b/tests/contrib/langchain/test_langchain.py index 53678d64e0c..e557a543a35 100644 --- a/tests/contrib/langchain/test_langchain.py +++ b/tests/contrib/langchain/test_langchain.py @@ -1,3 +1,5 @@ +import os + import langchain import langchain.prompts # noqa: F401 import mock @@ -7,9 +9,6 @@ from tests.contrib.langchain.utils import get_request_vcr -# from tests.utils import flaky - - LANGCHAIN_VERSION = parse_version(langchain.__version__) IGNORE_FIELDS = [ @@ -69,25 +68,25 @@ def test_openai_llm_error(langchain, langchain_openai, openai_completion_error): llm.generate([12345, 123456]) -# @pytest.mark.skipif(LANGCHAIN_VERSION < (0, 2), reason="Requires separate cassette for langchain v0.1") -# @pytest.mark.snapshot -# def test_cohere_llm_sync(langchain_cohere, request_vcr): -# llm = langchain_cohere.llms.Cohere(cohere_api_key=os.getenv("COHERE_API_KEY", "")) -# with request_vcr.use_cassette("cohere_completion_sync.yaml"): -# llm.invoke("What is the secret Krabby Patty recipe?") +@pytest.mark.skipif(LANGCHAIN_VERSION < (0, 2), reason="Requires separate cassette for langchain v0.1") +@pytest.mark.snapshot +def test_cohere_llm_sync(langchain_cohere, request_vcr): + llm = langchain_cohere.llms.Cohere(cohere_api_key=os.getenv("COHERE_API_KEY", "")) + with request_vcr.use_cassette("cohere_completion_sync.yaml"): + llm.invoke("What is the secret Krabby Patty recipe?") -# @pytest.mark.skipif( -# LANGCHAIN_VERSION < (0, 2) or sys.version_info < (3, 10), -# reason="Requires separate cassette for langchain v0.1, Python 3.9", -# ) -# @pytest.mark.snapshot -# def test_ai21_llm_sync(langchain_community, request_vcr): -# if langchain_community is None: -# pytest.skip("langchain-community not installed which is required for this test.") -# llm = langchain_community.llms.AI21(ai21_api_key=os.getenv("AI21_API_KEY", "")) -# with request_vcr.use_cassette("ai21_completion_sync.yaml"): -# llm.invoke("Why does everyone in Bikini Bottom hate Plankton?") +@pytest.mark.skipif( + LANGCHAIN_VERSION < (0, 2) or sys.version_info < (3, 10), + reason="Requires separate cassette for langchain v0.1, Python 3.9", +) +@pytest.mark.snapshot +def test_ai21_llm_sync(langchain_community, request_vcr): + if langchain_community is None: + pytest.skip("langchain-community not installed which is required for this test.") + llm = langchain_community.llms.AI21(ai21_api_key=os.getenv("AI21_API_KEY", "")) + with request_vcr.use_cassette("ai21_completion_sync.yaml"): + llm.invoke("Why does everyone in Bikini Bottom hate Plankton?") @pytest.mark.snapshot(ignores=IGNORE_FIELDS) @@ -122,55 +121,54 @@ def test_openai_chat_model_sync_generate(langchain_openai, openai_chat_completio ) -# @flaky(until=1754218112, reason="Problematic test that needs fixing") -# @pytest.mark.snapshot(ignores=IGNORE_FIELDS) -# def test_openai_chat_model_vision_generate(langchain_openai, request_vcr): -# """ -# Test that input messages with nested contents are still tagged without error -# Regression test for https://github.com/DataDog/dd-trace-py/issues/8149. -# """ -# image_url = ( -# "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk" -# ".jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg" -# ) -# chat = langchain_openai.ChatOpenAI(model="gpt-4o", temperature=0, max_tokens=256) -# with request_vcr.use_cassette("openai_chat_completion_image_input_sync_generate.yaml"): -# chat.generate( -# [ -# [ -# langchain.schema.HumanMessage( -# content=[ -# {"type": "text", "text": "What’s in this image?"}, -# { -# "type": "image_url", -# "image_url": {"url": image_url}, -# }, -# ], -# ), -# ], -# ] -# ) - - -# @pytest.mark.asyncio -# @pytest.mark.snapshot(ignores=IGNORE_FIELDS) -# async def test_openai_chat_model_async_generate(langchain_openai, request_vcr): -# chat = langchain_openai.ChatOpenAI(temperature=0, max_tokens=256) -# with request_vcr.use_cassette("openai_chat_completion_async_generate.yaml"): -# await chat.agenerate( -# [ -# [ -# langchain.schema.SystemMessage(content="Respond like a frat boy."), -# langchain.schema.HumanMessage( -# content="Where's the nearest equinox gym from Hudson Yards manhattan?" -# ), -# ], -# [ -# langchain.schema.SystemMessage(content="Respond with a pirate accent."), -# langchain.schema.HumanMessage(content="How does one get to Bikini Bottom from New York?"), -# ], -# ] -# ) +@pytest.mark.snapshot(ignores=IGNORE_FIELDS) +def test_openai_chat_model_vision_generate(langchain_openai, request_vcr): + """ + Test that input messages with nested contents are still tagged without error + Regression test for https://github.com/DataDog/dd-trace-py/issues/8149. + """ + image_url = ( + "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk" + ".jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg" + ) + chat = langchain_openai.ChatOpenAI(model="gpt-4o", temperature=0, max_tokens=256) + with request_vcr.use_cassette("openai_chat_completion_image_input_sync_generate.yaml"): + chat.generate( + [ + [ + langchain.schema.HumanMessage( + content=[ + {"type": "text", "text": "What’s in this image?"}, + { + "type": "image_url", + "image_url": {"url": image_url}, + }, + ], + ), + ], + ] + ) + + +@pytest.mark.asyncio +@pytest.mark.snapshot(ignores=IGNORE_FIELDS) +async def test_openai_chat_model_async_generate(langchain_openai, request_vcr): + chat = langchain_openai.ChatOpenAI(temperature=0, max_tokens=256) + with request_vcr.use_cassette("openai_chat_completion_async_generate.yaml"): + await chat.agenerate( + [ + [ + langchain.schema.SystemMessage(content="Respond like a frat boy."), + langchain.schema.HumanMessage( + content="Where's the nearest equinox gym from Hudson Yards manhattan?" + ), + ], + [ + langchain.schema.SystemMessage(content="Respond with a pirate accent."), + langchain.schema.HumanMessage(content="How does one get to Bikini Bottom from New York?"), + ], + ] + ) @pytest.mark.snapshot @@ -196,25 +194,25 @@ def test_fake_embedding_document(langchain_community): embeddings.embed_documents(texts=["foo", "bar"]) -# @pytest.mark.snapshot -# def test_pinecone_vectorstore_similarity_search(langchain_openai, request_vcr): -# """ -# Test that calling a similarity search on a Pinecone vectorstore with langchain will -# result in a 2-span trace with a vectorstore span and underlying OpenAI embedding interface span. -# """ -# import langchain_pinecone -# import pinecone - -# with mock.patch("langchain_openai.OpenAIEmbeddings._get_len_safe_embeddings", return_value=[0.0] * 1536): -# with request_vcr.use_cassette("openai_pinecone_similarity_search.yaml"): -# pc = pinecone.Pinecone( -# api_key=os.getenv("PINECONE_API_KEY", ""), -# environment=os.getenv("PINECONE_ENV", ""), -# ) -# embed = langchain_openai.OpenAIEmbeddings(model="text-embedding-ada-002") -# index = pc.Index("langchain-retrieval") -# vectorstore = langchain_pinecone.PineconeVectorStore(index, embed, "text") -# vectorstore.similarity_search("Who was Alan Turing?", 1) +@pytest.mark.snapshot +def test_pinecone_vectorstore_similarity_search(langchain_openai, request_vcr): + """ + Test that calling a similarity search on a Pinecone vectorstore with langchain will + result in a 2-span trace with a vectorstore span and underlying OpenAI embedding interface span. + """ + import langchain_pinecone + import pinecone + + with mock.patch("langchain_openai.OpenAIEmbeddings._get_len_safe_embeddings", return_value=[0.0] * 1536): + with request_vcr.use_cassette("openai_pinecone_similarity_search.yaml"): + pc = pinecone.Pinecone( + api_key=os.getenv("PINECONE_API_KEY", ""), + environment=os.getenv("PINECONE_ENV", ""), + ) + embed = langchain_openai.OpenAIEmbeddings(model="text-embedding-ada-002") + index = pc.Index("langchain-retrieval") + vectorstore = langchain_pinecone.PineconeVectorStore(index, embed, "text") + vectorstore.similarity_search("Who was Alan Turing?", 1) @pytest.mark.snapshot(ignores=IGNORE_FIELDS) diff --git a/tests/snapshots/tests.contrib.langchain.test_langchain.test_openai_chat_model_vision_generate.json b/tests/snapshots/tests.contrib.langchain.test_langchain.test_openai_chat_model_vision_generate.json new file mode 100644 index 00000000000..033314cedc1 --- /dev/null +++ b/tests/snapshots/tests.contrib.langchain.test_langchain.test_openai_chat_model_vision_generate.json @@ -0,0 +1,43 @@ +[[ + { + "name": "langchain.request", + "service": "tests.contrib.langchain", + "resource": "langchain_openai.chat_models.base.ChatOpenAI", + "trace_id": 0, + "span_id": 1, + "parent_id": 0, + "type": "", + "error": 0, + "meta": { + "_dd.p.dm": "-0", + "_dd.p.tid": "67a29bfa00000000", + "langchain.request.api_key": "...key>", + "langchain.request.messages.0.0.content": "[{'type': 'text', 'text': 'What\u2019s in this image?'}, {'type': 'image_url', 'image_url': {'url': 'https://upload.wikimedia.org/wik...", + "langchain.request.messages.0.0.message_type": "HumanMessage", + "langchain.request.model": "gpt-4o", + "langchain.request.openai.parameters.max_tokens": "256", + "langchain.request.openai.parameters.model": "gpt-4o", + "langchain.request.openai.parameters.model_name": "gpt-4o", + "langchain.request.openai.parameters.n": "1", + "langchain.request.openai.parameters.stream": "False", + "langchain.request.openai.parameters.temperature": "0.0", + "langchain.request.provider": "openai", + "langchain.request.type": "chat_model", + "langchain.response.completions.0.0.content": "The image shows a scenic landscape with a wooden boardwalk path leading through a lush green field. The sky is blue with scatter...", + "langchain.response.completions.0.0.message_type": "AIMessage", + "language": "python", + "runtime-id": "d54bd858212b42c686edd68387960fe9" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1, + "_dd.tracer_kr": 1.0, + "_sampling_priority_v1": 1, + "langchain.tokens.completion_tokens": 56, + "langchain.tokens.prompt_tokens": 1151, + "langchain.tokens.total_tokens": 1207, + "process_id": 65725 + }, + "duration": 25267000, + "start": 1738710010339445000 + }]] diff --git a/tests/snapshots/tests.contrib.langchain.test_langchain.test_pinecone_vectorstore_similarity_search.json b/tests/snapshots/tests.contrib.langchain.test_langchain.test_pinecone_vectorstore_similarity_search.json new file mode 100644 index 00000000000..96d290737e4 --- /dev/null +++ b/tests/snapshots/tests.contrib.langchain.test_langchain.test_pinecone_vectorstore_similarity_search.json @@ -0,0 +1,61 @@ +[[ + { + "name": "langchain.request", + "service": "tests.contrib.langchain", + "resource": "langchain_pinecone.vectorstores.PineconeVectorStore", + "trace_id": 0, + "span_id": 1, + "parent_id": 0, + "type": "", + "error": 0, + "meta": { + "_dd.p.dm": "-0", + "_dd.p.tid": "67a2982700000000", + "langchain.request.api_key": "", + "langchain.request.k": "1", + "langchain.request.provider": "pineconevectorstore", + "langchain.request.query": "Who was Alan Turing?", + "langchain.request.type": "similarity_search", + "langchain.response.document.0.metadata.chunk": "1.0", + "langchain.response.document.0.metadata.source": "https://simple.wikipedia.org/wiki/Alan%20Turing", + "langchain.response.document.0.metadata.title": "Alan Turing", + "langchain.response.document.0.metadata.wiki-id": "13", + "langchain.response.document.0.page_content": "A brilliant mathematician and cryptographer Alan was to become the founder of modern-day computer science and artificial intelli...", + "language": "python", + "runtime-id": "afffb6f62c04469c8e03e8d823a886b7" + }, + "metrics": { + "_dd.measured": 1, + "_dd.top_level": 1, + "_dd.tracer_kr": 1.0, + "_sampling_priority_v1": 1, + "langchain.response.document_count": 1, + "process_id": 57708 + }, + "duration": 1832000, + "start": 1738709031164723000 + }, + { + "name": "langchain.request", + "service": "tests.contrib.langchain", + "resource": "langchain_openai.embeddings.base.OpenAIEmbeddings", + "trace_id": 0, + "span_id": 2, + "parent_id": 1, + "type": "", + "error": 0, + "meta": { + "langchain.request.api_key": "...key>", + "langchain.request.inputs.0.text": "Who was Alan Turing?", + "langchain.request.model": "text-embedding-ada-002", + "langchain.request.provider": "openai", + "langchain.request.type": "embedding" + }, + "metrics": { + "_dd.measured": 1, + "langchain.request.input_count": 1, + "langchain.response.outputs.embedding_length": 1536 + }, + "duration": 467000, + "start": 1738709031164817000 + }]]