Skip to content

Commit d098e0f

Browse files
committed
feat(langgraph): upgrade langgraph
1 parent c6996db commit d098e0f

File tree

15 files changed

+300
-538
lines changed

15 files changed

+300
-538
lines changed

pyproject.toml

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
11
[project]
22
name = "uipath-langchain"
3-
version = "0.0.147"
3+
version = "0.0.143"
44
description = "UiPath Langchain"
55
readme = { file = "README.md", content-type = "text/markdown" }
6-
requires-python = ">=3.10"
6+
requires-python = ">=3.11"
77
dependencies = [
8-
"uipath>=2.1.110, <2.2.0",
9-
"langgraph>=0.5.0, <0.7.0",
10-
"langchain-core>=0.3.34",
8+
"uipath>=2.1.103, <2.2.0",
9+
"langgraph>=1.0.1, <1.1.0",
10+
"langchain-core>=1.0.0, <1.1.0",
1111
"langgraph-checkpoint-sqlite>=2.0.3",
12-
"langchain-community>=0.3.21",
13-
"langchain-openai>=0.3.3",
14-
"langchain>=0.3.4",
12+
"langchain-community>=0.4.1",
13+
"langchain-openai>=1.0.1",
14+
"langchain>=1.0.2",
1515
"pydantic-settings>=2.6.0",
1616
"python-dotenv>=1.0.1",
1717
"httpx>=0.27.0",
18-
"openai>=1.65.5",
19-
"openinference-instrumentation-langchain>=0.1.50",
18+
"openinference-instrumentation-langchain>=0.1.54",
2019
"jsonschema-pydantic>=0.6",
2120
]
2221
classifiers = [

testcases/common/trace_assert.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,15 +106,23 @@ def assert_traces(traces_file: str, expected_file: str) -> None:
106106
for expected in expected_spans:
107107
# Find a matching span
108108
found = False
109+
name = expected['name']
110+
# Handle both string and list of names
111+
name_str = name if isinstance(name, str) else f"[{' | '.join(name)}]"
112+
109113
for span in traces:
110114
if matches_expected(span, expected):
111115
found = True
112-
print(f"✓ Found span: {expected['name']}")
116+
print(f"✓ Found span: {name_str}")
113117
break
114118

115119
if not found:
116-
missing_spans.append(expected['name'])
117-
print(f"✗ Missing span: {expected['name']}")
120+
missing_spans.append(name_str)
121+
print(f"✗ Missing span: {name_str}")
122+
123+
print("Traces file content:")
124+
with open(traces_file, 'r', encoding='utf-8') as f:
125+
print(f.read())
118126

119127
if missing_spans:
120128
raise AssertionError(
Lines changed: 118 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,119 @@
11
{
2-
"description": "Company research agent trace assertions - check key spans exist",
3-
"required_spans": [
4-
{
5-
"name": "LangGraph",
6-
"span_type": "OpenTelemetry",
7-
"attributes": {
8-
"openinference.span.kind": "CHAIN"
9-
}
10-
},
11-
{
12-
"name": "call_model",
13-
"span_type": "OpenTelemetry",
14-
"attributes": {
15-
"openinference.span.kind": "CHAIN"
16-
}
17-
},
18-
{
19-
"name": [
20-
"UiPathChat",
21-
"UiPathAzureChatOpenAI"
22-
],
23-
"span_type": "OpenTelemetry",
24-
"attributes": {
25-
"openinference.span.kind": "LLM",
26-
"llm.provider": "azure",
27-
"llm.system": "openai",
28-
"llm.model_name": "gpt-4o-2024-08-06"
29-
}
30-
},
31-
{
32-
"name": "duckduckgo_results_json",
33-
"span_type": "OpenTelemetry",
34-
"attributes": {
35-
"openinference.span.kind": "TOOL",
36-
"tool.name": "duckduckgo_results_json",
37-
"tool.description": "A wrapper around Duck Duck Go Search. Useful for when you need to answer questions about current events. Input should be a search query."
38-
}
39-
}
40-
]
41-
}
2+
"description": "Expected traces for company-research-agent test with DuckDuckGo search tools",
3+
"required_spans": [
4+
{
5+
"name": "LangGraph",
6+
"span_type": "OpenTelemetry",
7+
"attributes": {
8+
"openinference.span.kind": "CHAIN",
9+
"session.id": "default"
10+
}
11+
},
12+
{
13+
"name": "researcher",
14+
"span_type": "OpenTelemetry",
15+
"parent_name": "LangGraph",
16+
"attributes": {
17+
"openinference.span.kind": "CHAIN",
18+
"session.id": "default"
19+
}
20+
},
21+
{
22+
"name": "model",
23+
"span_type": "OpenTelemetry",
24+
"parent_name": "researcher",
25+
"attributes": {
26+
"openinference.span.kind": "CHAIN",
27+
"session.id": "default"
28+
}
29+
},
30+
{
31+
"name": ["UiPathChat", "UiPathAzureChatOpenAI"],
32+
"span_type": "OpenTelemetry",
33+
"parent_name": "model",
34+
"attributes": {
35+
"openinference.span.kind": "LLM",
36+
"llm.provider": "azure",
37+
"llm.system": "openai",
38+
"llm.model_name": "gpt-4o-2024-08-06",
39+
"llm.input_messages.0.message.role": "system",
40+
"llm.input_messages.1.message.role": "user",
41+
"llm.output_messages.0.message.role": "assistant",
42+
"session.id": "default"
43+
}
44+
},
45+
{
46+
"name": "model_to_tools",
47+
"span_type": "OpenTelemetry",
48+
"parent_name": "model",
49+
"attributes": {
50+
"openinference.span.kind": "CHAIN",
51+
"session.id": "default"
52+
}
53+
},
54+
{
55+
"name": "tools",
56+
"span_type": "OpenTelemetry",
57+
"parent_name": "researcher",
58+
"attributes": {
59+
"openinference.span.kind": "CHAIN",
60+
"session.id": "default"
61+
}
62+
},
63+
{
64+
"name": "duckduckgo_results_json",
65+
"span_type": "OpenTelemetry",
66+
"parent_name": "tools",
67+
"attributes": {
68+
"openinference.span.kind": "TOOL",
69+
"tool.name": "duckduckgo_results_json",
70+
"tool.description": "A wrapper around Duck Duck Go Search. Useful for when you need to answer questions about current events. Input should be a search query.",
71+
"session.id": "default"
72+
}
73+
},
74+
{
75+
"name": "tools_to_model",
76+
"span_type": "OpenTelemetry",
77+
"parent_name": "tools",
78+
"attributes": {
79+
"openinference.span.kind": "CHAIN",
80+
"session.id": "default"
81+
}
82+
},
83+
{
84+
"name": "model",
85+
"span_type": "OpenTelemetry",
86+
"parent_name": "researcher",
87+
"count": 2,
88+
"attributes": {
89+
"openinference.span.kind": "CHAIN",
90+
"session.id": "default"
91+
}
92+
},
93+
{
94+
"name": ["UiPathChat", "UiPathAzureChatOpenAI"],
95+
"span_type": "OpenTelemetry",
96+
"parent_name": "model",
97+
"count": 2,
98+
"attributes": {
99+
"openinference.span.kind": "LLM",
100+
"llm.provider": "azure",
101+
"llm.system": "openai",
102+
"llm.model_name": "gpt-4o-2024-08-06",
103+
"llm.output_messages.0.message.role": "assistant",
104+
"session.id": "default"
105+
}
106+
},
107+
{
108+
"name": "model_to_tools",
109+
"span_type": "OpenTelemetry",
110+
"parent_name": "model",
111+
"count": 2,
112+
"attributes": {
113+
"openinference.span.kind": "CHAIN",
114+
"session.id": "default",
115+
"output.value": "__end__"
116+
}
117+
}
118+
]
119+
}

testcases/company-research-agent/pyproject.toml

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,12 @@ version = "0.0.1"
44
description = "Company research agent with Tavily web search"
55
authors = [{ name = "John Doe", email = "[email protected]" }]
66

7-
requires-python = ">=3.10"
7+
requires-python = ">=3.11"
88
dependencies = [
9-
"langgraph>=0.2.55",
10-
"langchain-anthropic>=0.3.8",
11-
"tavily-python>=0.5.0",
129
"uipath-langchain",
13-
"duckduckgo-search>=8.1.1",
10+
"langgraph>=1.0.1",
1411
"langchain-community>=0.3.21",
15-
"debugpy>=1.8.15",
12+
"ddgs>=9.6.1",
1613
]
1714

1815
[project.optional-dependencies]

testcases/company-research-agent/src/assert.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@
4444
# Check if response contains 'Successful execution.'
4545
assert "Successful execution." in local_run_output, f"Response does not contain 'Successful execution.'. Actual response: {local_run_output}"
4646

47+
with open("__uipath/execution.log", "r") as f:
48+
log_output = f.read()
49+
# Print the execution log content
50+
print(log_output)
51+
4752
assert_traces(".uipath/traces.jsonl", "expected_traces.json")
4853

4954
print("Required fields validation passed")

testcases/company-research-agent/src/graph.py

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,18 @@
22
from typing import Union
33

44
from langchain_community.tools import DuckDuckGoSearchResults
5-
from langchain_community.tools.tavily_search import TavilySearchResults
65
from langgraph.graph import END, START, MessagesState, StateGraph
7-
from langgraph.prebuilt import create_react_agent
6+
from langchain.agents import create_agent
87
from pydantic import BaseModel
98

109
from uipath_langchain.chat import UiPathAzureChatOpenAI, UiPathChat
1110

1211
# Configuration constants
13-
MAX_SEARCH_RESULTS = 5
1412
DEFAULT_MODEL = "gpt-4o-2024-08-06"
15-
ALTERNATIVE_MODEL = "claude-3-5-sonnet-latest"
1613

1714

18-
def get_search_tool() -> Union[TavilySearchResults, DuckDuckGoSearchResults]:
15+
def get_search_tool() -> Union[DuckDuckGoSearchResults]:
1916
"""Get the appropriate search tool based on available API keys."""
20-
if os.getenv("TAVILY_API_KEY"):
21-
return TavilySearchResults(max_results=MAX_SEARCH_RESULTS)
2217
return DuckDuckGoSearchResults()
2318

2419

@@ -50,15 +45,15 @@ def get_search_tool() -> Union[TavilySearchResults, DuckDuckGoSearchResults]:
5045
def create_llm() -> Union[UiPathAzureChatOpenAI, UiPathChat]:
5146
"""Create and configure the language model based on an environment variable."""
5247
if os.getenv("USE_AZURE_CHAT", "false").lower() == "true":
53-
return UiPathAzureChatOpenAI(model=DEFAULT_MODEL)
48+
return UiPathAzureChatOpenAI(model=DEFAULT_MODEL, streaming=False)
5449
return UiPathChat(model=DEFAULT_MODEL)
5550

5651

5752
def create_research_agent():
5853
"""Create the research agent with configured LLM and tools."""
5954
llm = create_llm()
6055
search_tool = get_search_tool()
61-
return create_react_agent(llm, tools=[search_tool], prompt=SYSTEM_PROMPT)
56+
return create_agent(llm, tools=[search_tool], system_prompt=SYSTEM_PROMPT)
6257

6358

6459
class GraphState(BaseModel):
@@ -73,7 +68,7 @@ class GraphOutput(BaseModel):
7368

7469
def create_user_message(company_name: str) -> str:
7570
"""Create a formatted user message for company research."""
76-
return f"""Please provide a comprehensive analysis and outreach strategy for the company: {company_name}. Use the TavilySearchResults tool to gather information. Include detailed research on the company's background, organizational structure, key decision-makers, and a tailored outreach strategy. Format your response using the following section headers:
71+
return f"""Please provide a comprehensive analysis and outreach strategy for the company: {company_name}. Use the DuckDuckGoSearchResults tool to gather information. Include detailed research on the company's background, organizational structure, key decision-makers, and a tailored outreach strategy. Format your response using the following section headers:
7772
7873
1. Company Overview
7974
2. Organizational Structure

testcases/init-flow/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ dependencies = [
77
"langchain-anthropic>=0.3.8",
88
"uipath-langchain",
99
]
10-
requires-python = ">=3.10"
10+
requires-python = ">=3.11"
1111

1212
[tool.uv.sources]
1313
uipath-langchain = { path = "../../", editable = true }

0 commit comments

Comments
 (0)