adding golden dataset
Browse files- app.py +49 -9
- data/testingset.json +17 -0
- pyproject.toml +1 -0
- uv.lock +63 -0
app.py
CHANGED
@@ -14,6 +14,10 @@ import os
|
|
14 |
from ragas import evaluate
|
15 |
from ragas.metrics import answer_relevancy
|
16 |
from langchain_core.documents import Document
|
|
|
|
|
|
|
|
|
17 |
|
18 |
|
19 |
load_dotenv()
|
@@ -21,6 +25,7 @@ load_dotenv()
|
|
21 |
# Load OpenAI Model
|
22 |
llm = ChatOpenAI(model="gpt-4o-mini")
|
23 |
qd_api_key = os.getenv("QDRANT_CLOUD_API_KEY")
|
|
|
24 |
|
25 |
|
26 |
embedding_model = OpenAIEmbeddings(model="text-embedding-3-small")
|
@@ -181,17 +186,19 @@ format_prompt = ChatPromptTemplate.from_template(ot_formatted_prompt)
|
|
181 |
def research_node(state) -> dict:
|
182 |
question = state["messages"][-1].content
|
183 |
|
184 |
-
#
|
185 |
query_vector = embedding_model.embed_query(question)
|
186 |
|
187 |
-
#
|
188 |
-
relevant_docs = search(query_vector=query_vector, top_k=1)
|
189 |
|
190 |
-
|
191 |
-
|
|
|
|
|
192 |
|
193 |
-
if
|
194 |
-
#
|
195 |
document_name = relevant_docs[0]["metadata"].get("document_name", "No source available.")
|
196 |
document_text = get_document_by_name(document_name)
|
197 |
|
@@ -201,17 +208,50 @@ def research_node(state) -> dict:
|
|
201 |
return {**state, "messages": state["messages"] + [HumanMessage(content=response.content)], "_next": "post_processing"}
|
202 |
|
203 |
else:
|
204 |
-
#
|
205 |
-
print("β οΈ RAGAS score too low, defaulting to LLM.")
|
206 |
messages = rag_prompt.format_messages(question=question, context="No relevant documents found.")
|
207 |
response = llm.invoke(messages)
|
208 |
|
209 |
return {**state, "messages": state["messages"] + [HumanMessage(content=response.content)], "_next": "post_processing"}
|
210 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
211 |
|
212 |
# **Post-Processing Node: Formats response using `ot_formatted_prompt`**
|
213 |
def post_processing_node(state) -> dict:
|
214 |
response_text = state["messages"][-1].content
|
|
|
|
|
|
|
|
|
|
|
|
|
215 |
messages = format_prompt.format_messages(context=response_text)
|
216 |
response = llm.invoke(messages)
|
217 |
|
|
|
14 |
from ragas import evaluate
|
15 |
from ragas.metrics import answer_relevancy
|
16 |
from langchain_core.documents import Document
|
17 |
+
import json
|
18 |
+
import numpy as np
|
19 |
+
from sklearn.metrics.pairwise import cosine_similarity
|
20 |
+
|
21 |
|
22 |
|
23 |
load_dotenv()
|
|
|
25 |
# Load OpenAI Model
|
26 |
llm = ChatOpenAI(model="gpt-4o-mini")
|
27 |
qd_api_key = os.getenv("QDRANT_CLOUD_API_KEY")
|
28 |
+
EVALUATION_MODE = os.getenv("EVALUATION_MODE", "false").lower() == "false"
|
29 |
|
30 |
|
31 |
embedding_model = OpenAIEmbeddings(model="text-embedding-3-small")
|
|
|
186 |
def research_node(state) -> dict:
|
187 |
question = state["messages"][-1].content
|
188 |
|
189 |
+
# Convert the text question to an embedding using OpenAI Embeddings
|
190 |
query_vector = embedding_model.embed_query(question)
|
191 |
|
192 |
+
# Query Qdrant with the vector
|
193 |
+
relevant_docs = search(query_vector=query_vector, top_k=1)
|
194 |
|
195 |
+
if EVALUATION_MODE:
|
196 |
+
# Evaluate retrieved documents using RAGAS
|
197 |
+
relevance_score = evaluate_retrieved_docs(question, relevant_docs)
|
198 |
+
print(f"π [Evaluation Mode] RAGAS Score: {relevance_score}")
|
199 |
|
200 |
+
if relevant_docs[0]['score'] > 0.5: # Threshold for good retrieval quality this will be the cosine similarity score
|
201 |
+
# Found relevant document β Summarize it
|
202 |
document_name = relevant_docs[0]["metadata"].get("document_name", "No source available.")
|
203 |
document_text = get_document_by_name(document_name)
|
204 |
|
|
|
208 |
return {**state, "messages": state["messages"] + [HumanMessage(content=response.content)], "_next": "post_processing"}
|
209 |
|
210 |
else:
|
211 |
+
# No relevant document
|
|
|
212 |
messages = rag_prompt.format_messages(question=question, context="No relevant documents found.")
|
213 |
response = llm.invoke(messages)
|
214 |
|
215 |
return {**state, "messages": state["messages"] + [HumanMessage(content=response.content)], "_next": "post_processing"}
|
216 |
|
217 |
+
def compare_text_similarity(text1, text2):
|
218 |
+
"""Compute cosine similarity between two texts using embeddings."""
|
219 |
+
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
|
220 |
+
|
221 |
+
emb1 = np.array(embeddings.embed_query(text1)).reshape(1, -1)
|
222 |
+
emb2 = np.array(embeddings.embed_query(text2)).reshape(1, -1)
|
223 |
+
|
224 |
+
return cosine_similarity(emb1, emb2)[0][0] # Return similarity score
|
225 |
+
|
226 |
+
def evaluate_against_golden_set(question, model_answer):
|
227 |
+
"""Compare model-generated answers against the golden dataset."""
|
228 |
+
with open("testingset.json", "r", encoding="utf-8") as f:
|
229 |
+
golden_data = json.load(f)
|
230 |
+
|
231 |
+
# Find the corresponding question in the dataset
|
232 |
+
for entry in golden_data:
|
233 |
+
if entry["question"].strip() == question.strip():
|
234 |
+
expected_answer = entry["expected_answer"]
|
235 |
+
break
|
236 |
+
else:
|
237 |
+
print("β οΈ Question not found in the Golden Data Set.")
|
238 |
+
return None
|
239 |
+
|
240 |
+
# Evaluate similarity (simple text match, or use embedding similarity)
|
241 |
+
similarity_score = compare_text_similarity(model_answer, expected_answer)
|
242 |
+
|
243 |
+
print(f"π [Evaluation] Model vs. Expected Score: {similarity_score:.2f}")
|
244 |
+
return similarity_score
|
245 |
|
246 |
# **Post-Processing Node: Formats response using `ot_formatted_prompt`**
|
247 |
def post_processing_node(state) -> dict:
|
248 |
response_text = state["messages"][-1].content
|
249 |
+
|
250 |
+
# Evaluate the model against the golden dataset
|
251 |
+
if EVALUATION_MODE:
|
252 |
+
question = state["messages"][0].content
|
253 |
+
evaluate_against_golden_set(question, response_text)
|
254 |
+
|
255 |
messages = format_prompt.format_messages(context=response_text)
|
256 |
response = llm.invoke(messages)
|
257 |
|
data/testingset.json
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[
|
2 |
+
{
|
3 |
+
"question": "What are the best exercises for tennis elbow?",
|
4 |
+
"contexts": [
|
5 |
+
"Tennis elbow graded exercise protocol...",
|
6 |
+
"Manual therapy review..."
|
7 |
+
],
|
8 |
+
"expected_answer": "Eccentric exercises and stretching reduce symptoms."
|
9 |
+
},
|
10 |
+
{
|
11 |
+
"question": "What is the role of manual therapy in treating elbow injuries?",
|
12 |
+
"contexts": [
|
13 |
+
"Research shows that manual therapy combined with exercise is beneficial."
|
14 |
+
],
|
15 |
+
"expected_answer": "Manual therapy improves range of motion and reduces pain."
|
16 |
+
}
|
17 |
+
]
|
pyproject.toml
CHANGED
@@ -14,6 +14,7 @@ dependencies = [
|
|
14 |
"nltk>=3.9.1",
|
15 |
"qdrant-client>=1.13.2",
|
16 |
"ragas>=0.2.13",
|
|
|
17 |
"unstructured>=0.14.8",
|
18 |
"websockets>=15.0",
|
19 |
]
|
|
|
14 |
"nltk>=3.9.1",
|
15 |
"qdrant-client>=1.13.2",
|
16 |
"ragas>=0.2.13",
|
17 |
+
"scikit-learn>=1.6.1",
|
18 |
"unstructured>=0.14.8",
|
19 |
"websockets>=15.0",
|
20 |
]
|
uv.lock
CHANGED
@@ -1271,6 +1271,7 @@ dependencies = [
|
|
1271 |
{ name = "nltk" },
|
1272 |
{ name = "qdrant-client" },
|
1273 |
{ name = "ragas" },
|
|
|
1274 |
{ name = "unstructured" },
|
1275 |
{ name = "websockets" },
|
1276 |
]
|
@@ -1286,6 +1287,7 @@ requires-dist = [
|
|
1286 |
{ name = "nltk", specifier = ">=3.9.1" },
|
1287 |
{ name = "qdrant-client", specifier = ">=1.13.2" },
|
1288 |
{ name = "ragas", specifier = ">=0.2.13" },
|
|
|
1289 |
{ name = "unstructured", specifier = ">=0.14.8" },
|
1290 |
{ name = "websockets", specifier = ">=15.0" },
|
1291 |
]
|
@@ -1716,6 +1718,58 @@ wheels = [
|
|
1716 |
{ url = "https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06", size = 54481 },
|
1717 |
]
|
1718 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1719 |
[[package]]
|
1720 |
name = "setuptools"
|
1721 |
version = "75.8.0"
|
@@ -1821,6 +1875,15 @@ wheels = [
|
|
1821 |
{ url = "https://files.pythonhosted.org/packages/b6/cb/b86984bed139586d01532a587464b5805f12e397594f19f931c4c2fbfa61/tenacity-9.0.0-py3-none-any.whl", hash = "sha256:93de0c98785b27fcf659856aa9f54bfbd399e29969b0621bc7f762bd441b4539", size = 28169 },
|
1822 |
]
|
1823 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1824 |
[[package]]
|
1825 |
name = "tiktoken"
|
1826 |
version = "0.9.0"
|
|
|
1271 |
{ name = "nltk" },
|
1272 |
{ name = "qdrant-client" },
|
1273 |
{ name = "ragas" },
|
1274 |
+
{ name = "scikit-learn" },
|
1275 |
{ name = "unstructured" },
|
1276 |
{ name = "websockets" },
|
1277 |
]
|
|
|
1287 |
{ name = "nltk", specifier = ">=3.9.1" },
|
1288 |
{ name = "qdrant-client", specifier = ">=1.13.2" },
|
1289 |
{ name = "ragas", specifier = ">=0.2.13" },
|
1290 |
+
{ name = "scikit-learn", specifier = ">=1.6.1" },
|
1291 |
{ name = "unstructured", specifier = ">=0.14.8" },
|
1292 |
{ name = "websockets", specifier = ">=15.0" },
|
1293 |
]
|
|
|
1718 |
{ url = "https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06", size = 54481 },
|
1719 |
]
|
1720 |
|
1721 |
+
[[package]]
|
1722 |
+
name = "scikit-learn"
|
1723 |
+
version = "1.6.1"
|
1724 |
+
source = { registry = "https://pypi.org/simple" }
|
1725 |
+
dependencies = [
|
1726 |
+
{ name = "joblib" },
|
1727 |
+
{ name = "numpy" },
|
1728 |
+
{ name = "scipy" },
|
1729 |
+
{ name = "threadpoolctl" },
|
1730 |
+
]
|
1731 |
+
sdist = { url = "https://files.pythonhosted.org/packages/9e/a5/4ae3b3a0755f7b35a280ac90b28817d1f380318973cff14075ab41ef50d9/scikit_learn-1.6.1.tar.gz", hash = "sha256:b4fc2525eca2c69a59260f583c56a7557c6ccdf8deafdba6e060f94c1c59738e", size = 7068312 }
|
1732 |
+
wheels = [
|
1733 |
+
{ url = "https://files.pythonhosted.org/packages/2e/59/8eb1872ca87009bdcdb7f3cdc679ad557b992c12f4b61f9250659e592c63/scikit_learn-1.6.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2ffa1e9e25b3d93990e74a4be2c2fc61ee5af85811562f1288d5d055880c4322", size = 12010001 },
|
1734 |
+
{ url = "https://files.pythonhosted.org/packages/9d/05/f2fc4effc5b32e525408524c982c468c29d22f828834f0625c5ef3d601be/scikit_learn-1.6.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:dc5cf3d68c5a20ad6d571584c0750ec641cc46aeef1c1507be51300e6003a7e1", size = 11096360 },
|
1735 |
+
{ url = "https://files.pythonhosted.org/packages/c8/e4/4195d52cf4f113573fb8ebc44ed5a81bd511a92c0228889125fac2f4c3d1/scikit_learn-1.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c06beb2e839ecc641366000ca84f3cf6fa9faa1777e29cf0c04be6e4d096a348", size = 12209004 },
|
1736 |
+
{ url = "https://files.pythonhosted.org/packages/94/be/47e16cdd1e7fcf97d95b3cb08bde1abb13e627861af427a3651fcb80b517/scikit_learn-1.6.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8ca8cb270fee8f1f76fa9bfd5c3507d60c6438bbee5687f81042e2bb98e5a97", size = 13171776 },
|
1737 |
+
{ url = "https://files.pythonhosted.org/packages/34/b0/ca92b90859070a1487827dbc672f998da95ce83edce1270fc23f96f1f61a/scikit_learn-1.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:7a1c43c8ec9fde528d664d947dc4c0789be4077a3647f232869f41d9bf50e0fb", size = 11071865 },
|
1738 |
+
{ url = "https://files.pythonhosted.org/packages/12/ae/993b0fb24a356e71e9a894e42b8a9eec528d4c70217353a1cd7a48bc25d4/scikit_learn-1.6.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a17c1dea1d56dcda2fac315712f3651a1fea86565b64b48fa1bc090249cbf236", size = 11955804 },
|
1739 |
+
{ url = "https://files.pythonhosted.org/packages/d6/54/32fa2ee591af44507eac86406fa6bba968d1eb22831494470d0a2e4a1eb1/scikit_learn-1.6.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:6a7aa5f9908f0f28f4edaa6963c0a6183f1911e63a69aa03782f0d924c830a35", size = 11100530 },
|
1740 |
+
{ url = "https://files.pythonhosted.org/packages/3f/58/55856da1adec655bdce77b502e94a267bf40a8c0b89f8622837f89503b5a/scikit_learn-1.6.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0650e730afb87402baa88afbf31c07b84c98272622aaba002559b614600ca691", size = 12433852 },
|
1741 |
+
{ url = "https://files.pythonhosted.org/packages/ff/4f/c83853af13901a574f8f13b645467285a48940f185b690936bb700a50863/scikit_learn-1.6.1-cp313-cp313t-win_amd64.whl", hash = "sha256:3f59fe08dc03ea158605170eb52b22a105f238a5d512c4470ddeca71feae8e5f", size = 11337256 },
|
1742 |
+
]
|
1743 |
+
|
1744 |
+
[[package]]
|
1745 |
+
name = "scipy"
|
1746 |
+
version = "1.15.2"
|
1747 |
+
source = { registry = "https://pypi.org/simple" }
|
1748 |
+
dependencies = [
|
1749 |
+
{ name = "numpy" },
|
1750 |
+
]
|
1751 |
+
sdist = { url = "https://files.pythonhosted.org/packages/b7/b9/31ba9cd990e626574baf93fbc1ac61cf9ed54faafd04c479117517661637/scipy-1.15.2.tar.gz", hash = "sha256:cd58a314d92838f7e6f755c8a2167ead4f27e1fd5c1251fd54289569ef3495ec", size = 59417316 }
|
1752 |
+
wheels = [
|
1753 |
+
{ url = "https://files.pythonhosted.org/packages/53/40/09319f6e0f276ea2754196185f95cd191cb852288440ce035d5c3a931ea2/scipy-1.15.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:01edfac9f0798ad6b46d9c4c9ca0e0ad23dbf0b1eb70e96adb9fa7f525eff0bf", size = 38717587 },
|
1754 |
+
{ url = "https://files.pythonhosted.org/packages/fe/c3/2854f40ecd19585d65afaef601e5e1f8dbf6758b2f95b5ea93d38655a2c6/scipy-1.15.2-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:08b57a9336b8e79b305a143c3655cc5bdbe6d5ece3378578888d2afbb51c4e37", size = 30100266 },
|
1755 |
+
{ url = "https://files.pythonhosted.org/packages/dd/b1/f9fe6e3c828cb5930b5fe74cb479de5f3d66d682fa8adb77249acaf545b8/scipy-1.15.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:54c462098484e7466362a9f1672d20888f724911a74c22ae35b61f9c5919183d", size = 22373768 },
|
1756 |
+
{ url = "https://files.pythonhosted.org/packages/15/9d/a60db8c795700414c3f681908a2b911e031e024d93214f2d23c6dae174ab/scipy-1.15.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:cf72ff559a53a6a6d77bd8eefd12a17995ffa44ad86c77a5df96f533d4e6c6bb", size = 25154719 },
|
1757 |
+
{ url = "https://files.pythonhosted.org/packages/37/3b/9bda92a85cd93f19f9ed90ade84aa1e51657e29988317fabdd44544f1dd4/scipy-1.15.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9de9d1416b3d9e7df9923ab23cd2fe714244af10b763975bea9e4f2e81cebd27", size = 35163195 },
|
1758 |
+
{ url = "https://files.pythonhosted.org/packages/03/5a/fc34bf1aa14dc7c0e701691fa8685f3faec80e57d816615e3625f28feb43/scipy-1.15.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb530e4794fc8ea76a4a21ccb67dea33e5e0e60f07fc38a49e821e1eae3b71a0", size = 37255404 },
|
1759 |
+
{ url = "https://files.pythonhosted.org/packages/4a/71/472eac45440cee134c8a180dbe4c01b3ec247e0338b7c759e6cd71f199a7/scipy-1.15.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5ea7ed46d437fc52350b028b1d44e002646e28f3e8ddc714011aaf87330f2f32", size = 36860011 },
|
1760 |
+
{ url = "https://files.pythonhosted.org/packages/01/b3/21f890f4f42daf20e4d3aaa18182dddb9192771cd47445aaae2e318f6738/scipy-1.15.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:11e7ad32cf184b74380f43d3c0a706f49358b904fa7d5345f16ddf993609184d", size = 39657406 },
|
1761 |
+
{ url = "https://files.pythonhosted.org/packages/0d/76/77cf2ac1f2a9cc00c073d49e1e16244e389dd88e2490c91d84e1e3e4d126/scipy-1.15.2-cp313-cp313-win_amd64.whl", hash = "sha256:a5080a79dfb9b78b768cebf3c9dcbc7b665c5875793569f48bf0e2b1d7f68f6f", size = 40961243 },
|
1762 |
+
{ url = "https://files.pythonhosted.org/packages/4c/4b/a57f8ddcf48e129e6054fa9899a2a86d1fc6b07a0e15c7eebff7ca94533f/scipy-1.15.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:447ce30cee6a9d5d1379087c9e474628dab3db4a67484be1b7dc3196bfb2fac9", size = 38870286 },
|
1763 |
+
{ url = "https://files.pythonhosted.org/packages/0c/43/c304d69a56c91ad5f188c0714f6a97b9c1fed93128c691148621274a3a68/scipy-1.15.2-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:c90ebe8aaa4397eaefa8455a8182b164a6cc1d59ad53f79943f266d99f68687f", size = 30141634 },
|
1764 |
+
{ url = "https://files.pythonhosted.org/packages/44/1a/6c21b45d2548eb73be9b9bff421aaaa7e85e22c1f9b3bc44b23485dfce0a/scipy-1.15.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:def751dd08243934c884a3221156d63e15234a3155cf25978b0a668409d45eb6", size = 22415179 },
|
1765 |
+
{ url = "https://files.pythonhosted.org/packages/74/4b/aefac4bba80ef815b64f55da06f62f92be5d03b467f2ce3668071799429a/scipy-1.15.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:302093e7dfb120e55515936cb55618ee0b895f8bcaf18ff81eca086c17bd80af", size = 25126412 },
|
1766 |
+
{ url = "https://files.pythonhosted.org/packages/b1/53/1cbb148e6e8f1660aacd9f0a9dfa2b05e9ff1cb54b4386fe868477972ac2/scipy-1.15.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7cd5b77413e1855351cdde594eca99c1f4a588c2d63711388b6a1f1c01f62274", size = 34952867 },
|
1767 |
+
{ url = "https://files.pythonhosted.org/packages/2c/23/e0eb7f31a9c13cf2dca083828b97992dd22f8184c6ce4fec5deec0c81fcf/scipy-1.15.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d0194c37037707b2afa7a2f2a924cf7bac3dc292d51b6a925e5fcb89bc5c776", size = 36890009 },
|
1768 |
+
{ url = "https://files.pythonhosted.org/packages/03/f3/e699e19cabe96bbac5189c04aaa970718f0105cff03d458dc5e2b6bd1e8c/scipy-1.15.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:bae43364d600fdc3ac327db99659dcb79e6e7ecd279a75fe1266669d9a652828", size = 36545159 },
|
1769 |
+
{ url = "https://files.pythonhosted.org/packages/af/f5/ab3838e56fe5cc22383d6fcf2336e48c8fe33e944b9037fbf6cbdf5a11f8/scipy-1.15.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f031846580d9acccd0044efd1a90e6f4df3a6e12b4b6bd694a7bc03a89892b28", size = 39136566 },
|
1770 |
+
{ url = "https://files.pythonhosted.org/packages/0a/c8/b3f566db71461cabd4b2d5b39bcc24a7e1c119535c8361f81426be39bb47/scipy-1.15.2-cp313-cp313t-win_amd64.whl", hash = "sha256:fe8a9eb875d430d81755472c5ba75e84acc980e4a8f6204d402849234d3017db", size = 40477705 },
|
1771 |
+
]
|
1772 |
+
|
1773 |
[[package]]
|
1774 |
name = "setuptools"
|
1775 |
version = "75.8.0"
|
|
|
1875 |
{ url = "https://files.pythonhosted.org/packages/b6/cb/b86984bed139586d01532a587464b5805f12e397594f19f931c4c2fbfa61/tenacity-9.0.0-py3-none-any.whl", hash = "sha256:93de0c98785b27fcf659856aa9f54bfbd399e29969b0621bc7f762bd441b4539", size = 28169 },
|
1876 |
]
|
1877 |
|
1878 |
+
[[package]]
|
1879 |
+
name = "threadpoolctl"
|
1880 |
+
version = "3.5.0"
|
1881 |
+
source = { registry = "https://pypi.org/simple" }
|
1882 |
+
sdist = { url = "https://files.pythonhosted.org/packages/bd/55/b5148dcbf72f5cde221f8bfe3b6a540da7aa1842f6b491ad979a6c8b84af/threadpoolctl-3.5.0.tar.gz", hash = "sha256:082433502dd922bf738de0d8bcc4fdcbf0979ff44c42bd40f5af8a282f6fa107", size = 41936 }
|
1883 |
+
wheels = [
|
1884 |
+
{ url = "https://files.pythonhosted.org/packages/4b/2c/ffbf7a134b9ab11a67b0cf0726453cedd9c5043a4fe7a35d1cefa9a1bcfb/threadpoolctl-3.5.0-py3-none-any.whl", hash = "sha256:56c1e26c150397e58c4926da8eeee87533b1e32bef131bd4bf6a2f45f3185467", size = 18414 },
|
1885 |
+
]
|
1886 |
+
|
1887 |
[[package]]
|
1888 |
name = "tiktoken"
|
1889 |
version = "0.9.0"
|