Golfn commited on
Commit
cc36db8
·
1 Parent(s): fd14a05

add code intrepeter and dependency

Browse files
Files changed (3) hide show
  1. code_interpreter.py +281 -0
  2. pdm.lock +117 -1
  3. pyproject.toml +1 -1
code_interpreter.py ADDED
@@ -0,0 +1,281 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import io
3
+ import sys
4
+ import uuid
5
+ import base64
6
+ import traceback
7
+ import contextlib
8
+ import tempfile
9
+ import subprocess
10
+ import sqlite3
11
+ from typing import Dict, List, Any, Optional, Union
12
+ import numpy as np
13
+ import pandas as pd
14
+ import matplotlib.pyplot as plt
15
+ from PIL import Image
16
+
17
+ class CodeInterpreter:
18
+ def __init__(self, allowed_modules=None, max_execution_time=30, working_directory=None):
19
+ """Initialize the code interpreter with safety measures."""
20
+ self.allowed_modules = allowed_modules or [
21
+ "numpy", "pandas", "matplotlib", "scipy", "sklearn",
22
+ "math", "random", "statistics", "datetime", "collections",
23
+ "itertools", "functools", "operator", "re", "json",
24
+ "sympy", "networkx", "nltk", "PIL", "pytesseract",
25
+ "cmath", "uuid", "tempfile", "requests", "urllib"
26
+ ]
27
+ self.max_execution_time = max_execution_time
28
+ self.working_directory = working_directory or os.path.join(os.getcwd())
29
+ if not os.path.exists(self.working_directory):
30
+ os.makedirs(self.working_directory)
31
+
32
+ self.globals = {
33
+ "__builtins__": __builtins__,
34
+ "np": np,
35
+ "pd": pd,
36
+ "plt": plt,
37
+ "Image": Image,
38
+ }
39
+ self.temp_sqlite_db = os.path.join(tempfile.gettempdir(), "code_exec.db")
40
+
41
+ def execute_code(self, code: str, language: str = "python") -> Dict[str, Any]:
42
+ """Execute the provided code in the selected programming language."""
43
+ language = language.lower()
44
+ execution_id = str(uuid.uuid4())
45
+
46
+ result = {
47
+ "execution_id": execution_id,
48
+ "status": "error",
49
+ "stdout": "",
50
+ "stderr": "",
51
+ "result": None,
52
+ "plots": [],
53
+ "dataframes": []
54
+ }
55
+
56
+ try:
57
+ if language == "python":
58
+ return self._execute_python(code, execution_id)
59
+ elif language == "bash":
60
+ return self._execute_bash(code, execution_id)
61
+ elif language == "sql":
62
+ return self._execute_sql(code, execution_id)
63
+ elif language == "c":
64
+ return self._execute_c(code, execution_id)
65
+ elif language == "java":
66
+ return self._execute_java(code, execution_id)
67
+ else:
68
+ result["stderr"] = f"Unsupported language: {language}"
69
+ except Exception as e:
70
+ result["stderr"] = str(e)
71
+
72
+ return result
73
+
74
+ def _execute_python(self, code: str, execution_id: str) -> dict:
75
+ output_buffer = io.StringIO()
76
+ error_buffer = io.StringIO()
77
+ result = {
78
+ "execution_id": execution_id,
79
+ "status": "error",
80
+ "stdout": "",
81
+ "stderr": "",
82
+ "result": None,
83
+ "plots": [],
84
+ "dataframes": []
85
+ }
86
+
87
+ try:
88
+ exec_dir = os.path.join(self.working_directory, execution_id)
89
+ os.makedirs(exec_dir, exist_ok=True)
90
+ plt.switch_backend('Agg')
91
+
92
+ with contextlib.redirect_stdout(output_buffer), contextlib.redirect_stderr(error_buffer):
93
+ exec_result = exec(code, self.globals)
94
+
95
+ if plt.get_fignums():
96
+ for i, fig_num in enumerate(plt.get_fignums()):
97
+ fig = plt.figure(fig_num)
98
+ img_path = os.path.join(exec_dir, f"plot_{i}.png")
99
+ fig.savefig(img_path)
100
+ with open(img_path, "rb") as img_file:
101
+ img_data = base64.b64encode(img_file.read()).decode('utf-8')
102
+ result["plots"].append({
103
+ "figure_number": fig_num,
104
+ "data": img_data
105
+ })
106
+
107
+ for var_name, var_value in self.globals.items():
108
+ if isinstance(var_value, pd.DataFrame) and len(var_value) > 0:
109
+ result["dataframes"].append({
110
+ "name": var_name,
111
+ "head": var_value.head().to_dict(),
112
+ "shape": var_value.shape,
113
+ "dtypes": str(var_value.dtypes)
114
+ })
115
+
116
+ result["status"] = "success"
117
+ result["stdout"] = output_buffer.getvalue()
118
+ result["result"] = exec_result
119
+
120
+ except Exception as e:
121
+ result["status"] = "error"
122
+ result["stderr"] = f"{error_buffer.getvalue()}\n{traceback.format_exc()}"
123
+
124
+ return result
125
+
126
+ def _execute_bash(self, code: str, execution_id: str) -> dict:
127
+ try:
128
+ completed = subprocess.run(
129
+ code, shell=True, capture_output=True, text=True, timeout=self.max_execution_time
130
+ )
131
+ return {
132
+ "execution_id": execution_id,
133
+ "status": "success" if completed.returncode == 0 else "error",
134
+ "stdout": completed.stdout,
135
+ "stderr": completed.stderr,
136
+ "result": None,
137
+ "plots": [],
138
+ "dataframes": []
139
+ }
140
+ except subprocess.TimeoutExpired:
141
+ return {
142
+ "execution_id": execution_id,
143
+ "status": "error",
144
+ "stdout": "",
145
+ "stderr": "Execution timed out.",
146
+ "result": None,
147
+ "plots": [],
148
+ "dataframes": []
149
+ }
150
+
151
+ def _execute_sql(self, code: str, execution_id: str) -> dict:
152
+ result = {
153
+ "execution_id": execution_id,
154
+ "status": "error",
155
+ "stdout": "",
156
+ "stderr": "",
157
+ "result": None,
158
+ "plots": [],
159
+ "dataframes": []
160
+ }
161
+ try:
162
+ conn = sqlite3.connect(self.temp_sqlite_db)
163
+ cur = conn.cursor()
164
+ cur.execute(code)
165
+ if code.strip().lower().startswith("select"):
166
+ columns = [description[0] for description in cur.description]
167
+ rows = cur.fetchall()
168
+ df = pd.DataFrame(rows, columns=columns)
169
+ result["dataframes"].append({
170
+ "name": "query_result",
171
+ "head": df.head().to_dict(),
172
+ "shape": df.shape,
173
+ "dtypes": str(df.dtypes)
174
+ })
175
+ else:
176
+ conn.commit()
177
+
178
+ result["status"] = "success"
179
+ result["stdout"] = "Query executed successfully."
180
+
181
+ except Exception as e:
182
+ result["stderr"] = str(e)
183
+ finally:
184
+ conn.close()
185
+
186
+ return result
187
+
188
+ def _execute_c(self, code: str, execution_id: str) -> dict:
189
+ temp_dir = tempfile.mkdtemp()
190
+ source_path = os.path.join(temp_dir, "program.c")
191
+ binary_path = os.path.join(temp_dir, "program")
192
+
193
+ try:
194
+ with open(source_path, "w") as f:
195
+ f.write(code)
196
+
197
+ compile_proc = subprocess.run(
198
+ ["gcc", source_path, "-o", binary_path],
199
+ capture_output=True, text=True, timeout=self.max_execution_time
200
+ )
201
+ if compile_proc.returncode != 0:
202
+ return {
203
+ "execution_id": execution_id,
204
+ "status": "error",
205
+ "stdout": compile_proc.stdout,
206
+ "stderr": compile_proc.stderr,
207
+ "result": None,
208
+ "plots": [],
209
+ "dataframes": []
210
+ }
211
+
212
+ run_proc = subprocess.run(
213
+ [binary_path],
214
+ capture_output=True, text=True, timeout=self.max_execution_time
215
+ )
216
+ return {
217
+ "execution_id": execution_id,
218
+ "status": "success" if run_proc.returncode == 0 else "error",
219
+ "stdout": run_proc.stdout,
220
+ "stderr": run_proc.stderr,
221
+ "result": None,
222
+ "plots": [],
223
+ "dataframes": []
224
+ }
225
+ except Exception as e:
226
+ return {
227
+ "execution_id": execution_id,
228
+ "status": "error",
229
+ "stdout": "",
230
+ "stderr": str(e),
231
+ "result": None,
232
+ "plots": [],
233
+ "dataframes": []
234
+ }
235
+
236
+ def _execute_java(self, code: str, execution_id: str) -> dict:
237
+ temp_dir = tempfile.mkdtemp()
238
+ source_path = os.path.join(temp_dir, "Main.java")
239
+
240
+ try:
241
+ with open(source_path, "w") as f:
242
+ f.write(code)
243
+
244
+ compile_proc = subprocess.run(
245
+ ["javac", source_path],
246
+ capture_output=True, text=True, timeout=self.max_execution_time
247
+ )
248
+ if compile_proc.returncode != 0:
249
+ return {
250
+ "execution_id": execution_id,
251
+ "status": "error",
252
+ "stdout": compile_proc.stdout,
253
+ "stderr": compile_proc.stderr,
254
+ "result": None,
255
+ "plots": [],
256
+ "dataframes": []
257
+ }
258
+
259
+ run_proc = subprocess.run(
260
+ ["java", "-cp", temp_dir, "Main"],
261
+ capture_output=True, text=True, timeout=self.max_execution_time
262
+ )
263
+ return {
264
+ "execution_id": execution_id,
265
+ "status": "success" if run_proc.returncode == 0 else "error",
266
+ "stdout": run_proc.stdout,
267
+ "stderr": run_proc.stderr,
268
+ "result": None,
269
+ "plots": [],
270
+ "dataframes": []
271
+ }
272
+ except Exception as e:
273
+ return {
274
+ "execution_id": execution_id,
275
+ "status": "error",
276
+ "stdout": "",
277
+ "stderr": str(e),
278
+ "result": None,
279
+ "plots": [],
280
+ "dataframes": []
281
+ }
pdm.lock CHANGED
@@ -5,7 +5,7 @@
5
  groups = ["default"]
