@@ -1353,3 +1353,91 @@ def test_cached_token_usage():
13531353 )
13541354 < 0.0001
13551355 )
1356+
1357+
1358+ def test_langchain_automatic_observation_types ():
1359+ """Test that LangChain components automatically get correct observation types:
1360+ AGENT, TOOL, GENERATION, RETRIEVER, CHAIN"""
1361+ langfuse = Langfuse ()
1362+
1363+ with langfuse .start_as_current_span (name = "observation_types_test_agent" ) as span :
1364+ trace_id = span .trace_id
1365+ handler = CallbackHandler ()
1366+
1367+ from langchain .agents import AgentExecutor , create_react_agent
1368+ from langchain .tools import tool
1369+
1370+ # for type TOOL
1371+ @tool
1372+ def test_tool (x : str ) -> str :
1373+ """Process input string."""
1374+ return f"processed { x } "
1375+
1376+ # for type GENERATION
1377+ llm = ChatOpenAI (temperature = 0 )
1378+ tools = [test_tool ]
1379+
1380+ prompt = PromptTemplate .from_template ("""
1381+ Answer: {input}
1382+
1383+ Tools: {tools}
1384+ Tool names: {tool_names}
1385+
1386+ Question: {input}
1387+ {agent_scratchpad}
1388+ """ )
1389+
1390+ # for type AGENT
1391+ agent = create_react_agent (llm , tools , prompt )
1392+ agent_executor = AgentExecutor (
1393+ agent = agent , tools = tools , handle_parsing_errors = True , max_iterations = 1
1394+ )
1395+
1396+ try :
1397+ agent_executor .invoke ({"input" : "hello" }, {"callbacks" : [handler ]})
1398+ except Exception :
1399+ pass
1400+
1401+ try :
1402+ test_tool .invoke ("simple input" , {"callbacks" : [handler ]})
1403+ except Exception :
1404+ pass
1405+
1406+ from langchain_core .prompts import PromptTemplate as CorePromptTemplate
1407+
1408+ # for type CHAIN
1409+ chain_prompt = CorePromptTemplate .from_template ("Answer: {question}" )
1410+ simple_chain = chain_prompt | llm
1411+
1412+ try :
1413+ simple_chain .invoke ({"question" : "hi" }, {"callbacks" : [handler ]})
1414+ except Exception :
1415+ pass
1416+
1417+ # for type RETRIEVER
1418+ from langchain_core .retrievers import BaseRetriever
1419+ from langchain_core .documents import Document
1420+
1421+ class SimpleRetriever (BaseRetriever ):
1422+ def _get_relevant_documents (self , query : str , * , run_manager ):
1423+ return [Document (page_content = "test doc" )]
1424+
1425+ try :
1426+ SimpleRetriever ().invoke ("query" , {"callbacks" : [handler ]})
1427+ except Exception :
1428+ pass
1429+
1430+ handler .client .flush ()
1431+ trace = get_api ().trace .get (trace_id )
1432+
1433+ # Validate all expected observation types are created
1434+ types_found = {obs .type for obs in trace .observations }
1435+ expected_types = {"AGENT" , "TOOL" , "CHAIN" , "RETRIEVER" , "GENERATION" }
1436+
1437+ for obs_type in expected_types :
1438+ obs_count = len ([obs for obs in trace .observations if obs .type == obs_type ])
1439+ assert obs_count > 0 , f"Expected { obs_type } observations, found { obs_count } "
1440+
1441+ assert expected_types .issubset (
1442+ types_found
1443+ ), f"Missing types: { expected_types - types_found } "
0 commit comments