Humanlearning commited on
Commit
8417a25
·
1 Parent(s): ab7953b

+ testing code written

Browse files
__pycache__/app.cpython-313.pyc ADDED
Binary file (13.2 kB). View file
 
__pycache__/basic_agent.cpython-313.pyc ADDED
Binary file (1.88 kB). View file
 
__pycache__/langraph_agent.cpython-313.pyc CHANGED
Binary files a/__pycache__/langraph_agent.cpython-313.pyc and b/__pycache__/langraph_agent.cpython-313.pyc differ
 
basic_agent.py ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ """A light-weight module that exposes the BasicAgent class and DEFAULT_API_URL constant.
4
+
5
+ Importing from this file is safe in CLI/unit-test contexts because it has **no** side
6
+ effects such as instantiating a Gradio Blocks UI or requiring the optional OAuth
7
+ dependencies of Gradio.
8
+ """
9
+
10
+ import logging
11
+
12
+ from langchain_core.messages import HumanMessage
13
+
14
+ from langraph_agent import build_graph
15
+
16
+ # Keep the public API identical to `app.py` so existing imports can be switched
17
+ # from `from app import BasicAgent, DEFAULT_API_URL` to
18
+ # `from basic_agent import BasicAgent, DEFAULT_API_URL` without further changes.
19
+ DEFAULT_API_URL: str = "https://agents-course-unit4-scoring.hf.space"
20
+
21
+
22
+ class BasicAgent: # pylint: disable=too-few-public-methods
23
+ """A minimal wrapper around the LangGraph agent used in this repo."""
24
+
25
+ def __init__(self) -> None:
26
+ # Building the graph can be an expensive operation; log it explicitly so
27
+ # users have feedback when the constructor blocks for a moment.
28
+ logging.debug("[BasicAgent] Building LangGraph …")
29
+ self.agent = build_graph()
30
+ logging.debug("[BasicAgent] LangGraph ready.")
31
+
32
+ async def aquery(self, question: str) -> str:
33
+ """Asynchronously ask the agent a question and return the raw answer text."""
34
+ messages = [HumanMessage(content=question)]
35
+ response = await self.agent.ainvoke({"messages": messages})
36
+ if isinstance(response, dict) and response.get("messages"):
37
+ return response["messages"][-1].content
38
+ return str(response)
pyproject.toml CHANGED
@@ -6,6 +6,7 @@ readme = "README.md"
6
  requires-python = ">=3.13"