6
  strategy = ["inherit_metadata"]
7
  lock_version = "4.5.0"
8
- content_hash = "sha256:0c6e1c83ed4ec2b1751cc0917ce598d614bf977d7f7b4568110a8a1b16d40739"
9
 
10
  [[metadata.targets]]
11
  requires_python = "==3.12.*"
@@ -226,6 +226,40 @@ files = [
226
  {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
227
  ]
228
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
229
  [[package]]
230
  name = "dataclasses-json"
231
  version = "0.6.7"
@@ -382,6 +416,25 @@ files = [
382
  {file = "filelock-3.18.0.tar.gz", hash = "sha256:adbc88eabb99d2fec8c9c1b229b171f18afa655400173ddc653d5d01501fb9f2"},
383
  ]
384
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
385
  [[package]]
386
  name = "frozenlist"
387
  version = "1.6.0"
@@ -786,6 +839,31 @@ files = [
786
  {file = "jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef"},
787
  ]
788
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
789
  [[package]]
790
  name = "langchain"
791
  version = "0.3.25"
@@ -1064,6 +1142,33 @@ files = [
1064
  {file = "marshmallow-3.26.1.tar.gz", hash = "sha256:e6d8affb6cb61d39d26402096dc0aee12d5a26d490a121f118d2e81dc0719dc6"},
1065
  ]
1066
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1067
  [[package]]
1068
  name = "mdurl"
1069
  version = "0.1.2"
@@ -1792,6 +1897,17 @@ files = [
1792
  {file = "pymupdf-1.25.5.tar.gz", hash = "sha256:5f96311cacd13254c905f6654a004a0a2025b71cabc04fda667f5472f72c15a0"},
1793
  ]
1794
 
 
 
 
 
 
 
 
 
 
 
 
1795
  [[package]]
1796
  name = "pytest"
1797
  version = "8.3.5"
 
5
  groups = ["default"]
6
  strategy = ["inherit_metadata"]
7
  lock_version = "4.5.0"
8
+ content_hash = "sha256:f81ca77951af90dfb67b0a9d676c0253886d33ef89a7089a391b0c0e87462336"
9
 
10
  [[metadata.targets]]
11
  requires_python = "==3.12.*"
 
226
  {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
227
  ]
228
 
229
+ [[package]]
230
+ name = "contourpy"
231
+ version = "1.3.2"
232
+ requires_python = ">=3.10"
233
+ summary = "Python library for calculating contours of 2D quadrilateral grids"
234
+ groups = ["default"]
235
+ dependencies = [
236
+ "numpy>=1.23",
237
+ ]
238
+ files = [
239
+ {file = "contourpy-1.3.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4caf2bcd2969402bf77edc4cb6034c7dd7c0803213b3523f111eb7460a51b8d2"},
240
+ {file = "contourpy-1.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:82199cb78276249796419fe36b7386bd8d2cc3f28b3bc19fe2454fe2e26c4c15"},
241
+ {file = "contourpy-1.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:106fab697af11456fcba3e352ad50effe493a90f893fca6c2ca5c033820cea92"},
242
+ {file = "contourpy-1.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d14f12932a8d620e307f715857107b1d1845cc44fdb5da2bc8e850f5ceba9f87"},
243
+ {file = "contourpy-1.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:532fd26e715560721bb0d5fc7610fce279b3699b018600ab999d1be895b09415"},
244
+ {file = "contourpy-1.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f26b383144cf2d2c29f01a1e8170f50dacf0eac02d64139dcd709a8ac4eb3cfe"},
245
+ {file = "contourpy-1.3.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c49f73e61f1f774650a55d221803b101d966ca0c5a2d6d5e4320ec3997489441"},
246
+ {file = "contourpy-1.3.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3d80b2c0300583228ac98d0a927a1ba6a2ba6b8a742463c564f1d419ee5b211e"},
247
+ {file = "contourpy-1.3.2-cp312-cp312-win32.whl", hash = "sha256:90df94c89a91b7362e1142cbee7568f86514412ab8a2c0d0fca72d7e91b62912"},
248
+ {file = "contourpy-1.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:8c942a01d9163e2e5cfb05cb66110121b8d07ad438a17f9e766317bcb62abf73"},
249
+ {file = "contourpy-1.3.2.tar.gz", hash = "sha256:b6945942715a034c671b7fc54f9588126b0b8bf23db2696e3ca8328f3ff0ab54"},
250
+ ]
251
+
252
+ [[package]]
253
+ name = "cycler"
254
+ version = "0.12.1"
255
+ requires_python = ">=3.8"
256
+ summary = "Composable style cycles"
257
+ groups = ["default"]
258
+ files = [
259
+ {file = "cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30"},
260
+ {file = "cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c"},
261
+ ]
262
+
263
  [[package]]
264
  name = "dataclasses-json"
265
  version = "0.6.7"
 
416
  {file = "filelock-3.18.0.tar.gz", hash = "sha256:adbc88eabb99d2fec8c9c1b229b171f18afa655400173ddc653d5d01501fb9f2"},
417
  ]
