Skip to content

Commit ebc4eb8

Browse files
feat: remove dependencies on Pydantic v1 (#3526)
# Description By moving to LangChain > 0.3, we can remove any dependency on Pydantic V1, thus avoiding the conflicts originating from mixing Pydantic V1 with Pydantic V2 Please include a summary of the changes and the related issue. Please also include relevant motivation and context. ## Checklist before requesting a review Please delete options that are not relevant. - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my code - [ ] I have commented hard-to-understand areas - [ ] I have ideally added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged ## Screenshots (if appropriate):
1 parent 09b4811 commit ebc4eb8

23 files changed

+559
-3430
lines changed

core/pyproject.toml

+5-4
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,24 @@ description = "Quivr core RAG package"
55
authors = [{ name = "Stan Girard", email = "[email protected]" }]
66
dependencies = [
77
"pydantic>=2.8.2",
8-
"langchain-core>=0.2.38",
9-
"langchain>=0.2.14,<0.3.0",
10-
"langgraph>=0.2.38",
8+
"langchain-core>=0.3,<0.4",
9+
"langchain>=0.3,<0.4",
10+
"langgraph>=0.2.38,<0.3",
1111
"httpx>=0.27.0",
1212
"rich>=13.7.1",
1313
"tiktoken>=0.7.0",
1414
"aiofiles>=23.1.0",
1515
"langchain-openai>=0.1.0",
1616
"langchain-cohere>=0.1.0",
17-
"langchain-community>=0.2.12",
17+
"langchain-community>=0.3,<0.4",
1818
"langchain-anthropic>=0.1.23",
1919
"types-pyyaml>=6.0.12.20240808",
2020
"transformers[sentencepiece]>=4.44.2",
2121
"faiss-cpu>=1.8.0.post1",
2222
"rapidfuzz>=3.10.1",
2323
"markupsafe>=2.1.5",
2424
"megaparse-sdk>=0.1.9",
25+
"langchain-mistralai>=0.2.3",
2526
]
2627
readme = "README.md"
2728
requires-python = ">= 3.11"

core/quivr_core/llm/llm_endpoint.py

+12-2
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@
55

66
import tiktoken
77
from langchain_anthropic import ChatAnthropic
8+
from langchain_mistralai import ChatMistralAI
89
from langchain_core.language_models.chat_models import BaseChatModel
910
from langchain_openai import AzureChatOpenAI, ChatOpenAI
10-
from pydantic.v1 import SecretStr
11+
from pydantic import SecretStr
1112

1213
from quivr_core.brain.info import LLMInfo
1314
from quivr_core.rag.entities.config import DefaultModelSuppliers, LLMEndpointConfig
@@ -54,7 +55,7 @@ def get_config(self):
5455

5556
@classmethod
5657
def from_config(cls, config: LLMEndpointConfig = LLMEndpointConfig()):
57-
_llm: Union[AzureChatOpenAI, ChatOpenAI, ChatAnthropic]
58+
_llm: Union[AzureChatOpenAI, ChatOpenAI, ChatAnthropic, ChatMistralAI]
5859
try:
5960
if config.supplier == DefaultModelSuppliers.AZURE:
6061
# Parse the URL
@@ -92,6 +93,15 @@ def from_config(cls, config: LLMEndpointConfig = LLMEndpointConfig()):
9293
max_tokens=config.max_output_tokens,
9394
temperature=config.temperature,
9495
)
96+
elif config.supplier == DefaultModelSuppliers.MISTRAL:
97+
_llm = ChatMistralAI(
98+
model=config.model,
99+
api_key=SecretStr(config.llm_api_key)
100+
if config.llm_api_key
101+
else None,
102+
base_url=config.llm_base_url,
103+
temperature=config.temperature,
104+
)
95105
else:
96106
_llm = ChatOpenAI(
97107
model=config.model,

core/quivr_core/llm_tools/web_search_tools.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from langchain_community.utilities.tavily_search import TavilySearchAPIWrapper
55
from quivr_core.llm_tools.entity import ToolsCategory
66
import os
7-
from pydantic.v1 import SecretStr as SecretStrV1 # Ensure correct import
7+
from pydantic import SecretStr # Ensure correct import
88
from quivr_core.llm_tools.entity import ToolWrapper, ToolRegistry
99
from langchain_core.documents import Document
1010

@@ -23,7 +23,7 @@ def create_tavily_tool(config: Dict[str, Any]) -> ToolWrapper:
2323
)
2424