7
  dependencies = [
8
  "dotenv>=0.9.9",
 
9
  "hf-xet>=1.1.3",
10
  "huggingface-hub[hf-xet]>=0.32.4",
11
  "ipykernel>=6.29.5",
 
6
  requires-python = ">=3.13"
7
  dependencies = [
8
  "dotenv>=0.9.9",
9
+ "gradio>=5.34.1",
10
  "hf-xet>=1.1.3",
11
  "huggingface-hub[hf-xet]>=0.32.4",
12
  "ipykernel>=6.29.5",
quick_random_agent_test.py ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import tempfile
3
+ import requests
4
+ from basic_agent import BasicAgent, DEFAULT_API_URL
5
+ from langchain_core.messages import HumanMessage
6
+ from langfuse.langchain import CallbackHandler
7
+
8
+ # Initialize Langfuse CallbackHandler for LangGraph/Langchain (tracing)
9
+ try:
10
+ langfuse_handler = CallbackHandler()
11
+ except Exception as e:
12
+ print(f"Warning: Could not initialize Langfuse handler: {e}")
13
+ langfuse_handler = None
14
+
15
+ def fetch_random_question(api_base: str = DEFAULT_API_URL):
16
+ """Return JSON of /random-question."""
17
+ resp = requests.get(f"{api_base}/random-question", timeout=30)
18
+ resp.raise_for_status()
19
+ return resp.json()
20
+
21
+
22
+ def maybe_download_file(task_id: str, api_base: str = DEFAULT_API_URL) -> str | None:
23
+ """Try to download the file associated with a given task id. Returns local path or None."""
24
+ url = f"{api_base}/files/{task_id}"
25
+ try:
26
+ resp = requests.get(url, timeout=60)
27
+ if resp.status_code != 200:
28
+ print(f"No file associated with task {task_id} (status {resp.status_code}).")
29
+ return None
30
+ # Create temp file with same name from headers if available
31
+ filename = resp.headers.get("content-disposition", "").split("filename=")[-1].strip("\"") or f"{task_id}_attachment"
32
+ tmp_path = os.path.join(tempfile.gettempdir(), filename)
33
+ with open(tmp_path, "wb") as f:
34
+ f.write(resp.content)
35
+ print(f"Downloaded attachment to {tmp_path}")
36
+ return tmp_path
37
+ except requests.HTTPError as e:
38
+ print(f"Could not download file for task {task_id}: {e}")
39
+ except Exception as e:
40
+ print(f"Error downloading file: {e}")
41
+ return None
42
+
43
+
44
+ def main():
45
+ q = fetch_random_question()
46
+ task_id = str(q["task_id"])
47
+ question_text = q["question"]
48
+ print("\n=== Random Question ===")
49
+ print(f"Task ID : {task_id}")
50
+ print(f"Question: {question_text}")
51
+
52
+ # Attempt to get attachment if any
53
+ maybe_download_file(task_id)
54
+
55
+ # Run the agent
56
+ agent = BasicAgent()
57
+ result = agent.agent.invoke({"messages": [HumanMessage(content=question_text)]}, config={"callbacks": [langfuse_handler]})
58
+ if isinstance(result, dict) and "messages" in result and result["messages"]:
59
+ answer = result["messages"][-1].content.strip()
60
+ else:
61
+ answer = str(result)
62
+ print("\n=== Agent Answer ===")
63
+ print(answer)
64
+
65
+
66
+ if __name__ == "__main__":
67
+ main()
test_random_question.py ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import requests
3
+ from datasets import load_dataset
4
+ from basic_agent import BasicAgent, DEFAULT_API_URL
5
+ from langchain_core.messages import HumanMessage
6
+
7
+ # Server-side filtering parameters (keep in sync with scoring API)
8
+ TOOL_THRESHOLD = 3
9
+ STEP_THRESHOLD = 6
10
+
11
+
12
+ def build_ground_truth_mapping():
13
+ """Return a dict mapping task_id -> final_answer for the filtered GAIA validation set."""
14
+ print("Loading GAIA benchmark validation split… (this may take a minute)")
15
+ ds = load_dataset("gaia-benchmark/GAIA", "2023_level1", split="validation", trust_remote_code=True)
16
+
17
+ mapping = {}
18
+ for item in ds:
19
+ meta = item.get("Annotator Metadata") or {}
20
+ try:
21
+ n_tools = int(meta.get("Number of tools", 99))
22
+ n_steps = int(meta.get("Number of steps", 99))
23
+ except ValueError:
24
+ continue # skip malformed counts
25
+
26
+ if n_tools < TOOL_THRESHOLD and n_steps < STEP_THRESHOLD:
27
+ task_id = str(item["task_id"])
28
+ mapping[task_id] = str(item["Final answer"])
29
+ print(f"Ground-truth map built for {len(mapping)} tasks.")
30
+ return mapping
31
+
32
+
33
+ def fetch_random_question(api_base: str = DEFAULT_API_URL):
34
+ """GET /random-question from the scoring API and return its JSON.
35
+ Raises requests.HTTPError on failure."""
36
+ url = f"{api_base}/random-question"
37
+ resp = requests.get(url, timeout=30)
38
+ resp.raise_for_status()
39
+ return resp.json()
40
+
41
+
42
+ def main():
43
+ gt = build_ground_truth_mapping()
44
+
45
+ q = fetch_random_question()
46
+ task_id = str(q["task_id"])
47
+ question_text = q["question"]
48
+
49
+ print("\n=== Random Question ===")
50
+ print(f"Task ID : {task_id}")
51
+ print(f"Question: {question_text}\n")
52
+
53
+ agent = BasicAgent()
54
+ answer = agent.agent.invoke({"messages": [HumanMessage(content=question_text)]}) # sync invoke for simplicity
55
+ # If agent.aquery exists (async), you could run via asyncio.run; here we keep it simple.
56
+
57
+ if isinstance(answer, dict) and "messages" in answer and answer["messages"]:
58
+ answer_str = answer["messages"][-1].content.strip()
59
+ else:
60
+ print("Agent returned unexpected structure – treating as error.")
61
+ answer_str = ""
62
+
63
+ print(f"Agent answer: {answer_str}")
64
+
65
+ gt_answer = gt.get(task_id)
66
+ if gt_answer is None:
67
+ print("Ground-truth answer not found for this task ID. Filtering may be out of sync with the server.")
68
+ return
69
+
70
+ print(f"Ground truth: {gt_answer}")
71
+
72
+ if answer_str.strip().lower() == gt_answer.strip().lower():
73
+ print("✅ Correct!")
74
+ else:
75
+ print("❌ Incorrect.")
76
+
77
+
78
+ if __name__ == "__main__":
79
+ main()
uv.lock CHANGED
@@ -2,6 +2,15 @@ version = 1
2
  revision = 1
3
  requires-python = ">=3.13"
4
 
 
 
 
 
 
 
 
 
 
5
  [[package]]
6
  name = "aiohappyeyeballs"
7
  version = "2.6.1"
@@ -131,6 +140,46 @@ wheels = [
131
  { url = "https://files.pythonhosted.org/packages/77/06/bb80f5f86020c4551da315d78b3ab75e8228f89f0162f2c3a819e407941a/attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", size = 63815 },
132
  ]
133
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134
  [[package]]
135
  name = "backoff"
136
  version = "2.2.1"
@@ -383,6 +432,20 @@ wheels = [
383
  { url = "https://files.pythonhosted.org/packages/7b/8f/c4d9bafc34ad7ad5d8dc16dd1347ee0e507a52c3adb6bfa8887e1c6a26ba/executing-2.2.0-py2.py3-none-any.whl", hash = "sha256:11387150cad388d62750327a53d3339fad4888b39a6fe233c3afbb54ecffd3aa", size = 26702 },
384
  ]
385
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
386
  [[package]]
387
  name = "feedparser"
388
  version = "6.0.11"
@@ -395,6 +458,15 @@ wheels = [
395
  { url = "https://files.pythonhosted.org/packages/7c/d4/8c31aad9cc18f451c49f7f9cfb5799dadffc88177f7917bc90a66459b1d7/feedparser-6.0.11-py3-none-any.whl", hash = "sha256:0be7ee7b395572b19ebeb1d6aafb0028dee11169f1c934e0ed67d54992f4ad45", size = 81343 },
396
  ]
397
 
 
 
 
 
 
 
 
 
 
398
  [[package]]
399
  name = "filelock"
400
  version = "3.18.0"
@@ -419,6 +491,7 @@ version = "0.1.0"
419
  source = { virtual = "." }
420
  dependencies = [
421
  { name = "dotenv" },
 
422
  { name = "hf-xet" },
423
  { name = "huggingface-hub", extra = ["hf-xet"] },
424
  { name = "ipykernel" },
@@ -446,6 +519,7 @@ dependencies = [
446
  [package.metadata]
447
  requires-dist = [
448
  { name = "dotenv", specifier = ">=0.9.9" },
 
449
  { name = "hf-xet", specifier = ">=1.1.3" },
450
  { name = "huggingface-hub", extras = ["hf-xet"], specifier = ">=0.32.4" },
451
  { name = "ipykernel", specifier = ">=6.29.5" },
@@ -600,6 +674,63 @@ wheels = [
600
  { url = "https://files.pythonhosted.org/packages/ee/5c/fe0dd370294c782fc1f627bb7e3eedd87c3d4d7f8d2b39fe8dd63c3096a8/gotrue-2.12.0-py3-none-any.whl", hash = "sha256:de94928eebb42d7d9672dbe4fbd0b51140a45051a31626a06dad2ad44a9a976a", size = 43649 },
601
  ]
602
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
603
  [[package]]
604
  name = "greenlet"
605
  version = "3.2.3"
@@ -636,6 +767,15 @@ wheels = [
636
  { url = "https://files.pythonhosted.org/packages/58/c6/5c20af38c2a57c15d87f7f38bee77d63c1d2a3689f74fefaf35915dd12b2/griffe-1.7.3-py3-none-any.whl", hash = "sha256:c6b3ee30c2f0f17f30bcdef5068d6ab7a2a4f1b8bf1a3e74b56fffd21e1c5f75", size = 129303 },
637
  ]
638
 
 
 
 
 
 
 
 
 
 
639
  [[package]]
640
  name = "groq"
641
  version = "0.28.0"
@@ -2381,6 +2521,15 @@ wheels = [
2381
  { url = "https://files.pythonhosted.org/packages/b6/5f/d6d641b490fd3ec2c4c13b4244d68deea3a1b970a97be64f34fb5504ff72/pydantic_settings-2.9.1-py3-none-any.whl", hash = "sha256:59b4f431b1defb26fe620c71a7d3968a710d719f5f4cdbbdb7926edeb770f6ef", size = 44356 },
2382
  ]
2383
 
 
 
 
 
 
 
 
 
 
2384
  [[package]]
2385
  name = "pygments"
2386
  version = "2.19.1"
@@ -2457,6 +2606,15 @@ wheels = [
2457
  { url = "https://files.pythonhosted.org/packages/1e/18/98a99ad95133c6a6e2005fe89faedf294a748bd5dc803008059409ac9b1e/python_dotenv-1.1.0-py3-none-any.whl", hash = "sha256:d7c01d9e2293916c18baf562d95698754b0dbbb5e74d457c45d4f6561fb9d55d", size = 20256 },
2458
  ]
2459
 
 
 
 
 
 
 
 
 
 
2460
  [[package]]
2461
  name = "pytz"
2462
  version = "2025.2"
@@ -2613,6 +2771,43 @@ wheels = [
2613
  { url = "https://files.pythonhosted.org/packages/64/8d/0133e4eb4beed9e425d9a98ed6e081a55d195481b7632472be1af08d2f6b/rsa-4.9.1-py3-none-any.whl", hash = "sha256:68635866661c6836b8d39430f97a996acbd61bfa49406748ea243539fe239762", size = 34696 },
2614
  ]
2615
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2616
  [[package]]
2617
  name = "safetensors"
2618
  version = "0.5.3"
@@ -2687,6 +2882,15 @@ wheels = [
2687
  { url = "https://files.pythonhosted.org/packages/81/06/0a5e5349474e1cbc5757975b21bd4fad0e72ebf138c5592f191646154e06/scipy-1.15.3-cp313-cp313t-win_amd64.whl", hash = "sha256:76ad1fb5f8752eabf0fa02e4cc0336b4e8f021e2d5f061ed37d6d264db35e3ca", size = 40308097 },
2688
  ]
2689
 
 
 
 
 
 
 
 
 
 
2690
  [[package]]
2691
  name = "sentence-transformers"
2692
  version = "4.1.0"
@@ -2721,6 +2925,15 @@ version = "1.0.0"
2721
  source = { registry = "https://pypi.org/simple" }
2722
  sdist = { url = "https://files.pythonhosted.org/packages/9e/bd/3704a8c3e0942d711c1299ebf7b9091930adae6675d7c8f476a7ce48653c/sgmllib3k-1.0.0.tar.gz", hash = "sha256:7868fb1c8bfa764c1ac563d3cf369c381d1325d36124933a726f29fcdaa812e9", size = 5750 }
2723
 
 
 
 
 
 
 
 
 
 
2724
  [[package]]
2725
  name = "six"
2726
  version = "1.17.0"
@@ -2788,6 +3001,18 @@ wheels = [
2788
  { url = "https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695", size = 24521 },
2789
  ]
2790
 
 
 
 
 
 
 
 
 
 
 
 
 
2791
  [[package]]
2792
  name = "storage3"
2793
  version = "0.11.3"
@@ -2936,6 +3161,15 @@ wheels = [
2936
  { url = "https://files.pythonhosted.org/packages/e6/b6/072a8e053ae600dcc2ac0da81a23548e3b523301a442a6ca900e92ac35be/tokenizers-0.21.1-cp39-abi3-win_amd64.whl", hash = "sha256:0f0dcbcc9f6e13e675a66d7a5f2f225a736745ce484c1a4e07476a89ccdad382", size = 2435481 },
2937
  ]
2938
 
 
 
 
 
 
 
 
 
 
2939
  [[package]]
2940
  name = "torch"
2941
  version = "2.7.1"
@@ -3048,6 +3282,21 @@ wheels = [
3048
  { url = "https://files.pythonhosted.org/packages/28/71/bd20ffcb7a64c753dc2463489a61bf69d531f308e390ad06390268c4ea04/triton-3.3.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a3198adb9d78b77818a5388bff89fa72ff36f9da0bc689db2f0a651a67ce6a42", size = 155735832 },
3049
  ]
3050
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3051
  [[package]]
3052
  name = "typing-extensions"
3053
  version = "4.14.0"
@@ -3100,6 +3349,19 @@ wheels = [
3100
  { url = "https://files.pythonhosted.org/packages/6b/11/cc635220681e93a0183390e26485430ca2c7b5f9d33b15c74c2861cb8091/urllib3-2.4.0-py3-none-any.whl", hash = "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813", size = 128680 },
3101
  ]
3102
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3103
  [[package]]
3104
  name = "wcwidth"
3105
  version = "0.2.13"
 
2
  revision = 1
3
  requires-python = ">=3.13"
4
 
5
+ [[package]]
6
+ name = "aiofiles"
7
+ version = "24.1.0"
8
+ source = { registry = "https://pypi.org/simple" }
9
+ sdist = { url = "https://files.pythonhosted.org/packages/0b/03/a88171e277e8caa88a4c77808c20ebb04ba74cc4681bf1e9416c862de237/aiofiles-24.1.0.tar.gz", hash = "sha256:22a075c9e5a3810f0c2e48f3008c94d68c65d763b9b03857924c99e57355166c", size = 30247 }
10
+ wheels = [
11
+ { url = "https://files.pythonhosted.org/packages/a5/45/30bb92d442636f570cb5651bc661f52b610e2eec3f891a5dc3a4c3667db0/aiofiles-24.1.0-py3-none-any.whl", hash = "sha256:b4ec55f4195e3eb5d7abd1bf7e061763e864dd4954231fb8539a0ef8bb8260e5", size = 15896 },
12
+ ]
13
+
14
  [[package]]
15
  name = "aiohappyeyeballs"
16
  version = "2.6.1"
 
140
  { url = "https://files.pythonhosted.org/packages/77/06/bb80f5f86020c4551da315d78b3ab75e8228f89f0162f2c3a819e407941a/attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", size = 63815 },
141
  ]
142
 
143
+ [[package]]
144
+ name = "audioop-lts"
145
+ version = "0.2.1"
146
+ source = { registry = "https://pypi.org/simple" }
147
+ sdist = { url = "https://files.pythonhosted.org/packages/dd/3b/69ff8a885e4c1c42014c2765275c4bd91fe7bc9847e9d8543dbcbb09f820/audioop_lts-0.2.1.tar.gz", hash = "sha256:e81268da0baa880431b68b1308ab7257eb33f356e57a5f9b1f915dfb13dd1387", size = 30204 }
148
+ wheels = [
149
+ { url = "https://files.pythonhosted.org/packages/01/91/a219253cc6e92db2ebeaf5cf8197f71d995df6f6b16091d1f3ce62cb169d/audioop_lts-0.2.1-cp313-abi3-macosx_10_13_universal2.whl", hash = "sha256:fd1345ae99e17e6910f47ce7d52673c6a1a70820d78b67de1b7abb3af29c426a", size = 46252 },
150
+ { url = "https://files.pythonhosted.org/packages/ec/f6/3cb21e0accd9e112d27cee3b1477cd04dafe88675c54ad8b0d56226c1e0b/audioop_lts-0.2.1-cp313-abi3-macosx_10_13_x86_64.whl", hash = "sha256:e175350da05d2087e12cea8e72a70a1a8b14a17e92ed2022952a4419689ede5e", size = 27183 },
151
+ { url = "https://files.pythonhosted.org/packages/ea/7e/f94c8a6a8b2571694375b4cf94d3e5e0f529e8e6ba280fad4d8c70621f27/audioop_lts-0.2.1-cp313-abi3-macosx_11_0_arm64.whl", hash = "sha256:4a8dd6a81770f6ecf019c4b6d659e000dc26571b273953cef7cd1d5ce2ff3ae6", size = 26726 },
152
+ { url = "https://files.pythonhosted.org/packages/ef/f8/a0e8e7a033b03fae2b16bc5aa48100b461c4f3a8a38af56d5ad579924a3a/audioop_lts-0.2.1-cp313-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1cd3c0b6f2ca25c7d2b1c3adeecbe23e65689839ba73331ebc7d893fcda7ffe", size = 80718 },
153
+ { url = "https://files.pythonhosted.org/packages/8f/ea/a98ebd4ed631c93b8b8f2368862cd8084d75c77a697248c24437c36a6f7e/audioop_lts-0.2.1-cp313-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ff3f97b3372c97782e9c6d3d7fdbe83bce8f70de719605bd7ee1839cd1ab360a", size = 88326 },
154
+ { url = "https://files.pythonhosted.org/packages/33/79/e97a9f9daac0982aa92db1199339bd393594d9a4196ad95ae088635a105f/audioop_lts-0.2.1-cp313-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a351af79edefc2a1bd2234bfd8b339935f389209943043913a919df4b0f13300", size = 80539 },
155
+ { url = "https://files.pythonhosted.org/packages/b2/d3/1051d80e6f2d6f4773f90c07e73743a1e19fcd31af58ff4e8ef0375d3a80/audioop_lts-0.2.1-cp313-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2aeb6f96f7f6da80354330470b9134d81b4cf544cdd1c549f2f45fe964d28059", size = 78577 },
156
+ { url = "https://files.pythonhosted.org/packages/7a/1d/54f4c58bae8dc8c64a75071c7e98e105ddaca35449376fcb0180f6e3c9df/audioop_lts-0.2.1-cp313-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c589f06407e8340e81962575fcffbba1e92671879a221186c3d4662de9fe804e", size = 82074 },
157
+ { url = "https://files.pythonhosted.org/packages/36/89/2e78daa7cebbea57e72c0e1927413be4db675548a537cfba6a19040d52fa/audioop_lts-0.2.1-cp313-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:fbae5d6925d7c26e712f0beda5ed69ebb40e14212c185d129b8dfbfcc335eb48", size = 84210 },
158
+ { url = "https://files.pythonhosted.org/packages/a5/57/3ff8a74df2ec2fa6d2ae06ac86e4a27d6412dbb7d0e0d41024222744c7e0/audioop_lts-0.2.1-cp313-abi3-musllinux_1_2_i686.whl", hash = "sha256:d2d5434717f33117f29b5691fbdf142d36573d751716249a288fbb96ba26a281", size = 85664 },
159
+ { url = "https://files.pythonhosted.org/packages/16/01/21cc4e5878f6edbc8e54be4c108d7cb9cb6202313cfe98e4ece6064580dd/audioop_lts-0.2.1-cp313-abi3-musllinux_1_2_ppc64le.whl", hash = "sha256:f626a01c0a186b08f7ff61431c01c055961ee28769591efa8800beadd27a2959", size = 93255 },
160
+ { url = "https://files.pythonhosted.org/packages/3e/28/7f7418c362a899ac3b0bf13b1fde2d4ffccfdeb6a859abd26f2d142a1d58/audioop_lts-0.2.1-cp313-abi3-musllinux_1_2_s390x.whl", hash = "sha256:05da64e73837f88ee5c6217d732d2584cf638003ac72df124740460531e95e47", size = 87760 },
161
+ { url = "https://files.pythonhosted.org/packages/6d/d8/577a8be87dc7dd2ba568895045cee7d32e81d85a7e44a29000fe02c4d9d4/audioop_lts-0.2.1-cp313-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:56b7a0a4dba8e353436f31a932f3045d108a67b5943b30f85a5563f4d8488d77", size = 84992 },
162
+ { url = "https://files.pythonhosted.org/packages/ef/9a/4699b0c4fcf89936d2bfb5425f55f1a8b86dff4237cfcc104946c9cd9858/audioop_lts-0.2.1-cp313-abi3-win32.whl", hash = "sha256:6e899eb8874dc2413b11926b5fb3857ec0ab55222840e38016a6ba2ea9b7d5e3", size = 26059 },
163
+ { url = "https://files.pythonhosted.org/packages/3a/1c/1f88e9c5dd4785a547ce5fd1eb83fff832c00cc0e15c04c1119b02582d06/audioop_lts-0.2.1-cp313-abi3-win_amd64.whl", hash = "sha256:64562c5c771fb0a8b6262829b9b4f37a7b886c01b4d3ecdbae1d629717db08b4", size = 30412 },
164
+ { url = "https://files.pythonhosted.org/packages/c4/e9/c123fd29d89a6402ad261516f848437472ccc602abb59bba522af45e281b/audioop_lts-0.2.1-cp313-abi3-win_arm64.whl", hash = "sha256:c45317debeb64002e980077642afbd977773a25fa3dfd7ed0c84dccfc1fafcb0", size = 23578 },
165
+ { url = "https://files.pythonhosted.org/packages/7a/99/bb664a99561fd4266687e5cb8965e6ec31ba4ff7002c3fce3dc5ef2709db/audioop_lts-0.2.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:3827e3fce6fee4d69d96a3d00cd2ab07f3c0d844cb1e44e26f719b34a5b15455", size = 46827 },
166
+ { url = "https://files.pythonhosted.org/packages/c4/e3/f664171e867e0768ab982715e744430cf323f1282eb2e11ebfb6ee4c4551/audioop_lts-0.2.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:161249db9343b3c9780ca92c0be0d1ccbfecdbccac6844f3d0d44b9c4a00a17f", size = 27479 },
167
+ { url = "https://files.pythonhosted.org/packages/a6/0d/2a79231ff54eb20e83b47e7610462ad6a2bea4e113fae5aa91c6547e7764/audioop_lts-0.2.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5b7b4ff9de7a44e0ad2618afdc2ac920b91f4a6d3509520ee65339d4acde5abf", size = 27056 },
168
+ { url = "https://files.pythonhosted.org/packages/86/46/342471398283bb0634f5a6df947806a423ba74b2e29e250c7ec0e3720e4f/audioop_lts-0.2.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:72e37f416adb43b0ced93419de0122b42753ee74e87070777b53c5d2241e7fab", size = 87802 },
169
+ { url = "https://files.pythonhosted.org/packages/56/44/7a85b08d4ed55517634ff19ddfbd0af05bf8bfd39a204e4445cd0e6f0cc9/audioop_lts-0.2.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:534ce808e6bab6adb65548723c8cbe189a3379245db89b9d555c4210b4aaa9b6", size = 95016 },
170
+ { url = "https://files.pythonhosted.org/packages/a8/2a/45edbca97ea9ee9e6bbbdb8d25613a36e16a4d1e14ae01557392f15cc8d3/audioop_lts-0.2.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d2de9b6fb8b1cf9f03990b299a9112bfdf8b86b6987003ca9e8a6c4f56d39543", size = 87394 },
171
+ { url = "https://files.pythonhosted.org/packages/14/ae/832bcbbef2c510629593bf46739374174606e25ac7d106b08d396b74c964/audioop_lts-0.2.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f24865991b5ed4b038add5edbf424639d1358144f4e2a3e7a84bc6ba23e35074", size = 84874 },
172
+ { url = "https://files.pythonhosted.org/packages/26/1c/8023c3490798ed2f90dfe58ec3b26d7520a243ae9c0fc751ed3c9d8dbb69/audioop_lts-0.2.1-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bdb3b7912ccd57ea53197943f1bbc67262dcf29802c4a6df79ec1c715d45a78", size = 88698 },
173
+ { url = "https://files.pythonhosted.org/packages/2c/db/5379d953d4918278b1f04a5a64b2c112bd7aae8f81021009da0dcb77173c/audioop_lts-0.2.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:120678b208cca1158f0a12d667af592e067f7a50df9adc4dc8f6ad8d065a93fb", size = 90401 },
174
+ { url = "https://files.pythonhosted.org/packages/99/6e/3c45d316705ab1aec2e69543a5b5e458d0d112a93d08994347fafef03d50/audioop_lts-0.2.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:54cd4520fc830b23c7d223693ed3e1b4d464997dd3abc7c15dce9a1f9bd76ab2", size = 91864 },
175
+ { url = "https://files.pythonhosted.org/packages/08/58/6a371d8fed4f34debdb532c0b00942a84ebf3e7ad368e5edc26931d0e251/audioop_lts-0.2.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:d6bd20c7a10abcb0fb3d8aaa7508c0bf3d40dfad7515c572014da4b979d3310a", size = 98796 },
176
+ { url = "https://files.pythonhosted.org/packages/ee/77/d637aa35497e0034ff846fd3330d1db26bc6fd9dd79c406e1341188b06a2/audioop_lts-0.2.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:f0ed1ad9bd862539ea875fb339ecb18fcc4148f8d9908f4502df28f94d23491a", size = 94116 },
177
+ { url = "https://files.pythonhosted.org/packages/1a/60/7afc2abf46bbcf525a6ebc0305d85ab08dc2d1e2da72c48dbb35eee5b62c/audioop_lts-0.2.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:e1af3ff32b8c38a7d900382646e91f2fc515fd19dea37e9392275a5cbfdbff63", size = 91520 },
178
+ { url = "https://files.pythonhosted.org/packages/65/6d/42d40da100be1afb661fd77c2b1c0dfab08af1540df57533621aea3db52a/audioop_lts-0.2.1-cp313-cp313t-win32.whl", hash = "sha256:f51bb55122a89f7a0817d7ac2319744b4640b5b446c4c3efcea5764ea99ae509", size = 26482 },
179
+ { url = "https://files.pythonhosted.org/packages/01/09/f08494dca79f65212f5b273aecc5a2f96691bf3307cac29acfcf84300c01/audioop_lts-0.2.1-cp313-cp313t-win_amd64.whl", hash = "sha256:f0f2f336aa2aee2bce0b0dcc32bbba9178995454c7b979cf6ce086a8801e14c7", size = 30780 },
180
+ { url = "https://files.pythonhosted.org/packages/5d/35/be73b6015511aa0173ec595fc579133b797ad532996f2998fd6b8d1bbe6b/audioop_lts-0.2.1-cp313-cp313t-win_arm64.whl", hash = "sha256:78bfb3703388c780edf900be66e07de5a3d4105ca8e8720c5c4d67927e0b15d0", size = 23918 },
181
+ ]
182
+
183
  [[package]]
184
  name = "backoff"
185
  version = "2.2.1"
 
432
  { url = "https://files.pythonhosted.org/packages/7b/8f/c4d9bafc34ad7ad5d8dc16dd1347ee0e507a52c3adb6bfa8887e1c6a26ba/executing-2.2.0-py2.py3-none-any.whl", hash = "sha256:11387150cad388d62750327a53d3339fad4888b39a6fe233c3afbb54ecffd3aa", size = 26702 },
433
  ]
434
 
435
+ [[package]]
436
+ name = "fastapi"
437
+ version = "0.115.13"
438
+ source = { registry = "https://pypi.org/simple" }
439
+ dependencies = [
440
+ { name = "pydantic" },
441
+ { name = "starlette" },
442
+ { name = "typing-extensions" },
443
+ ]
444
+ sdist = { url = "https://files.pythonhosted.org/packages/20/64/ec0788201b5554e2a87c49af26b77a4d132f807a0fa9675257ac92c6aa0e/fastapi-0.115.13.tar.gz", hash = "sha256:55d1d25c2e1e0a0a50aceb1c8705cd932def273c102bff0b1c1da88b3c6eb307", size = 295680 }
445
+ wheels = [
446
+ { url = "https://files.pythonhosted.org/packages/59/4a/e17764385382062b0edbb35a26b7cf76d71e27e456546277a42ba6545c6e/fastapi-0.115.13-py3-none-any.whl", hash = "sha256:0a0cab59afa7bab22f5eb347f8c9864b681558c278395e94035a741fc10cd865", size = 95315 },
447
+ ]
448
+
449
  [[package]]
450
  name = "feedparser"
451
  version = "6.0.11"
 
458
  { url = "https://files.pythonhosted.org/packages/7c/d4/8c31aad9cc18f451c49f7f9cfb5799dadffc88177f7917bc90a66459b1d7/feedparser-6.0.11-py3-none-any.whl", hash = "sha256:0be7ee7b395572b19ebeb1d6aafb0028dee11169f1c934e0ed67d54992f4ad45", size = 81343 },
459
  ]
460
 
461
+ [[package]]
462
+ name = "ffmpy"
463
+ version = "0.6.0"
464
+ source = { registry = "https://pypi.org/simple" }
465
+ sdist = { url = "https://files.pythonhosted.org/packages/38/0d/5d2411c1db5d734fbbc547d1049c679536513cea2c97124b3b90228dfb41/ffmpy-0.6.0.tar.gz", hash = "sha256:332dd93198a162db61e527e866a04578d3713e577bfe68f2ed26ba9d09dbc948", size = 4955 }
466
+ wheels = [
467
+ { url = "https://files.pythonhosted.org/packages/cb/2f/932f05d6c63e206baf1cb8ad6034f6eac6fe8dfdae86a74044216d4987fc/ffmpy-0.6.0-py3-none-any.whl", hash = "sha256:c8369bf45f8bd5285ebad94c4a789a79e7af86eded74c1f8c36eccf57aaea58c", size = 5513 },
468
+ ]
469
+
470
  [[package]]
471
  name = "filelock"
472
  version = "3.18.0"
 
491
  source = { virtual = "." }
492
  dependencies = [
493
  { name = "dotenv" },
494
+ { name = "gradio" },
495
  { name = "hf-xet" },
496
  { name = "huggingface-hub", extra = ["hf-xet"] },
497
  { name = "ipykernel" },
 
519
  [package.metadata]
520
  requires-dist = [
521
  { name = "dotenv", specifier = ">=0.9.9" },
522
+ { name = "gradio", specifier = ">=5.34.1" },
523
  { name = "hf-xet", specifier = ">=1.1.3" },
524
  { name = "huggingface-hub", extras = ["hf-xet"], specifier = ">=0.32.4" },
525
  { name = "ipykernel", specifier = ">=6.29.5" },
 
674
  { url = "https://files.pythonhosted.org/packages/ee/5c/fe0dd370294c782fc1f627bb7e3eedd87c3d4d7f8d2b39fe8dd63c3096a8/gotrue-2.12.0-py3-none-any.whl", hash = "sha256:de94928eebb42d7d9672dbe4fbd0b51140a45051a31626a06dad2ad44a9a976a", size = 43649 },
675
  ]
676
 
677
+ [[package]]
678
+ name = "gradio"
679
+ version = "5.34.1"
680
+ source = { registry = "https://pypi.org/simple" }
681
+ dependencies = [
682
+ { name = "aiofiles" },
683
+ { name = "anyio" },
684
+ { name = "audioop-lts" },
685
+ { name = "fastapi" },
686
+ { name = "ffmpy" },
687
+ { name = "gradio-client" },
688
+ { name = "groovy" },
689
+ { name = "httpx" },
690
+ { name = "huggingface-hub" },
691
+ { name = "jinja2" },
692
+ { name = "markupsafe" },
693
+ { name = "numpy" },
694
+ { name = "orjson" },
695
+ { name = "packaging" },
696
+ { name = "pandas" },
697
+ { name = "pillow" },
698
+ { name = "pydantic" },
699
+ { name = "pydub" },
700
+ { name = "python-multipart" },
701
+ { name = "pyyaml" },
702
+ { name = "ruff", marker = "sys_platform != 'emscripten'" },
703
+ { name = "safehttpx" },
704
+ { name = "semantic-version" },
705
+ { name = "starlette", marker = "sys_platform != 'emscripten'" },
706
+ { name = "tomlkit" },
707
+ { name = "typer", marker = "sys_platform != 'emscripten'" },
708
+ { name = "typing-extensions" },
709
+ { name = "urllib3", marker = "sys_platform == 'emscripten'" },
710
+ { name = "uvicorn", marker = "sys_platform != 'emscripten'" },
711
+ ]
712
+ sdist = { url = "https://files.pythonhosted.org/packages/f8/b9/e9c5113422eed97bb7692709775142e2f76259f0237652b544f459c503ef/gradio-5.34.1.tar.gz", hash = "sha256:26e3a01b0d3170e0ecc4757a0973aab78d5e1a15110b122c512ada116e137729", size = 65347644 }
713
+ wheels = [
714
+ { url = "https://files.pythonhosted.org/packages/6e/4d/3883eaf9502c24a78f13ec755e28dc6e71f4f5b050cc9e04efecc5d2dcdd/gradio-5.34.1-py3-none-any.whl", hash = "sha256:399167c0dbf11abcbe6e281575614b105ff4bfaea9491aa2b06de64ffdd553c4", size = 54273535 },
715
+ ]
716
+
717
+ [[package]]
718
+ name = "gradio-client"
719
+ version = "1.10.3"
720
+ source = { registry = "https://pypi.org/simple" }
721
+ dependencies = [
722
+ { name = "fsspec" },
723
+ { name = "httpx" },
724
+ { name = "huggingface-hub" },
725
+ { name = "packaging" },
726
+ { name = "typing-extensions" },
727
+ { name = "websockets" },
728
+ ]
729
+ sdist = { url = "https://files.pythonhosted.org/packages/0b/91/a31536da8fd18ed1c1d5b05929b7291a7bfe5963dfcd37a20a42fc2194f0/gradio_client-1.10.3.tar.gz", hash = "sha256:9e99b88e47f05dc3b68e40a3f3f83819f8d0ddcd43466ad385fe42e137825774", size = 321637 }
730
+ wheels = [
731
+ { url = "https://files.pythonhosted.org/packages/ea/72/1e76abc821f8efaaeb2e3bd727a6c97bf87c6a9a0ffacfed0647e587824a/gradio_client-1.10.3-py3-none-any.whl", hash = "sha256:941e7f8d9a160f88487e9780a3db2736a40ea2b8b69d53ffdb306e47ef658b76", size = 323599 },
732
+ ]
733
+
734
  [[package]]
735
  name = "greenlet"
736
  version = "3.2.3"
 
767
  { url = "https://files.pythonhosted.org/packages/58/c6/5c20af38c2a57c15d87f7f38bee77d63c1d2a3689f74fefaf35915dd12b2/griffe-1.7.3-py3-none-any.whl", hash = "sha256:c6b3ee30c2f0f17f30bcdef5068d6ab7a2a4f1b8bf1a3e74b56fffd21e1c5f75", size = 129303 },
768
  ]
769
 
770
+ [[package]]
771
+ name = "groovy"
772
+ version = "0.1.2"
773
+ source = { registry = "https://pypi.org/simple" }
774
+ sdist = { url = "https://files.pythonhosted.org/packages/52/36/bbdede67400277bef33d3ec0e6a31750da972c469f75966b4930c753218f/groovy-0.1.2.tar.gz", hash = "sha256:25c1dc09b3f9d7e292458aa762c6beb96ea037071bf5e917fc81fb78d2231083", size = 17325 }
775
+ wheels = [
776
+ { url = "https://files.pythonhosted.org/packages/28/27/3d6dcadc8a3214d8522c1e7f6a19554e33659be44546d44a2f7572ac7d2a/groovy-0.1.2-py3-none-any.whl", hash = "sha256:7f7975bab18c729a257a8b1ae9dcd70b7cafb1720481beae47719af57c35fa64", size = 14090 },
777
+ ]
778
+
779
  [[package]]
780
  name = "groq"
781
  version = "0.28.0"
 
2521
  { url = "https://files.pythonhosted.org/packages/b6/5f/d6d641b490fd3ec2c4c13b4244d68deea3a1b970a97be64f34fb5504ff72/pydantic_settings-2.9.1-py3-none-any.whl", hash = "sha256:59b4f431b1defb26fe620c71a7d3968a710d719f5f4cdbbdb7926edeb770f6ef", size = 44356 },
2522
  ]
2523
 
2524
+ [[package]]
2525
+ name = "pydub"
2526
+ version = "0.25.1"
2527
+ source = { registry = "https://pypi.org/simple" }
2528
+ sdist = { url = "https://files.pythonhosted.org/packages/fe/9a/e6bca0eed82db26562c73b5076539a4a08d3cffd19c3cc5913a3e61145fd/pydub-0.25.1.tar.gz", hash = "sha256:980a33ce9949cab2a569606b65674d748ecbca4f0796887fd6f46173a7b0d30f", size = 38326 }
2529
+ wheels = [
2530
+ { url = "https://files.pythonhosted.org/packages/a6/53/d78dc063216e62fc55f6b2eebb447f6a4b0a59f55c8406376f76bf959b08/pydub-0.25.1-py2.py3-none-any.whl", hash = "sha256:65617e33033874b59d87db603aa1ed450633288aefead953b30bded59cb599a6", size = 32327 },
2531
+ ]
2532
+
2533
  [[package]]
2534
  name = "pygments"
2535
  version = "2.19.1"
 
2606
  { url = "https://files.pythonhosted.org/packages/1e/18/98a99ad95133c6a6e2005fe89faedf294a748bd5dc803008059409ac9b1e/python_dotenv-1.1.0-py3-none-any.whl", hash = "sha256:d7c01d9e2293916c18baf562d95698754b0dbbb5e74d457c45d4f6561fb9d55d", size = 20256 },
2607
  ]