418
 
419
+ [[package]]
420
+ name = "fonttools"
421
+ version = "4.58.0"
422
+ requires_python = ">=3.9"
423
+ summary = "Tools to manipulate font files"
424
+ groups = ["default"]
425
+ files = [
426
+ {file = "fonttools-4.58.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:aa8316798f982c751d71f0025b372151ea36405733b62d0d94d5e7b8dd674fa6"},
427
+ {file = "fonttools-4.58.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c6db489511e867633b859b11aefe1b7c0d90281c5bdb903413edbb2ba77b97f1"},
428
+ {file = "fonttools-4.58.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:107bdb2dacb1f627db3c4b77fb16d065a10fe88978d02b4fc327b9ecf8a62060"},
429
+ {file = "fonttools-4.58.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba7212068ab20f1128a0475f169068ba8e5b6e35a39ba1980b9f53f6ac9720ac"},
430
+ {file = "fonttools-4.58.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f95ea3b6a3b9962da3c82db73f46d6a6845a6c3f3f968f5293b3ac1864e771c2"},
431
+ {file = "fonttools-4.58.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:874f1225cc4ccfeac32009887f722d7f8b107ca5e867dcee067597eef9d4c80b"},
432
+ {file = "fonttools-4.58.0-cp312-cp312-win32.whl", hash = "sha256:5f3cde64ec99c43260e2e6c4fa70dfb0a5e2c1c1d27a4f4fe4618c16f6c9ff71"},
433
+ {file = "fonttools-4.58.0-cp312-cp312-win_amd64.whl", hash = "sha256:2aee08e2818de45067109a207cbd1b3072939f77751ef05904d506111df5d824"},
434
+ {file = "fonttools-4.58.0-py3-none-any.whl", hash = "sha256:c96c36880be2268be409df7b08c5b5dacac1827083461a6bc2cb07b8cbcec1d7"},
435
+ {file = "fonttools-4.58.0.tar.gz", hash = "sha256:27423d0606a2c7b336913254bf0b1193ebd471d5f725d665e875c5e88a011a43"},
436
+ ]
437
+
438
  [[package]]
