Skip to content

Commit 43b0489

Browse files
committed
chore: use uv, upgrade packages
Signed-off-by: Tyler Slaton <tyler@copilotkit.ai>
1 parent 96a0c4c commit 43b0489

File tree

9 files changed

+1692
-59
lines changed

9 files changed

+1692
-59
lines changed

.github/workflows/smoke.yml

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ on:
66
pull_request:
77
branches: main
88
schedule:
9-
- cron: '0 0 * * *' # Run daily at midnight UTC
9+
- cron: "0 0 * * *" # Run daily at midnight UTC
1010

1111
jobs:
1212
smoke:
@@ -33,6 +33,14 @@ jobs:
3333
with:
3434
python-version: ${{ matrix.python }}
3535

36+
- name: Install uv
37+
uses: astral-sh/setup-uv@v4
38+
with:
39+
enable-cache: true
40+
41+
- name: Configure uv to use matrix Python version
42+
run: echo "UV_PYTHON=python${{ matrix.python }}" >> $GITHUB_ENV
43+
3644
- name: Install Node.js dependencies (root)
3745
run: npm install
3846

@@ -55,12 +63,12 @@ jobs:
5563
# Start the Next.js frontend in background
5664
npm start &
5765
FRONTEND_PID=$!
58-
66+
5967
# Wait for frontend to start (max 30 seconds)
6068
timeout=30
6169
elapsed=0
6270
started=false
63-
71+
6472
while [ $elapsed -lt $timeout ] && [ "$started" = false ]; do
6573
if curl -s http://localhost:3000 > /dev/null 2>&1; then
6674
started=true
@@ -70,10 +78,10 @@ jobs:
7078
elapsed=$((elapsed + 1))
7179
fi
7280
done
73-
81+
7482
# Clean up background process
7583
kill $FRONTEND_PID 2>/dev/null || true
76-
84+
7785
if [ "$started" = false ]; then
7886
echo "❌ Frontend failed to start within 30 seconds"
7987
exit 1
@@ -85,12 +93,12 @@ jobs:
8593
run: |
8694
# Start the Next.js frontend in background
8795
npm start &
88-
96+
8997
# Wait for frontend to start (max 30 seconds)
9098
$timeout = 30
9199
$elapsed = 0
92100
$started = $false
93-
101+
94102
while ($elapsed -lt $timeout -and -not $started) {
95103
try {
96104
$response = Invoke-WebRequest -Uri "http://localhost:3000" -TimeoutSec 1 -ErrorAction SilentlyContinue
@@ -103,7 +111,7 @@ jobs:
103111
$elapsed++
104112
}
105113
}
106-
114+
107115
if (-not $started) {
108116
Write-Host "❌ Frontend failed to start within 30 seconds"
109117
exit 1
@@ -118,7 +126,7 @@ jobs:
118126
runs-on: ubuntu-latest
119127
needs: smoke
120128
if: |
121-
failure() &&
129+
failure() &&
122130
github.event_name == 'schedule'
123131
steps:
124132
- name: Notify Slack
@@ -138,4 +146,4 @@ jobs:
138146
}
139147
}
140148
]
141-
}
149+
}

agent/langgraph.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
"python_version": "3.12",
33
"dockerfile_lines": [],
44
"dependencies": ["."],
5+
"package_manager": "uv",
56
"graphs": {
6-
"sample_agent": "./agent.py:graph"
7+
"sample_agent": "./main.py:graph"
78
},
89
"env": ".env"
910
}