2608
 
2609
+ [[package]]
2610
+ name = "python-multipart"
2611
+ version = "0.0.20"
2612
+ source = { registry = "https://pypi.org/simple" }
2613
+ sdist = { url = "https://files.pythonhosted.org/packages/f3/87/f44d7c9f274c7ee665a29b885ec97089ec5dc034c7f3fafa03da9e39a09e/python_multipart-0.0.20.tar.gz", hash = "sha256:8dd0cab45b8e23064ae09147625994d090fa46f5b0d1e13af944c331a7fa9d13", size = 37158 }
2614
+ wheels = [
2615
+ { url = "https://files.pythonhosted.org/packages/45/58/38b5afbc1a800eeea951b9285d3912613f2603bdf897a4ab0f4bd7f405fc/python_multipart-0.0.20-py3-none-any.whl", hash = "sha256:8a62d3a8335e06589fe01f2a3e178cdcc632f3fbe0d492ad9ee0ec35aab1f104", size = 24546 },
2616
+ ]
2617
+
2618
  [[package]]
2619
  name = "pytz"
2620
  version = "2025.2"
 
2771
  { url = "https://files.pythonhosted.org/packages/64/8d/0133e4eb4beed9e425d9a98ed6e081a55d195481b7632472be1af08d2f6b/rsa-4.9.1-py3-none-any.whl", hash = "sha256:68635866661c6836b8d39430f97a996acbd61bfa49406748ea243539fe239762", size = 34696 },