439
  name = "frozenlist"
440
  version = "1.6.0"
 
839
  {file = "jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef"},
840
  ]
841
 
842
+ [[package]]
843
+ name = "kiwisolver"
844
+ version = "1.4.8"
845
+ requires_python = ">=3.10"
846
+ summary = "A fast implementation of the Cassowary constraint solver"
847
+ groups = ["default"]
848
+ files = [
849
+ {file = "kiwisolver-1.4.8-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d6af5e8815fd02997cb6ad9bbed0ee1e60014438ee1a5c2444c96f87b8843502"},
850
+ {file = "kiwisolver-1.4.8-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:bade438f86e21d91e0cf5dd7c0ed00cda0f77c8c1616bd83f9fc157fa6760d31"},
851
+ {file = "kiwisolver-1.4.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b83dc6769ddbc57613280118fb4ce3cd08899cc3369f7d0e0fab518a7cf37fdb"},
852
+ {file = "kiwisolver-1.4.8-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:111793b232842991be367ed828076b03d96202c19221b5ebab421ce8bcad016f"},
853
+ {file = "kiwisolver-1.4.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:257af1622860e51b1a9d0ce387bf5c2c4f36a90594cb9514f55b074bcc787cfc"},
854
+ {file = "kiwisolver-1.4.8-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:69b5637c3f316cab1ec1c9a12b8c5f4750a4c4b71af9157645bf32830e39c03a"},
855
+ {file = "kiwisolver-1.4.8-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:782bb86f245ec18009890e7cb8d13a5ef54dcf2ebe18ed65f795e635a96a1c6a"},
856
+ {file = "kiwisolver-1.4.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc978a80a0db3a66d25767b03688f1147a69e6237175c0f4ffffaaedf744055a"},
857
+ {file = "kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:36dbbfd34838500a31f52c9786990d00150860e46cd5041386f217101350f0d3"},
858
+ {file = "kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:eaa973f1e05131de5ff3569bbba7f5fd07ea0595d3870ed4a526d486fe57fa1b"},
859
+ {file = "kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:a66f60f8d0c87ab7f59b6fb80e642ebb29fec354a4dfad687ca4092ae69d04f4"},
860
+ {file = "kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:858416b7fb777a53f0c59ca08190ce24e9abbd3cffa18886a5781b8e3e26f65d"},
861
+ {file = "kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:085940635c62697391baafaaeabdf3dd7a6c3643577dde337f4d66eba021b2b8"},
862
+ {file = "kiwisolver-1.4.8-cp312-cp312-win_amd64.whl", hash = "sha256:01c3d31902c7db5fb6182832713d3b4122ad9317c2c5877d0539227d96bb2e50"},
863
+ {file = "kiwisolver-1.4.8-cp312-cp312-win_arm64.whl", hash = "sha256:a3c44cb68861de93f0c4a8175fbaa691f0aa22550c331fefef02b618a9dcb476"},
864
+ {file = "kiwisolver-1.4.8.tar.gz", hash = "sha256:23d5f023bdc8c7e54eb65f03ca5d5bb25b601eac4d7f1a042888a1f45237987e"},
865
+ ]
866
+
867
  [[package]]
