|
6 | 6 | from typing import Optional |
7 | 7 |
|
8 | 8 | import pytest |
9 | | -from langchain_core.prompts import ChatPromptTemplate |
10 | | -from langchain_openai import ChatOpenAI |
11 | 9 | from opentelemetry import trace |
12 | 10 |
|
13 | 11 | from langfuse import Langfuse, get_client, observe, propagate_attributes |
14 | 12 | from langfuse._client.environment_variables import LANGFUSE_PUBLIC_KEY |
15 | 13 | from langfuse._client.resource_manager import LangfuseResourceManager |
16 | | -from langfuse.langchain import CallbackHandler |
17 | 14 | from langfuse.media import LangfuseMedia |
18 | 15 | from tests.support.utils import ( |
19 | 16 | get_observations, |
@@ -389,88 +386,6 @@ def level_1_function(*args, **kwargs): |
389 | 386 | assert level_3_observation.total_cost > 0 |
390 | 387 |
|
391 | 388 |
|
392 | | -def test_decorators_langchain(): |
393 | | - mock_name = "test_decorators_langchain" |
394 | | - langfuse = get_client() |
395 | | - mock_trace_id = langfuse.create_trace_id() |
396 | | - |
397 | | - @observe() |
398 | | - def langchain_operations(*args, **kwargs): |
399 | | - # Get langfuse callback handler for LangChain |
400 | | - handler = CallbackHandler() |
401 | | - prompt = ChatPromptTemplate.from_template("tell me a short joke about {topic}") |
402 | | - model = ChatOpenAI(temperature=0) |
403 | | - |
404 | | - chain = prompt | model |
405 | | - |
406 | | - return chain.invoke( |
407 | | - {"topic": kwargs["topic"]}, |
408 | | - config={ |
409 | | - "callbacks": [handler], |
410 | | - }, |
411 | | - ) |
412 | | - |
413 | | - @observe() |
414 | | - def level_3_function(*args, **kwargs): |
415 | | - langfuse.update_current_span(metadata=mock_metadata) |
416 | | - langfuse.update_current_span(metadata=mock_deep_metadata) |
417 | | - return langchain_operations(*args, **kwargs) |
418 | | - |
419 | | - @observe() |
420 | | - def level_2_function(*args, **kwargs): |
421 | | - langfuse.update_current_span(metadata=mock_metadata) |
422 | | - |
423 | | - return level_3_function(*args, **kwargs) |
424 | | - |
425 | | - @observe() |
426 | | - def level_1_function(*args, **kwargs): |
427 | | - return level_2_function(*args, **kwargs) |
428 | | - |
429 | | - with propagate_attributes(session_id=mock_session_id, trace_name=mock_name): |
430 | | - level_1_function(topic="socks", langfuse_trace_id=mock_trace_id) |
431 | | - |
432 | | - langfuse.flush() |
433 | | - |
434 | | - trace_data = wait_for_trace_snapshot( |
435 | | - mock_trace_id, |
436 | | - is_result_ready=lambda trace: ( |
437 | | - trace.session_id == mock_session_id |
438 | | - and trace.name == mock_name |
439 | | - and { |
440 | | - "level_1_function", |
441 | | - "level_2_function", |
442 | | - "level_3_function", |
443 | | - "langchain_operations", |
444 | | - "ChatPromptTemplate", |
445 | | - }.issubset({observation.name for observation in trace.observations}) |
446 | | - ), |
447 | | - ) |
448 | | - assert len(trace_data.observations) > 2 |
449 | | - |
450 | | - # trace parameters if set anywhere in the call stack |
451 | | - assert trace_data.session_id == mock_session_id |
452 | | - assert trace_data.name == mock_name |
453 | | - |
454 | | - level_1_observation = _get_observation_by_name(trace_data, "level_1_function") |
455 | | - level_2_observation = _get_observation_by_name(trace_data, "level_2_function") |
456 | | - level_3_observation = _get_observation_by_name(trace_data, "level_3_function") |
457 | | - langchain_observation = _get_observation_by_name(trace_data, "langchain_operations") |
458 | | - prompt_observation = _get_observation_by_name(trace_data, "ChatPromptTemplate") |
459 | | - |
460 | | - assert level_1_observation.name == "level_1_function" |
461 | | - assert _is_descendant(trace_data, level_2_observation.id, level_1_observation.id) |
462 | | - assert level_2_observation.name == "level_2_function" |
463 | | - assert level_2_observation.metadata["key"] == mock_metadata["key"] |
464 | | - assert _is_descendant(trace_data, level_3_observation.id, level_2_observation.id) |
465 | | - assert level_3_observation.name == "level_3_function" |
466 | | - assert level_3_observation.metadata["key"] == mock_deep_metadata["key"] |
467 | | - assert _is_descendant(trace_data, langchain_observation.id, level_3_observation.id) |
468 | | - assert langchain_observation.name == "langchain_operations" |
469 | | - |
470 | | - # Check that LangChain components are captured |
471 | | - assert _is_descendant(trace_data, prompt_observation.id, langchain_observation.id) |
472 | | - |
473 | | - |
474 | 389 | def test_get_current_trace_url(): |
475 | 390 | langfuse = get_client() |
476 | 391 | mock_trace_id = langfuse.create_trace_id() |
@@ -860,105 +775,6 @@ async def main_async(**kwargs): |
860 | 775 | assert nested_observation.output == "Hello--, async --World!" |
861 | 776 |
|
862 | 777 |
|
863 | | -@pytest.mark.asyncio |
864 | | -async def test_async_nested_openai_chat_stream(): |
865 | | - from langfuse.openai import AsyncOpenAI |
866 | | - |
867 | | - mock_name = "test_async_nested_openai_chat_stream" |
868 | | - langfuse = get_client() |
869 | | - mock_trace_id = langfuse.create_trace_id() |
870 | | - mock_tags = ["tag1", "tag2"] |
871 | | - mock_session_id = "session-id-1" |
872 | | - mock_user_id = "user-id-1" |
873 | | - |
874 | | - @observe(capture_output=False) |
875 | | - async def level_2_function(): |
876 | | - gen = await AsyncOpenAI().chat.completions.create( |
877 | | - model="gpt-3.5-turbo", |
878 | | - messages=[{"role": "user", "content": "1 + 1 = "}], |
879 | | - temperature=0, |
880 | | - metadata={"someKey": "someResponse"}, |
881 | | - stream=True, |
882 | | - ) |
883 | | - |
884 | | - with propagate_attributes( |
885 | | - session_id=mock_session_id, |
886 | | - user_id=mock_user_id, |
887 | | - tags=mock_tags, |
888 | | - trace_name=mock_name, |
889 | | - ): |
890 | | - async for c in gen: |
891 | | - print(c) |
892 | | - |
893 | | - langfuse.update_current_span(metadata=mock_metadata) |
894 | | - |
895 | | - return "level_2" |
896 | | - |
897 | | - @observe() |
898 | | - async def level_1_function(*args, **kwargs): |
899 | | - await level_2_function() |
900 | | - |
901 | | - return "level_1" |
902 | | - |
903 | | - result = await level_1_function( |
904 | | - *mock_args, **mock_kwargs, langfuse_trace_id=mock_trace_id |
905 | | - ) |
906 | | - langfuse.flush() |
907 | | - |
908 | | - assert result == "level_1" # Wrapped function returns correctly |
909 | | - |
910 | | - # ID setting for span or trace |
911 | | - trace_data = wait_for_trace_snapshot( |
912 | | - mock_trace_id, |
913 | | - is_result_ready=lambda trace: ( |
914 | | - trace.session_id == mock_session_id |
915 | | - and trace.name == mock_name |
916 | | - and { |
917 | | - "level_1_function", |
918 | | - "level_2_function", |
919 | | - "OpenAI-generation", |
920 | | - }.issubset({observation.name for observation in trace.observations}) |
921 | | - ), |
922 | | - ) |
923 | | - assert len(trace_data.observations) >= 3 |
924 | | - |
925 | | - # trace parameters if set anywhere in the call stack |
926 | | - assert trace_data.session_id == mock_session_id |
927 | | - assert trace_data.name == mock_name |
928 | | - |
929 | | - level_1_observation = _get_observation_by_name(trace_data, "level_1_function") |
930 | | - level_2_observation = _get_observation_by_name(trace_data, "level_2_function") |
931 | | - level_3_observation = _get_observation_by_name(trace_data, "OpenAI-generation") |
932 | | - assert _is_descendant(trace_data, level_2_observation.id, level_1_observation.id) |
933 | | - assert _is_descendant(trace_data, level_3_observation.id, level_2_observation.id) |
934 | | - |
935 | | - assert level_2_observation.metadata["key"] == mock_metadata["key"] |
936 | | - |
937 | | - generation = level_3_observation |
938 | | - |
939 | | - assert generation.name == "OpenAI-generation" |
940 | | - assert generation.metadata["someKey"] == "someResponse" |
941 | | - assert generation.input == [{"content": "1 + 1 = ", "role": "user"}] |
942 | | - assert generation.type == "GENERATION" |
943 | | - assert "gpt-3.5-turbo" in generation.model |
944 | | - assert generation.start_time is not None |
945 | | - assert generation.end_time is not None |
946 | | - assert generation.start_time < generation.end_time |
947 | | - assert generation.model_parameters == { |
948 | | - "service_tier": "default", |
949 | | - "temperature": 0, |
950 | | - "top_p": 1, |
951 | | - "frequency_penalty": 0, |
952 | | - "max_tokens": "Infinity", |
953 | | - "presence_penalty": 0, |
954 | | - } |
955 | | - assert generation.usage_details["input"] is not None |
956 | | - assert generation.usage_details["output"] is not None |
957 | | - assert generation.usage_details["total"] is not None |
958 | | - print(generation) |
959 | | - assert generation.output == "2" |
960 | | - |
961 | | - |
962 | 778 | def test_generator_as_function_input(): |
963 | 779 | langfuse = get_client() |
964 | 780 | mock_trace_id = langfuse.create_trace_id() |
|
0 commit comments