2772
  ]
2773
 
2774
+ [[package]]
2775
+ name = "ruff"
2776
+ version = "0.12.0"
2777
+ source = { registry = "https://pypi.org/simple" }
2778
+ sdist = { url = "https://files.pythonhosted.org/packages/24/90/5255432602c0b196a0da6720f6f76b93eb50baef46d3c9b0025e2f9acbf3/ruff-0.12.0.tar.gz", hash = "sha256:4d047db3662418d4a848a3fdbfaf17488b34b62f527ed6f10cb8afd78135bc5c", size = 4376101 }
2779
+ wheels = [
2780
+ { url = "https://files.pythonhosted.org/packages/e6/fd/b46bb20e14b11ff49dbc74c61de352e0dc07fb650189513631f6fb5fc69f/ruff-0.12.0-py3-none-linux_armv6l.whl", hash = "sha256:5652a9ecdb308a1754d96a68827755f28d5dfb416b06f60fd9e13f26191a8848", size = 10311554 },
2781
+ { url = "https://files.pythonhosted.org/packages/e7/d3/021dde5a988fa3e25d2468d1dadeea0ae89dc4bc67d0140c6e68818a12a1/ruff-0.12.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:05ed0c914fabc602fc1f3b42c53aa219e5736cb030cdd85640c32dbc73da74a6", size = 11118435 },
2782
+ { url = "https://files.pythonhosted.org/packages/07/a2/01a5acf495265c667686ec418f19fd5c32bcc326d4c79ac28824aecd6a32/ruff-0.12.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:07a7aa9b69ac3fcfda3c507916d5d1bca10821fe3797d46bad10f2c6de1edda0", size = 10466010 },
2783
+ { url = "https://files.pythonhosted.org/packages/4c/57/7caf31dd947d72e7aa06c60ecb19c135cad871a0a8a251723088132ce801/ruff-0.12.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e7731c3eec50af71597243bace7ec6104616ca56dda2b99c89935fe926bdcd48", size = 10661366 },
2784
+ { url = "https://files.pythonhosted.org/packages/e9/ba/aa393b972a782b4bc9ea121e0e358a18981980856190d7d2b6187f63e03a/ruff-0.12.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:952d0630eae628250ab1c70a7fffb641b03e6b4a2d3f3ec6c1d19b4ab6c6c807", size = 10173492 },
2785
+ { url = "https://files.pythonhosted.org/packages/d7/50/9349ee777614bc3062fc6b038503a59b2034d09dd259daf8192f56c06720/ruff-0.12.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c021f04ea06966b02614d442e94071781c424ab8e02ec7af2f037b4c1e01cc82", size = 11761739 },
2786
+ { url = "https://files.pythonhosted.org/packages/04/8f/ad459de67c70ec112e2ba7206841c8f4eb340a03ee6a5cabc159fe558b8e/ruff-0.12.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:7d235618283718ee2fe14db07f954f9b2423700919dc688eacf3f8797a11315c", size = 12537098 },
2787
+ { url = "https://files.pythonhosted.org/packages/ed/50/15ad9c80ebd3c4819f5bd8883e57329f538704ed57bac680d95cb6627527/ruff-0.12.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0c0758038f81beec8cc52ca22de9685b8ae7f7cc18c013ec2050012862cc9165", size = 12154122 },
2788
+ { url = "https://files.pythonhosted.org/packages/76/e6/79b91e41bc8cc3e78ee95c87093c6cacfa275c786e53c9b11b9358026b3d/ruff-0.12.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:139b3d28027987b78fc8d6cfb61165447bdf3740e650b7c480744873688808c2", size = 11363374 },
2789
+ { url = "https://files.pythonhosted.org/packages/db/c3/82b292ff8a561850934549aa9dc39e2c4e783ab3c21debe55a495ddf7827/ruff-0.12.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68853e8517b17bba004152aebd9dd77d5213e503a5f2789395b25f26acac0da4", size = 11587647 },
2790
+ { url = "https://files.pythonhosted.org/packages/2b/42/d5760d742669f285909de1bbf50289baccb647b53e99b8a3b4f7ce1b2001/ruff-0.12.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:3a9512af224b9ac4757f7010843771da6b2b0935a9e5e76bb407caa901a1a514", size = 10527284 },
2791
+ { url = "https://files.pythonhosted.org/packages/19/f6/fcee9935f25a8a8bba4adbae62495c39ef281256693962c2159e8b284c5f/ruff-0.12.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:b08df3d96db798e5beb488d4df03011874aff919a97dcc2dd8539bb2be5d6a88", size = 10158609 },
2792
+ { url = "https://files.pythonhosted.org/packages/37/fb/057febf0eea07b9384787bfe197e8b3384aa05faa0d6bd844b94ceb29945/ruff-0.12.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:6a315992297a7435a66259073681bb0d8647a826b7a6de45c6934b2ca3a9ed51", size = 11141462 },
2793
+ { url = "https://files.pythonhosted.org/packages/10/7c/1be8571011585914b9d23c95b15d07eec2d2303e94a03df58294bc9274d4/ruff-0.12.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:1e55e44e770e061f55a7dbc6e9aed47feea07731d809a3710feda2262d2d4d8a", size = 11641616 },
2794
+ { url = "https://files.pythonhosted.org/packages/6a/ef/b960ab4818f90ff59e571d03c3f992828d4683561095e80f9ef31f3d58b7/ruff-0.12.0-py3-none-win32.whl", hash = "sha256:7162a4c816f8d1555eb195c46ae0bd819834d2a3f18f98cc63819a7b46f474fb", size = 10525289 },
2795
+ { url = "https://files.pythonhosted.org/packages/34/93/8b16034d493ef958a500f17cda3496c63a537ce9d5a6479feec9558f1695/ruff-0.12.0-py3-none-win_amd64.whl", hash = "sha256:d00b7a157b8fb6d3827b49d3324da34a1e3f93492c1f97b08e222ad7e9b291e0", size = 11598311 },
2796
+ { url = "https://files.pythonhosted.org/packages/d0/33/4d3e79e4a84533d6cd526bfb42c020a23256ae5e4265d858bd1287831f7d/ruff-0.12.0-py3-none-win_arm64.whl", hash = "sha256:8cd24580405ad8c1cc64d61725bca091d6b6da7eb3d36f72cc605467069d7e8b", size = 10724946 },
2797
+ ]
2798
+
2799
+ [[package]]
2800
+ name = "safehttpx"
2801
+ version = "0.1.6"
2802
+ source = { registry = "https://pypi.org/simple" }
2803
+ dependencies = [
2804
+ { name = "httpx" },
2805
+ ]
2806
+ sdist = { url = "https://files.pythonhosted.org/packages/67/4c/19db75e6405692b2a96af8f06d1258f8aa7290bdc35ac966f03e207f6d7f/safehttpx-0.1.6.tar.gz", hash = "sha256:b356bfc82cee3a24c395b94a2dbeabbed60aff1aa5fa3b5fe97c4f2456ebce42", size = 9987 }
2807
+ wheels = [
2808
+ { url = "https://files.pythonhosted.org/packages/4d/c0/1108ad9f01567f66b3154063605b350b69c3c9366732e09e45f9fd0d1deb/safehttpx-0.1.6-py3-none-any.whl", hash = "sha256:407cff0b410b071623087c63dd2080c3b44dc076888d8c5823c00d1e58cb381c", size = 8692 },
2809
+ ]
2810
+
2811
  [[package]]