868
  name = "langchain"
869
  version = "0.3.25"
 
1142
  {file = "marshmallow-3.26.1.tar.gz", hash = "sha256:e6d8affb6cb61d39d26402096dc0aee12d5a26d490a121f118d2e81dc0719dc6"},
1143
  ]
1144
 
1145
+ [[package]]
1146
+ name = "matplotlib"
1147
+ version = "3.10.3"
1148
+ requires_python = ">=3.10"
1149
+ summary = "Python plotting package"
1150
+ groups = ["default"]
1151
+ dependencies = [
1152
+ "contourpy>=1.0.1",
1153
+ "cycler>=0.10",
1154
+ "fonttools>=4.22.0",
1155
+ "kiwisolver>=1.3.1",
1156
+ "numpy>=1.23",
1157
+ "packaging>=20.0",
1158
+ "pillow>=8",
1159
+ "pyparsing>=2.3.1",
1160
+ "python-dateutil>=2.7",
1161
+ ]
1162
+ files = [
1163
+ {file = "matplotlib-3.10.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:0ab1affc11d1f495ab9e6362b8174a25afc19c081ba5b0775ef00533a4236eea"},
1164
+ {file = "matplotlib-3.10.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2a818d8bdcafa7ed2eed74487fdb071c09c1ae24152d403952adad11fa3c65b4"},
1165
+ {file = "matplotlib-3.10.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:748ebc3470c253e770b17d8b0557f0aa85cf8c63fd52f1a61af5b27ec0b7ffee"},
1166
+ {file = "matplotlib-3.10.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed70453fd99733293ace1aec568255bc51c6361cb0da94fa5ebf0649fdb2150a"},
1167
+ {file = "matplotlib-3.10.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dbed9917b44070e55640bd13419de83b4c918e52d97561544814ba463811cbc7"},
1168
+ {file = "matplotlib-3.10.3-cp312-cp312-win_amd64.whl", hash = "sha256:cf37d8c6ef1a48829443e8ba5227b44236d7fcaf7647caa3178a4ff9f7a5be05"},
1169
+ {file = "matplotlib-3.10.3.tar.gz", hash = "sha256:2f82d2c5bb7ae93aaaa4cd42aca65d76ce6376f83304fa3a630b569aca274df0"},
1170
+ ]
1171
+
1172
  [[package]]