agent/agent.py renamed to agent/main.py

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44
"""
55

66
from typing import Any, List
7-
from typing_extensions import Literal
8-
from langchain_openai import ChatOpenAI
9-
from langchain_core.messages import SystemMessage, BaseMessage
10-
from langchain_core.runnables import RunnableConfig
7+
118
from langchain.tools import tool
12-
from langgraph.graph import StateGraph, END
13-
from langgraph.types import Command
14-
from langgraph.graph import MessagesState
9+
from langchain_core.messages import BaseMessage, SystemMessage
10+
from langchain_core.runnables import RunnableConfig
11+
from langchain_openai import ChatOpenAI
12+
from langgraph.graph import END, MessagesState, StateGraph
1513
from langgraph.prebuilt import ToolNode
14+
from langgraph.types import Command
15+
1616

1717
class AgentState(MessagesState):
1818
"""
@@ -22,17 +22,20 @@ class AgentState(MessagesState):
2222
the CopilotKitState fields. We're also adding a custom field, `language`,
2323
which will be used to set the language of the agent.
2424
"""
25-
proverbs: List[str] = []
25+
26+
proverbs: List[str]
2627
tools: List[Any]
2728
# your_custom_agent_state: str = ""
2829

30+
2931
@tool
3032
def get_weather(location: str):
3133
"""
3234
Get the weather for a given location.
3335
"""
3436
return f"The weather for {location} is 70 degrees."
3537

38+
3639
# @tool
3740
# def your_tool_here(your_arg: str):
3841
# """Your tool description here."""
@@ -48,7 +51,7 @@ def get_weather(location: str):
4851
backend_tool_names = [tool.name for tool in backend_tools]
4952

5053

51-
async def chat_node(state: AgentState, config: RunnableConfig) -> Command[Literal["tool_node", "__end__"]]:
54+
async def chat_node(state: AgentState, config: RunnableConfig) -> Command[str]:
5255
"""
5356
Standard chat node based on the ReAct design pattern. It handles:
5457
- The model to use (and binds in CopilotKit actions and the tools defined above)
@@ -61,16 +64,15 @@ async def chat_node(state: AgentState, config: RunnableConfig) -> Command[Litera
6164
"""
6265

6366
# 1. Define the model
64-
model = ChatOpenAI(model="gpt-4o")
67+
model = ChatOpenAI(model="gpt-5-mini")
6568

6669
# 2. Bind the tools to the model
6770
model_with_tools = model.bind_tools(
6871
[
69-
*state.get("tools", []), # bind tools defined by ag-ui
72+
*state.get("tools", []), # bind tools defined by ag-ui
7073
*backend_tools,
7174
# your_tool_here
7275
],
73-
7476
# 2.1 Disable parallel tool calls to avoid race conditions,
7577
# enable this for faster performance if you want to manage
7678
# the complexity of running tool calls in parallel.
@@ -83,10 +85,13 @@ async def chat_node(state: AgentState, config: RunnableConfig) -> Command[Litera
8385
)
8486

8587
# 4. Run the model to generate a response
86-
response = await model_with_tools.ainvoke([
87-
system_message,
88-
*state["messages"],
89-
], config)
88+
response = await model_with_tools.ainvoke(
89+
[
90+
system_message,
91+
*state["messages"],
92+
],
93+
config,
94+
)
9095

9196
# only route to tool node if tool is not in the tools list
9297
if route_to_tool_node(response):
@@ -95,17 +100,18 @@ async def chat_node(state: AgentState, config: RunnableConfig) -> Command[Litera
95100
goto="tool_node",
96101
update={
97102
"messages": [response],
98-
}
103+
},
99104
)
100105

101106
# 5. We've handled all tool calls, so we can end the graph.
102107
return Command(
103108
goto=END,
104109
update={
105110
"messages": [response],
106-
}
111+
},
107112
)
108113

114+
109115
def route_to_tool_node(response: BaseMessage):
110116
"""
111117
Route to tool node if any tool call in the response matches a backend tool name.
@@ -119,6 +125,7 @@ def route_to_tool_node(response: BaseMessage):
119125
return True
120126
return False
121127

128+
122129
# Define the workflow graph
123130
workflow = StateGraph(AgentState)
124131
workflow.add_node("chat_node", chat_node)

agent/pyproject.toml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[project]
2+
name = "sample-agent"
3+
version = "0.1.0"
4+
description = "A LangGraph agent"
5+
requires-python = ">=3.12"
6+
dependencies = [
7+
"langchain==1.1.0",
8+
"langgraph==1.0.4",
9+
"langsmith>=0.4.49",
10+
"openai>=1.68.2,<2.0.0",
11+
"fastapi>=0.115.5,<1.0.0",
12+
"uvicorn>=0.29.0,<1.0.0",
13+
"python-dotenv>=1.0.0,<2.0.0",
14+
"langgraph-cli[inmem]>=0.4.7",
15+
"langchain-openai>=1.1.0",
16+
]

agent/requirements.txt

Lines changed: 0 additions & 9 deletions
This file was deleted.

0 commit comments

Comments
 (0)