2812
  name = "safetensors"
2813
  version = "0.5.3"
 
2882
  { url = "https://files.pythonhosted.org/packages/81/06/0a5e5349474e1cbc5757975b21bd4fad0e72ebf138c5592f191646154e06/scipy-1.15.3-cp313-cp313t-win_amd64.whl", hash = "sha256:76ad1fb5f8752eabf0fa02e4cc0336b4e8f021e2d5f061ed37d6d264db35e3ca", size = 40308097 },
2883
  ]
2884
 
2885
+ [[package]]
2886
+ name = "semantic-version"
2887
+ version = "2.10.0"
2888
+ source = { registry = "https://pypi.org/simple" }
2889
+ sdist = { url = "https://files.pythonhosted.org/packages/7d/31/f2289ce78b9b473d582568c234e104d2a342fd658cc288a7553d83bb8595/semantic_version-2.10.0.tar.gz", hash = "sha256:bdabb6d336998cbb378d4b9db3a4b56a1e3235701dc05ea2690d9a997ed5041c", size = 52289 }
2890
+ wheels = [
2891
+ { url = "https://files.pythonhosted.org/packages/6a/23/8146aad7d88f4fcb3a6218f41a60f6c2d4e3a72de72da1825dc7c8f7877c/semantic_version-2.10.0-py2.py3-none-any.whl", hash = "sha256:de78a3b8e0feda74cabc54aab2da702113e33ac9d9eb9d2389bcf1f58b7d9177", size = 15552 },
2892
+ ]
2893
+
2894
  [[package]]