2525
tavily_api_wrapper = TavilySearchAPIWrapper(
26-
tavily_api_key=SecretStrV1(api_key),
26+
tavily_api_key=SecretStr(api_key),
2727
)
2828
tool = TavilySearchResults(
2929
api_wrapper=tavily_api_wrapper,

core/quivr_core/rag/entities/models.py

+7-10
Original file line numberDiff line numberDiff line change
@@ -5,35 +5,33 @@
55

66
from langchain_core.documents import Document
77
from langchain_core.messages import AIMessage, HumanMessage
8-
from langchain_core.pydantic_v1 import BaseModel as BaseModelV1
9-
from langchain_core.pydantic_v1 import Field as FieldV1
108
from pydantic import BaseModel, Field
119
from typing_extensions import TypedDict
1210

1311

14-
class cited_answer(BaseModelV1):
12+
class cited_answer(BaseModel):
1513
"""Answer the user question based only on the given sources, and cite the sources used."""
1614

17-
answer: str = FieldV1(
15+
answer: str = Field(
1816
...,
1917
description="The answer to the user question, which is based only on the given sources.",
2018
)
21-
citations: list[int] = FieldV1(
19+
citations: list[int] = Field(
2220
...,
2321
description="The integer IDs of the SPECIFIC sources which justify the answer.",
2422
)
2523

26-
followup_questions: list[str] = FieldV1(
24+
followup_questions: list[str] = Field(
2725
...,
2826
description="Generate up to 3 follow-up questions that could be asked based on the answer given or context provided.",
2927
)
3028

3129

32-
class ChatMessage(BaseModelV1):
30+
class ChatMessage(BaseModel):
3331
chat_id: UUID
3432
message_id: UUID
3533
brain_id: UUID | None
36-
msg: AIMessage | HumanMessage
34+
msg: HumanMessage | AIMessage
3735
message_time: datetime
3836
metadata: dict[str, Any]
3937

@@ -108,7 +106,6 @@ class QuivrKnowledge(BaseModel):
108106
metadata: Optional[Dict[str, str]] = None
109107

110108

111-
# NOTE: for compatibility issues with langchain <-> PydanticV1
112-
class SearchResult(BaseModelV1):
109+
class SearchResult(BaseModel):
113110
chunk: Document
114111
distance: float

core/requirements-dev.lock

+39-12
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ aiosignal==1.3.1
2121
# via aiohttp
2222
annotated-types==0.7.0
2323
# via pydantic
24-
anthropic==0.36.1
24+
anthropic==0.40.0
2525
# via langchain-anthropic
2626
anyio==4.6.2.post1
2727
# via anthropic
@@ -89,12 +89,16 @@ httpcore==1.0.6
8989
httpx==0.27.2
9090
# via anthropic
9191
# via cohere
92+
# via langchain-mistralai
9293
# via langgraph-sdk
9394
# via langsmith
95+
# via megaparse-sdk
9496
# via openai
9597
# via quivr-core
9698
httpx-sse==0.4.0
9799
# via cohere
100+
# via langchain-community
101+
# via langchain-mistralai
98102
# via langgraph-sdk
99103
huggingface-hub==0.25.2
100104
# via tokenizers
@@ -125,32 +129,35 @@ jupyter-client==8.6.3
125129
jupyter-core==5.7.2
126130
# via ipykernel
127131
# via jupyter-client
128-
langchain==0.2.16
132+
langchain==0.3.9
129133
# via langchain-community
130134
# via quivr-core
131-
langchain-anthropic==0.1.23
135+
langchain-anthropic==0.3.0
132136
# via quivr-core
133-
langchain-cohere==0.2.4
137+
langchain-cohere==0.3.3
134138
# via quivr-core
135-
langchain-community==0.2.17
139+
langchain-community==0.3.9
136140
# via langchain-experimental
137141
# via quivr-core
138-
langchain-core==0.2.41
142+
langchain-core==0.3.21
139143
# via langchain
140144
# via langchain-anthropic
141145
# via langchain-cohere
142146
# via langchain-community
143147
# via langchain-experimental
148+
# via langchain-mistralai
144149
# via langchain-openai
145150
# via langchain-text-splitters
146151
# via langgraph
147152
# via langgraph-checkpoint
148153
# via quivr-core
149-
langchain-experimental==0.0.65
154+
langchain-experimental==0.3.3
150155
# via langchain-cohere
151-
langchain-openai==0.1.25
156+
langchain-mistralai==0.2.3
157+
# via quivr-core
158+
langchain-openai==0.2.11
152159
# via quivr-core
153-
langchain-text-splitters==0.2.4
160+
langchain-text-splitters==0.3.2
154161
# via langchain
155162
langgraph==0.2.38
156163
# via quivr-core
@@ -162,8 +169,12 @@ langsmith==0.1.135
162169
# via langchain
163170
# via langchain-community
164171
# via langchain-core
172+
loguru==0.7.2
173+
# via megaparse-sdk
165174
markdown-it-py==3.0.0
166175
# via rich
176+
markupsafe==3.0.2
177+
# via quivr-core
167178
marshmallow==3.22.0
168179
# via dataclasses-json
169180
matplotlib-inline==0.1.7
@@ -173,6 +184,8 @@ mccabe==0.7.0
173184
# via flake8
174185
mdurl==0.1.2
175186
# via markdown-it-py
187+
megaparse-sdk==0.1.10
188+
# via quivr-core
176189
msgpack==1.1.0
177190
# via langgraph-checkpoint
178191
multidict==6.1.0
@@ -183,6 +196,8 @@ mypy-extensions==1.0.0
183196
# via black
184197
# via mypy
185198
# via typing-inspect
199+
nats-py==2.9.0
200+
# via megaparse-sdk
186201
nest-asyncio==1.6.0
187202
# via ipykernel
188203
nodeenv==1.9.1
@@ -193,7 +208,7 @@ numpy==1.26.4
193208
# via langchain-community
194209
# via pandas
195210
# via transformers
196-
openai==1.52.0
211+
openai==1.56.2
197212
# via langchain-openai
198213
orjson==3.10.7
199214
# via langgraph-sdk
@@ -230,8 +245,9 @@ propcache==0.2.0
230245
# via yarl
231246
protobuf==5.28.2
232247
# via transformers
233-
psutil==6.0.0
248+
psutil==6.1.0
234249
# via ipykernel
250+
# via megaparse-sdk
235251
ptyprocess==0.7.0
236252
# via pexpect
237253
pure-eval==0.2.3
@@ -240,17 +256,25 @@ py-cpuinfo==9.0.0
240256
# via pytest-benchmark
241257
pycodestyle==2.12.1
242258
# via flake8
259+
pycryptodome==3.21.0
260+
# via megaparse-sdk
243261
pydantic==2.9.2
244262
# via anthropic
245263
# via cohere
246264
# via langchain
265+
# via langchain-anthropic
266+
# via langchain-cohere
247267
# via langchain-core
268+
# via langchain-mistralai
248269
# via langsmith
249270
# via openai
271+
# via pydantic-settings
250272
# via quivr-core
251273
pydantic-core==2.23.4
252274
# via cohere
253275
# via pydantic
276+
pydantic-settings==2.6.1
277+
# via langchain-community
254278
pyflakes==3.2.0
255279
# via flake8
256280
pygments==2.18.0
@@ -266,6 +290,9 @@ pytest-xdist==3.6.1
266290
python-dateutil==2.8.2
267291
# via jupyter-client
268292
# via pandas
293+
python-dotenv==1.0.1
294+
# via megaparse-sdk
295+
# via pydantic-settings
269296
pytz==2024.2
270297
# via pandas
271298
pyyaml==6.0.2
@@ -324,8 +351,8 @@ tiktoken==0.8.0
324351
# via langchain-openai
325352
# via quivr-core
326353
tokenizers==0.20.1
327-
# via anthropic
328354
# via cohere
355+
# via langchain-mistralai
329356
# via transformers
330357
tornado==6.4.1
331358
# via ipykernel

0 commit comments

Comments
 (0)