1173
  name = "mdurl"
1174
  version = "0.1.2"
 
1897
  {file = "pymupdf-1.25.5.tar.gz", hash = "sha256:5f96311cacd13254c905f6654a004a0a2025b71cabc04fda667f5472f72c15a0"},
1898
  ]
1899
 
1900
+ [[package]]
1901
+ name = "pyparsing"
1902
+ version = "3.2.3"
1903
+ requires_python = ">=3.9"
1904
+ summary = "pyparsing module - Classes and methods to define and execute parsing grammars"
1905
+ groups = ["default"]
1906
+ files = [
1907
+ {file = "pyparsing-3.2.3-py3-none-any.whl", hash = "sha256:a749938e02d6fd0b59b356ca504a24982314bb090c383e3cf201c95ef7e2bfcf"},
1908
+ {file = "pyparsing-3.2.3.tar.gz", hash = "sha256:b9c13f1ab8b3b542f72e28f634bad4de758ab3ce4546e4301970ad6fa77c38be"},
1909
+ ]
1910
+
1911
  [[package]]
1912
  name = "pytest"
1913
  version = "8.3.5"
pyproject.toml CHANGED
@@ -5,7 +5,7 @@ description = "Default template for PDM package"
5
  authors = [
6
  {name = "Supphawit_Golf", email = "supphawit.n@gmail.com"},
7
  ]
8
- dependencies = ["langchain>=0.3.25", "huggingface-hub>=0.31.2", "pandas>=2.2.3", "langgraph>=0.4.5", "langchain-openai>=0.3.17", "dotenv>=0.9.9", "datasets>=3.6.0", "langchain-community>=0.3.24", "rank-bm25>=0.2.2", "langchain-huggingface>=0.2.0", "duckduckgo-search>=8.0.2", "requests>=2.32.3", "gradio>=5.29.1", "arxiv>=2.2.0", "pymupdf>=1.25.5", "pymilvus>=2.5.9", "supabase>=2.15.1", "psycopg2-binary>=2.9.10"]
9
  requires-python = "==3.12.*"
10
  readme = "README.md"
11
  license = {text = "MIT"}
 
5
  authors = [
6
  {name = "Supphawit_Golf", email = "supphawit.n@gmail.com"},
7
  ]
8
+ dependencies = ["langchain>=0.3.25", "huggingface-hub>=0.31.2", "pandas>=2.2.3", "langgraph>=0.4.5", "langchain-openai>=0.3.17", "dotenv>=0.9.9", "datasets>=3.6.0", "langchain-community>=0.3.24", "rank-bm25>=0.2.2", "langchain-huggingface>=0.2.0", "duckduckgo-search>=8.0.2", "requests>=2.32.3", "gradio>=5.29.1", "arxiv>=2.2.0", "pymupdf>=1.25.5", "pymilvus>=2.5.9", "supabase>=2.15.1", "psycopg2-binary>=2.9.10", "matplotlib>=3.10.3"]
9
  requires-python = "==3.12.*"
10
  readme = "README.md"
11
  license = {text = "MIT"}