2895
  name = "sentence-transformers"
2896
  version = "4.1.0"
 
2925
  source = { registry = "https://pypi.org/simple" }
2926
  sdist = { url = "https://files.pythonhosted.org/packages/9e/bd/3704a8c3e0942d711c1299ebf7b9091930adae6675d7c8f476a7ce48653c/sgmllib3k-1.0.0.tar.gz", hash = "sha256:7868fb1c8bfa764c1ac563d3cf369c381d1325d36124933a726f29fcdaa812e9", size = 5750 }
2927
 
2928
+ [[package]]
2929
+ name = "shellingham"
2930
+ version = "1.5.4"
2931
+ source = { registry = "https://pypi.org/simple" }
2932
+ sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310 }
2933
+ wheels = [
2934
+ { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755 },
2935
+ ]
2936
+
2937
  [[package]]
2938
  name = "six"
2939
  version = "1.17.0"
 
3001
  { url = "https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695", size = 24521 },
3002
  ]
3003
 
3004
+ [[package]]
3005
+ name = "starlette"
3006
+ version = "0.46.2"
3007
+ source = { registry = "https://pypi.org/simple" }
3008
+ dependencies = [
3009
+ { name = "anyio" },
3010
+ ]
3011
+ sdist = { url = "https://files.pythonhosted.org/packages/ce/20/08dfcd9c983f6a6f4a1000d934b9e6d626cff8d2eeb77a89a68eef20a2b7/starlette-0.46.2.tar.gz", hash = "sha256:7f7361f34eed179294600af672f565727419830b54b7b084efe44bb82d2fccd5", size = 2580846 }
3012
+ wheels = [
3013
+ { url = "https://files.pythonhosted.org/packages/8b/0c/9d30a4ebeb6db2b25a841afbb80f6ef9a854fc3b41be131d249a977b4959/starlette-0.46.2-py3-none-any.whl", hash = "sha256:595633ce89f8ffa71a015caed34a5b2dc1c0cdb3f0f1fbd1e69339cf2abeec35", size = 72037 },
3014
+ ]
3015
+
3016
  [[package]]
