Skip to content

Commit 3c7adea

Browse files
simplify tests
1 parent a165333 commit 3c7adea

1 file changed

Lines changed: 178 additions & 117 deletions

File tree

tests/integrations/langchain/test_langchain.py

Lines changed: 178 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -1026,54 +1026,29 @@ def test_langchain_openai_tools_agent(
10261026
assert "get_word_length" in tools_data
10271027

10281028

1029-
@pytest.mark.parametrize(
1030-
"send_default_pii, include_prompts",
1031-
[
1032-
(True, True),
1033-
(True, False),
1034-
(False, True),
1035-
(False, False),
1036-
],
1037-
)
1038-
@pytest.mark.parametrize(
1039-
"system_instructions_content",
1040-
[
1041-
"You are very powerful assistant, but don't know current events",
1042-
["You are a helpful assistant.", "Be concise and clear."],
1043-
[
1044-
{"type": "text", "text": "You are a helpful assistant."},
1045-
{"type": "text", "text": "Be concise and clear."},
1046-
],
1047-
],
1048-
ids=["string", "list", "blocks"],
1049-
)
10501029
def test_langchain_openai_tools_agent_with_config(
10511030
sentry_init,
10521031
capture_events,
1053-
send_default_pii,
1054-
include_prompts,
1055-
system_instructions_content,
1056-
request,
10571032
get_model_response,
10581033
server_side_event_chunks,
10591034
streaming_chat_completions_model_responses,
10601035
):
10611036
sentry_init(
10621037
integrations=[
10631038
LangchainIntegration(
1064-
include_prompts=include_prompts,
1039+
include_prompts=True,
10651040
)
10661041
],
10671042
traces_sample_rate=1.0,
1068-
send_default_pii=send_default_pii,
1043+
send_default_pii=True,
10691044
)
10701045
events = capture_events()
10711046

10721047
prompt = ChatPromptTemplate.from_messages(
10731048
[
10741049
(
10751050
"system",
1076-
system_instructions_content,
1051+
"You are very powerful assistant, but don't know current events",
10771052
),
10781053
("user", "{input}"),
10791054
MessagesPlaceholder(variable_name="agent_scratchpad"),
@@ -1130,25 +1105,12 @@ def test_langchain_openai_tools_agent_with_config(
11301105
@pytest.mark.parametrize(
11311106
"send_default_pii, include_prompts",
11321107
[
1133-
(True, True),
11341108
(True, False),
11351109
(False, True),
11361110
(False, False),
11371111
],
11381112
)
1139-
@pytest.mark.parametrize(
1140-
"system_instructions_content",
1141-
[
1142-
"You are very powerful assistant, but don't know current events",
1143-
["You are a helpful assistant.", "Be concise and clear."],
1144-
[
1145-
{"type": "text", "text": "You are a helpful assistant."},
1146-
{"type": "text", "text": "Be concise and clear."},
1147-
],
1148-
],
1149-
ids=["string", "list", "blocks"],
1150-
)
1151-
def test_langchain_openai_tools_agent_stream(
1113+
def test_langchain_openai_tools_agent_stream_no_prompts(
11521114
sentry_init,
11531115
capture_events,
11541116
send_default_pii,
@@ -1251,68 +1213,24 @@ def test_langchain_openai_tools_agent_stream(
12511213
assert chat_spans[1]["data"]["gen_ai.usage.output_tokens"] == 28
12521214
assert chat_spans[1]["data"]["gen_ai.usage.total_tokens"] == 117
12531215

1254-
if send_default_pii and include_prompts:
1255-
assert "5" in chat_spans[0]["data"][SPANDATA.GEN_AI_RESPONSE_TEXT]
1256-
assert "word" in tool_exec_span["data"][SPANDATA.GEN_AI_TOOL_INPUT]
1257-
assert 5 == int(tool_exec_span["data"][SPANDATA.GEN_AI_TOOL_OUTPUT])
1258-
1259-
param_id = request.node.callspec.id
1260-
if "string" in param_id:
1261-
assert [
1262-
{
1263-
"type": "text",
1264-
"content": "You are very powerful assistant, but don't know current events",
1265-
}
1266-
] == json.loads(chat_spans[0]["data"][SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS])
1267-
else:
1268-
assert [
1269-
{
1270-
"type": "text",
1271-
"content": "You are a helpful assistant.",
1272-
},
1273-
{
1274-
"type": "text",
1275-
"content": "Be concise and clear.",
1276-
},
1277-
] == json.loads(chat_spans[0]["data"][SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS])
1278-
1279-
assert "5" in chat_spans[1]["data"][SPANDATA.GEN_AI_RESPONSE_TEXT]
1280-
1281-
# Verify tool calls are recorded when PII is enabled
1282-
assert SPANDATA.GEN_AI_RESPONSE_TOOL_CALLS in chat_spans[0].get("data", {}), (
1283-
"Tool calls should be recorded when send_default_pii=True and include_prompts=True"
1284-
)
1285-
tool_calls_data = chat_spans[0]["data"][SPANDATA.GEN_AI_RESPONSE_TOOL_CALLS]
1286-
assert isinstance(tool_calls_data, (list, str)) # Could be serialized
1287-
if isinstance(tool_calls_data, str):
1288-
assert "get_word_length" in tool_calls_data
1289-
elif isinstance(tool_calls_data, list) and len(tool_calls_data) > 0:
1290-
# Check if tool calls contain expected function name
1291-
tool_call_str = str(tool_calls_data)
1292-
assert "get_word_length" in tool_call_str
1293-
else:
1294-
assert SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS not in chat_spans[0].get("data", {})
1295-
assert SPANDATA.GEN_AI_REQUEST_MESSAGES not in chat_spans[0].get("data", {})
1296-
assert SPANDATA.GEN_AI_RESPONSE_TEXT not in chat_spans[0].get("data", {})
1297-
assert SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS not in chat_spans[1].get("data", {})
1298-
assert SPANDATA.GEN_AI_REQUEST_MESSAGES not in chat_spans[1].get("data", {})
1299-
assert SPANDATA.GEN_AI_RESPONSE_TEXT not in chat_spans[1].get("data", {})
1300-
assert SPANDATA.GEN_AI_TOOL_INPUT not in tool_exec_span.get("data", {})
1301-
assert SPANDATA.GEN_AI_TOOL_OUTPUT not in tool_exec_span.get("data", {})
1216+
assert SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS not in chat_spans[0].get("data", {})
1217+
assert SPANDATA.GEN_AI_REQUEST_MESSAGES not in chat_spans[0].get("data", {})
1218+
assert SPANDATA.GEN_AI_RESPONSE_TEXT not in chat_spans[0].get("data", {})
1219+
assert SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS not in chat_spans[1].get("data", {})
1220+
assert SPANDATA.GEN_AI_REQUEST_MESSAGES not in chat_spans[1].get("data", {})
1221+
assert SPANDATA.GEN_AI_RESPONSE_TEXT not in chat_spans[1].get("data", {})
1222+
assert SPANDATA.GEN_AI_TOOL_INPUT not in tool_exec_span.get("data", {})
1223+
assert SPANDATA.GEN_AI_TOOL_OUTPUT not in tool_exec_span.get("data", {})
13021224

1303-
# Verify tool calls are NOT recorded when PII is disabled
1304-
assert SPANDATA.GEN_AI_RESPONSE_TOOL_CALLS not in chat_spans[0].get(
1305-
"data", {}
1306-
), (
1307-
f"Tool calls should NOT be recorded when send_default_pii={send_default_pii} "
1308-
f"and include_prompts={include_prompts}"
1309-
)
1310-
assert SPANDATA.GEN_AI_RESPONSE_TOOL_CALLS not in chat_spans[1].get(
1311-
"data", {}
1312-
), (
1313-
f"Tool calls should NOT be recorded when send_default_pii={send_default_pii} "
1314-
f"and include_prompts={include_prompts}"
1315-
)
1225+
# Verify tool calls are NOT recorded when PII is disabled
1226+
assert SPANDATA.GEN_AI_RESPONSE_TOOL_CALLS not in chat_spans[0].get("data", {}), (
1227+
f"Tool calls should NOT be recorded when send_default_pii={send_default_pii} "
1228+
f"and include_prompts={include_prompts}"
1229+
)
1230+
assert SPANDATA.GEN_AI_RESPONSE_TOOL_CALLS not in chat_spans[1].get("data", {}), (
1231+
f"Tool calls should NOT be recorded when send_default_pii={send_default_pii} "
1232+
f"and include_prompts={include_prompts}"
1233+
)
13161234

13171235
# Verify finish_reasons is always an array of strings
13181236
assert chat_spans[0]["data"][SPANDATA.GEN_AI_RESPONSE_FINISH_REASONS] == [
@@ -1329,15 +1247,6 @@ def test_langchain_openai_tools_agent_stream(
13291247
assert "get_word_length" in tools_data
13301248

13311249

1332-
@pytest.mark.parametrize(
1333-
"send_default_pii, include_prompts",
1334-
[
1335-
(True, True),
1336-
(True, False),
1337-
(False, True),
1338-
(False, False),
1339-
],
1340-
)
13411250
@pytest.mark.parametrize(
13421251
"system_instructions_content",
13431252
[
@@ -1350,11 +1259,9 @@ def test_langchain_openai_tools_agent_stream(
13501259
],
13511260
ids=["string", "list", "blocks"],
13521261
)
1353-
def test_langchain_openai_tools_agent_stream_with_config(
1262+
def test_langchain_openai_tools_agent_stream(
13541263
sentry_init,
13551264
capture_events,
1356-
send_default_pii,
1357-
include_prompts,
13581265
system_instructions_content,
13591266
request,
13601267
get_model_response,
@@ -1364,11 +1271,11 @@ def test_langchain_openai_tools_agent_stream_with_config(
13641271
sentry_init(
13651272
integrations=[
13661273
LangchainIntegration(
1367-
include_prompts=include_prompts,
1274+
include_prompts=True,
13681275
)
13691276
],
13701277
traces_sample_rate=1.0,
1371-
send_default_pii=send_default_pii,
1278+
send_default_pii=True,
13721279
)
13731280
events = capture_events()
13741281

@@ -1399,6 +1306,160 @@ def test_langchain_openai_tools_agent_stream_with_config(
13991306
)
14001307
)
14011308

1309+
llm = ChatOpenAI(
1310+
model_name="gpt-3.5-turbo",
1311+
temperature=0,
1312+
openai_api_key="badkey",
1313+
)
1314+
agent = create_openai_tools_agent(llm, [get_word_length], prompt)
1315+
1316+
agent_executor = AgentExecutor(agent=agent, tools=[get_word_length], verbose=True)
1317+
1318+
with patch.object(
1319+
llm.client._client._client,
1320+
"send",
1321+
side_effect=[tool_response, final_response],
1322+
) as _:
1323+
with start_transaction():
1324+
list(
1325+
agent_executor.stream(
1326+
{"input": "How many letters in the word eudca"},
1327+
{"run_name": "my-snazzy-pipeline"},
1328+
)
1329+
)
1330+
1331+
tx = events[0]
1332+
assert tx["type"] == "transaction"
1333+
assert tx["contexts"]["trace"]["origin"] == "manual"
1334+
1335+
invoke_agent_span = next(x for x in tx["spans"] if x["op"] == "gen_ai.invoke_agent")
1336+
chat_spans = list(x for x in tx["spans"] if x["op"] == "gen_ai.chat")
1337+
tool_exec_span = next(x for x in tx["spans"] if x["op"] == "gen_ai.execute_tool")
1338+
1339+
assert len(chat_spans) == 2
1340+
1341+
assert invoke_agent_span["origin"] == "auto.ai.langchain"
1342+
assert chat_spans[0]["origin"] == "auto.ai.langchain"
1343+
assert chat_spans[1]["origin"] == "auto.ai.langchain"
1344+
assert tool_exec_span["origin"] == "auto.ai.langchain"
1345+
1346+
assert invoke_agent_span["data"]["gen_ai.function_id"] == "my-snazzy-pipeline"
1347+
1348+
# We can't guarantee anything about the "shape" of the langchain execution graph
1349+
assert len(list(x for x in tx["spans"] if x["op"] == "gen_ai.chat")) > 0
1350+
1351+
# Token usage is only available in newer versions of langchain (v0.2+)
1352+
# where usage_metadata is supported on AIMessageChunk
1353+
if "gen_ai.usage.input_tokens" in chat_spans[0]["data"]:
1354+
assert chat_spans[0]["data"]["gen_ai.usage.input_tokens"] == 142
1355+
assert chat_spans[0]["data"]["gen_ai.usage.output_tokens"] == 50
1356+
assert chat_spans[0]["data"]["gen_ai.usage.total_tokens"] == 192
1357+
1358+
if "gen_ai.usage.input_tokens" in chat_spans[1]["data"]:
1359+
assert chat_spans[1]["data"]["gen_ai.usage.input_tokens"] == 89
1360+
assert chat_spans[1]["data"]["gen_ai.usage.output_tokens"] == 28
1361+
assert chat_spans[1]["data"]["gen_ai.usage.total_tokens"] == 117
1362+
1363+
assert "5" in chat_spans[0]["data"][SPANDATA.GEN_AI_RESPONSE_TEXT]
1364+
assert "word" in tool_exec_span["data"][SPANDATA.GEN_AI_TOOL_INPUT]
1365+
assert 5 == int(tool_exec_span["data"][SPANDATA.GEN_AI_TOOL_OUTPUT])
1366+
1367+
param_id = request.node.callspec.id
1368+
if "string" in param_id:
1369+
assert [
1370+
{
1371+
"type": "text",
1372+
"content": "You are very powerful assistant, but don't know current events",
1373+
}
1374+
] == json.loads(chat_spans[0]["data"][SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS])
1375+
else:
1376+
assert [
1377+
{
1378+
"type": "text",
1379+
"content": "You are a helpful assistant.",
1380+
},
1381+
{
1382+
"type": "text",
1383+
"content": "Be concise and clear.",
1384+
},
1385+
] == json.loads(chat_spans[0]["data"][SPANDATA.GEN_AI_SYSTEM_INSTRUCTIONS])
1386+
1387+
assert "5" in chat_spans[1]["data"][SPANDATA.GEN_AI_RESPONSE_TEXT]
1388+
1389+
# Verify tool calls are recorded when PII is enabled
1390+
assert SPANDATA.GEN_AI_RESPONSE_TOOL_CALLS in chat_spans[0].get("data", {}), (
1391+
"Tool calls should be recorded when send_default_pii=True and include_prompts=True"
1392+
)
1393+
tool_calls_data = chat_spans[0]["data"][SPANDATA.GEN_AI_RESPONSE_TOOL_CALLS]
1394+
assert isinstance(tool_calls_data, (list, str)) # Could be serialized
1395+
if isinstance(tool_calls_data, str):
1396+
assert "get_word_length" in tool_calls_data
1397+
elif isinstance(tool_calls_data, list) and len(tool_calls_data) > 0:
1398+
# Check if tool calls contain expected function name
1399+
tool_call_str = str(tool_calls_data)
1400+
assert "get_word_length" in tool_call_str
1401+
1402+
# Verify finish_reasons is always an array of strings
1403+
assert chat_spans[0]["data"][SPANDATA.GEN_AI_RESPONSE_FINISH_REASONS] == [
1404+
"function_call"
1405+
]
1406+
assert chat_spans[1]["data"][SPANDATA.GEN_AI_RESPONSE_FINISH_REASONS] == ["stop"]
1407+
1408+
# Verify that available tools are always recorded regardless of PII settings
1409+
for chat_span in chat_spans:
1410+
tools_data = chat_span["data"][SPANDATA.GEN_AI_REQUEST_AVAILABLE_TOOLS]
1411+
assert tools_data is not None, (
1412+
"Available tools should always be recorded regardless of PII settings"
1413+
)
1414+
assert "get_word_length" in tools_data
1415+
1416+
1417+
def test_langchain_openai_tools_agent_stream_with_config(
1418+
sentry_init,
1419+
capture_events,
1420+
system_instructions_content,
1421+
get_model_response,
1422+
server_side_event_chunks,
1423+
streaming_chat_completions_model_responses,
1424+
):
1425+
sentry_init(
1426+
integrations=[
1427+
LangchainIntegration(
1428+
include_prompts=True,
1429+
)
1430+
],
1431+
traces_sample_rate=1.0,
1432+
send_default_pii=True,
1433+
)
1434+
events = capture_events()
1435+
1436+
prompt = ChatPromptTemplate.from_messages(
1437+
[
1438+
(
1439+
"system",
1440+
"You are very powerful assistant, but don't know current events",
1441+
),
1442+
("user", "{input}"),
1443+
MessagesPlaceholder(variable_name="agent_scratchpad"),
1444+
]
1445+
)
1446+
1447+
model_responses = streaming_chat_completions_model_responses()
1448+
1449+
tool_response = get_model_response(
1450+
server_side_event_chunks(
1451+
next(model_responses),
1452+
include_event_type=False,
1453+
)
1454+
)
1455+
1456+
final_response = get_model_response(
1457+
server_side_event_chunks(
1458+
next(model_responses),
1459+
include_event_type=False,
1460+
)
1461+
)
1462+
14021463
llm = ChatOpenAI(
14031464
model_name="gpt-3.5-turbo",
14041465
temperature=0,

0 commit comments

Comments
 (0)