Skip to content

Commit b5d4125

Browse files
committed
Upgrade langchain
1 parent 6094546 commit b5d4125

File tree

13 files changed

+93
-79
lines changed

13 files changed

+93
-79
lines changed

services/chatbot/build-image.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ cd "$(dirname $0)"
1818
mkdir -p retrieval
1919
cp -Rv ../../docs retrieval/
2020
cp -Rv ../../deploy/docker/*.yml retrieval/docs/
21-
cp -Rv ../../deploy/docker/*.yaml retrieval/docs/
2221

2322
docker build -t crapi/crapi-chatbot:${VERSION:-latest} .
2423
retVal=$?

services/chatbot/requirements.txt

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
1-
langchain==0.3.26
2-
langchain-community==0.3.27
3-
langchain-core==0.3.68
4-
langchain-mongodb==0.6.1
5-
langchain-openai==0.3.16
6-
langchain-text-splitters==0.3.8
7-
markdown==3.8
8-
pymongo==4.12.1
9-
python-dotenv==1.1.0
10-
unstructured==0.17.2
11-
numpy==1.26.4
12-
langchain-mcp-adapters==0.1.8
1+
langchain==1.0.3
2+
langchain-community==0.4.1
3+
langchain-core==1.0.2
4+
langchain-mongodb==0.7.1
5+
langchain-openai==1.0.1
6+
langchain-text-splitters==1.0.0
7+
langchain-mcp-adapters==0.1.11
8+
langgraph==1.0.2
9+
chromadb==1.3.0
10+
langchain-chroma==1.0.0
11+
openai==2.6.1
12+
fastmcp==2.13.0.2
13+
markdown-it-py==3.0.0
14+
pymongo==4.15.3
15+
python-dotenv==1.2.1
16+
unstructured==0.18.15
17+
numpy==2.2.6
1318
Quart==0.20.0
1419
quart-cors==0.8.0
1520
motor==3.7.1
16-
openai==1.77.0
17-
langgraph==0.5.1
18-
faiss-cpu==1.11.0
19-
psycopg2-binary
20-
uvicorn==0.35.0
21-
fastmcp==2.10.2
22-
chromadb>=0.6.1
23-
langchain-chroma>=0.1.1
21+
faiss-cpu==1.12.0
22+
psycopg2-binary==2.9.11
23+
uvicorn==0.38.0
Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,57 @@
11
import json
2+
23
from langchain_core.messages import ToolMessage
4+
35
from .config import Config
46

57
INDIVIDUAL_MIN_LENGTH = 100
68

9+
710
def collect_long_strings(obj):
811
field_info = []
12+
913
def _collect(obj):
1014
if isinstance(obj, dict):
1115
for key, value in obj.items():
1216
if isinstance(value, str) and len(value) > INDIVIDUAL_MIN_LENGTH:
13-
field_info.append({
14-
'length': len(value),
15-
'dict': obj,
16-
'key': key,
17-
})
17+
field_info.append(
18+
{
19+
"length": len(value),
20+
"dict": obj,
21+
"key": key,
22+
}
23+
)
1824
elif isinstance(value, (dict, list)):
1925
_collect(value)
2026
elif isinstance(obj, list):
2127
for item in obj:
2228
if isinstance(item, (dict, list)):
2329
_collect(item)
24-
30+
2531
_collect(obj)
2632
return field_info
2733

2834

2935
def truncate_by_length(content, max_length):
3036
"""
31-
Truncate JSON content by recursively truncating the longest fields until content is under limit.
37+
Truncate JSON content by recursively truncating the longest fields until content is under limit.
3238
Preserves structure and smaller fields with minimum loss of information.
3339
"""
3440
try:
3541
data = json.loads(content)
36-
field_info = sorted(collect_long_strings(data), key=lambda x: x['length'])
42+
field_info = sorted(collect_long_strings(data), key=lambda x: x["length"])
3743

3844
cur_length = len(json.dumps(data))
39-
while field_info and cur_length-max_length>0:
45+
while field_info and cur_length - max_length > 0:
4046
longest = field_info.pop()
4147
excess = cur_length - max_length
42-
new_length = max(INDIVIDUAL_MIN_LENGTH, longest['length'] - excess)
43-
cur_length -= longest['length'] - new_length
44-
longest['dict'][longest['key']] = (
45-
longest['dict'][longest['key']][:new_length] +
46-
f"... [TRUNCATED: {longest['length'] - new_length} chars removed]"
48+
new_length = max(INDIVIDUAL_MIN_LENGTH, longest["length"] - excess)
49+
cur_length -= longest["length"] - new_length
50+
longest["dict"][longest["key"]] = (
51+
longest["dict"][longest["key"]][:new_length]
52+
+ f"... [TRUNCATED: {longest['length'] - new_length} chars removed]"
4753
)
48-
54+
4955
if cur_length <= max_length:
5056
return json.dumps(data)
5157
except (json.JSONDecodeError, Exception):
@@ -61,13 +67,20 @@ def truncate_tool_messages(state):
6167
"""
6268
messages = state.get("messages", [])
6369
modified_messages = []
64-
65-
for i,msg in enumerate(messages):
66-
if isinstance(msg, ToolMessage) and len(msg.content) > Config.MAX_CONTENT_LENGTH:
67-
truncated_msg = msg.model_copy(update={
68-
'content': truncate_by_length(msg.content, Config.MAX_CONTENT_LENGTH)
69-
})
70+
71+
for i, msg in enumerate(messages):
72+
if (
73+
isinstance(msg, ToolMessage)
74+
and len(msg.content) > Config.MAX_CONTENT_LENGTH
75+
):
76+
truncated_msg = msg.model_copy(
77+
update={
78+
"content": truncate_by_length(
79+
msg.content, Config.MAX_CONTENT_LENGTH
80+
)
81+
}
82+
)
7083
modified_messages.append(truncated_msg)
7184
else:
7285
modified_messages.append(msg)
73-
return {"messages": modified_messages}
86+
return {"messages": modified_messages}

services/chatbot/src/chatbot/chat_api.py

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
import logging
2-
from quart import Blueprint, jsonify, request, session
32
from uuid import uuid4
3+
4+
from quart import Blueprint, jsonify, request
5+
6+
from .chat_service import (delete_chat_history, get_chat_history,
7+
process_user_message)
48
from .config import Config
5-
from .chat_service import delete_chat_history, get_chat_history, process_user_message
6-
from .session_service import (
7-
delete_api_key,
8-
get_api_key,
9-
get_model_name,
10-
get_or_create_session_id,
11-
store_api_key,
12-
store_model_name,
13-
get_user_jwt,
14-
)
9+
from .session_service import (get_api_key, get_model_name,
10+
get_or_create_session_id, get_user_jwt,
11+
store_api_key, store_model_name)
1512

1613
chat_bp = Blueprint("chat", __name__, url_prefix="/genai")
1714
logger = logging.getLogger(__name__)

services/chatbot/src/chatbot/chat_service.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
from uuid import uuid4
2+
23
from langgraph.graph.message import Messages
3-
from .retriever_utils import add_to_chroma_collection
4+
45
from .extensions import db
56
from .langgraph_agent import execute_langgraph_agent
7+
from .retriever_utils import add_to_chroma_collection
68

79

810
async def get_chat_history(session_id):
@@ -38,7 +40,7 @@ async def process_user_message(session_id, user_message, api_key, model_name, us
3840
history.append(
3941
{"id": response_message_id, "role": "assistant", "content": reply.content}
4042
)
41-
res = add_to_chroma_collection(
43+
add_to_chroma_collection(
4244
api_key, session_id, [{"user": user_message}, {"assistant": reply.content}]
4345
)
4446
# Limit chat history to last 20 messages

services/chatbot/src/chatbot/config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from dotenv import load_dotenv
44

5-
from .dbconnections import MONGO_CONNECTION_URI, CHROMA_HOST, CHROMA_PORT
5+
from .dbconnections import CHROMA_HOST, CHROMA_PORT, MONGO_CONNECTION_URI
66

77
load_dotenv()
88

services/chatbot/src/chatbot/extensions.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import asyncio
2-
31
from langchain_community.utilities.sql_database import SQLDatabase
42
from motor.motor_asyncio import AsyncIOMotorClient
53

services/chatbot/src/chatbot/langgraph_agent.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import textwrap
2+
3+
from langchain.agents import create_agent
24
from langchain_community.agent_toolkits import SQLDatabaseToolkit
35
from langchain_openai import ChatOpenAI
4-
from langgraph.prebuilt import create_react_agent
5-
from .retriever_utils import get_retriever_tool
66

7+
from .agent_utils import truncate_tool_messages
78
from .extensions import postgresdb
89
from .mcp_client import get_mcp_client
9-
from .agent_utils import truncate_tool_messages
10+
from .retriever_utils import get_retriever_tool
1011

1112

1213
async def build_langgraph_agent(api_key, model_name, user_jwt):
@@ -55,7 +56,12 @@ async def build_langgraph_agent(api_key, model_name, user_jwt):
5556
tools = mcp_tools + db_tools
5657
retriever_tool = get_retriever_tool(api_key)
5758
tools.append(retriever_tool)
58-
agent_node = create_react_agent(model=llm, tools=tools, prompt=system_prompt, pre_model_hook=truncate_tool_messages)
59+
agent_node = create_agent(
60+
model=llm,
61+
tools=tools,
62+
prompt=system_prompt,
63+
pre_model_hook=truncate_tool_messages,
64+
)
5965
return agent_node
6066

6167

services/chatbot/src/chatbot/retriever_utils.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
from langchain.agents.agent_toolkits import create_retriever_tool
21
import chromadb
32
from langchain_chroma import Chroma as ChromaClient
4-
from .config import Config
53
from langchain_community.embeddings import OpenAIEmbeddings
64
from langchain_core.documents import Document
5+
from langchain_core.tools import create_retriever_tool
6+
7+
from .config import Config
78

89

910
def get_chroma_client():

services/chatbot/src/chatbot/session_service.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import os
22
import uuid
3-
from .config import Config
3+
44
from quart import after_this_request, request
55

6+
from .config import Config
67
from .extensions import db
78

89
SESSION_COOKIE_NAME = "chat_session_id"

0 commit comments

Comments
 (0)