3017
  name = "storage3"
3018
  version = "0.11.3"
 
3161
  { url = "https://files.pythonhosted.org/packages/e6/b6/072a8e053ae600dcc2ac0da81a23548e3b523301a442a6ca900e92ac35be/tokenizers-0.21.1-cp39-abi3-win_amd64.whl", hash = "sha256:0f0dcbcc9f6e13e675a66d7a5f2f225a736745ce484c1a4e07476a89ccdad382", size = 2435481 },
3162
  ]
3163
 
3164
+ [[package]]
3165
+ name = "tomlkit"
3166
+ version = "0.13.3"
3167
+ source = { registry = "https://pypi.org/simple" }
3168
+ sdist = { url = "https://files.pythonhosted.org/packages/cc/18/0bbf3884e9eaa38819ebe46a7bd25dcd56b67434402b66a58c4b8e552575/tomlkit-0.13.3.tar.gz", hash = "sha256:430cf247ee57df2b94ee3fbe588e71d362a941ebb545dec29b53961d61add2a1", size = 185207 }
3169
+ wheels = [
3170
+ { url = "https://files.pythonhosted.org/packages/bd/75/8539d011f6be8e29f339c42e633aae3cb73bffa95dd0f9adec09b9c58e85/tomlkit-0.13.3-py3-none-any.whl", hash = "sha256:c89c649d79ee40629a9fda55f8ace8c6a1b42deb912b2a8fd8d942ddadb606b0", size = 38901 },
3171
+ ]
3172
+
3173
  [[package]]
3174
  name = "torch"
3175
  version = "2.7.1"
 
3282
  { url = "https://files.pythonhosted.org/packages/28/71/bd20ffcb7a64c753dc2463489a61bf69d531f308e390ad06390268c4ea04/triton-3.3.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a3198adb9d78b77818a5388bff89fa72ff36f9da0bc689db2f0a651a67ce6a42", size = 155735832 },
3283
  ]
3284
 
3285
+ [[package]]
3286
+ name = "typer"
3287
+ version = "0.16.0"
3288
+ source = { registry = "https://pypi.org/simple" }
3289
+ dependencies = [
3290
+ { name = "click" },
3291
+ { name = "rich" },
3292
+ { name = "shellingham" },
3293
+ { name = "typing-extensions" },
3294
+ ]
3295
+ sdist = { url = "https://files.pythonhosted.org/packages/c5/8c/7d682431efca5fd290017663ea4588bf6f2c6aad085c7f108c5dbc316e70/typer-0.16.0.tar.gz", hash = "sha256:af377ffaee1dbe37ae9440cb4e8f11686ea5ce4e9bae01b84ae7c63b87f1dd3b", size = 102625 }
3296
+ wheels = [
3297
+ { url = "https://files.pythonhosted.org/packages/76/42/3efaf858001d2c2913de7f354563e3a3a2f0decae3efe98427125a8f441e/typer-0.16.0-py3-none-any.whl", hash = "sha256:1f79bed11d4d02d4310e3c1b7ba594183bcedb0ac73b27a9e5f28f6fb5b98855", size = 46317 },
3298
+ ]
3299
+
3300
  [[package]]
3301
  name = "typing-extensions"
3302
  version = "4.14.0"
 
3349
  { url = "https://files.pythonhosted.org/packages/6b/11/cc635220681e93a0183390e26485430ca2c7b5f9d33b15c74c2861cb8091/urllib3-2.4.0-py3-none-any.whl", hash = "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813", size = 128680 },
3350
  ]
3351
 
3352
+ [[package]]
3353
+ name = "uvicorn"
3354
+ version = "0.34.3"
3355
+ source = { registry = "https://pypi.org/simple" }
3356
+ dependencies = [
3357
+ { name = "click" },
3358
+ { name = "h11" },
3359
+ ]
3360
+ sdist = { url = "https://files.pythonhosted.org/packages/de/ad/713be230bcda622eaa35c28f0d328c3675c371238470abdea52417f17a8e/uvicorn-0.34.3.tar.gz", hash = "sha256:35919a9a979d7a59334b6b10e05d77c1d0d574c50e0fc98b8b1a0f165708b55a", size = 76631 }
3361
+ wheels = [
3362
+ { url = "https://files.pythonhosted.org/packages/6d/0d/8adfeaa62945f90d19ddc461c55f4a50c258af7662d34b6a3d5d1f8646f6/uvicorn-0.34.3-py3-none-any.whl", hash = "sha256:16246631db62bdfbf069b0645177d6e8a77ba950cfedbfd093acef9444e4d885", size = 62431 },
3363
+ ]
3364
+
3365
  [[package]]
3366
  name = "wcwidth"
3367
  version = "0.2.13"