quantalogic 0.50.5__py3-none-any.whl → 0.50.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- quantalogic/tools/__init__.py +3 -3
- quantalogic/tools/database/sql_query_tool_advanced.py +20 -3
- quantalogic/tools/sql_query_tool.py +25 -8
- quantalogic/tools/utils/create_sample_database.py +64 -7
- quantalogic/tools/utils/generate_database_report.py +38 -5
- {quantalogic-0.50.5.dist-info → quantalogic-0.50.7.dist-info}/METADATA +2 -1
- {quantalogic-0.50.5.dist-info → quantalogic-0.50.7.dist-info}/RECORD +10 -10
- {quantalogic-0.50.5.dist-info → quantalogic-0.50.7.dist-info}/LICENSE +0 -0
- {quantalogic-0.50.5.dist-info → quantalogic-0.50.7.dist-info}/WHEEL +0 -0
- {quantalogic-0.50.5.dist-info → quantalogic-0.50.7.dist-info}/entry_points.txt +0 -0
quantalogic/tools/__init__.py
CHANGED
@@ -33,8 +33,8 @@ class LazyLoader:
|
|
33
33
|
_TOOL_IMPORTS = {
|
34
34
|
"AgentTool": (".agent_tool", False),
|
35
35
|
"ComposioTool": (".composio.composio", True),
|
36
|
-
"GenerateDatabaseReportTool": (".database.generate_database_report_tool",
|
37
|
-
"SQLQueryToolAdvanced": (".database.sql_query_tool_advanced",
|
36
|
+
"GenerateDatabaseReportTool": (".database.generate_database_report_tool", True),
|
37
|
+
"SQLQueryToolAdvanced": (".database.sql_query_tool_advanced", True),
|
38
38
|
"MarkdownToDocxTool": (".document_tools.markdown_to_docx_tool", True),
|
39
39
|
"MarkdownToEpubTool": (".document_tools.markdown_to_epub_tool", True),
|
40
40
|
"MarkdownToHtmlTool": (".document_tools.markdown_to_html_tool", True),
|
@@ -76,7 +76,7 @@ _TOOL_IMPORTS = {
|
|
76
76
|
"SearchDefinitionNames": (".search_definition_names", False),
|
77
77
|
"SequenceTool": (".sequence_tool", False),
|
78
78
|
"SerpApiSearchTool": (".serpapi_search_tool", False),
|
79
|
-
"SQLQueryTool": (".sql_query_tool",
|
79
|
+
"SQLQueryTool": (".sql_query_tool", True),
|
80
80
|
"TaskCompleteTool": (".task_complete_tool", False),
|
81
81
|
"Tool": (".tool", False),
|
82
82
|
"ToolArgument": (".tool", False),
|
@@ -1,13 +1,27 @@
|
|
1
1
|
"""Tool for executing SQL queries and performing database operations with safety checks."""
|
2
2
|
|
3
|
+
import importlib.util
|
3
4
|
import json
|
4
5
|
from enum import Enum
|
5
|
-
from typing import Any, Dict, List, Optional
|
6
|
+
from typing import Any, Dict, List, Optional, TYPE_CHECKING
|
6
7
|
|
7
8
|
from loguru import logger
|
8
9
|
from pydantic import Field
|
9
|
-
|
10
|
-
|
10
|
+
|
11
|
+
# Check if sqlalchemy is available
|
12
|
+
SQLALCHEMY_AVAILABLE = False
|
13
|
+
try:
|
14
|
+
spec = importlib.util.find_spec("sqlalchemy")
|
15
|
+
SQLALCHEMY_AVAILABLE = spec is not None
|
16
|
+
if SQLALCHEMY_AVAILABLE:
|
17
|
+
from sqlalchemy import create_engine, inspect, text
|
18
|
+
from sqlalchemy.engine import Engine
|
19
|
+
except ImportError:
|
20
|
+
pass
|
21
|
+
|
22
|
+
# Type checking imports
|
23
|
+
if TYPE_CHECKING:
|
24
|
+
from sqlalchemy.engine import Engine
|
11
25
|
|
12
26
|
from quantalogic.tools.tool import Tool, ToolArgument
|
13
27
|
|
@@ -72,6 +86,9 @@ class SQLQueryToolAdvanced(Tool):
|
|
72
86
|
|
73
87
|
def __init__(self, **data):
|
74
88
|
super().__init__(**data)
|
89
|
+
if not SQLALCHEMY_AVAILABLE:
|
90
|
+
raise ImportError("The 'sqlalchemy' package is required to use SQLQueryToolAdvanced. "
|
91
|
+
"Install it with 'pip install sqlalchemy' or include it in your dependencies.")
|
75
92
|
self._engine = create_engine(self.connection_string)
|
76
93
|
logger.info(f"Initialized SQL tool with engine for {self.connection_string}")
|
77
94
|
|
@@ -1,10 +1,20 @@
|
|
1
1
|
"""Tool for executing SQL queries and returning paginated results in markdown format."""
|
2
2
|
|
3
|
-
|
3
|
+
import importlib.util
|
4
|
+
from typing import Any, Dict, List, TYPE_CHECKING
|
4
5
|
|
5
6
|
from pydantic import Field, ValidationError
|
6
|
-
|
7
|
-
|
7
|
+
|
8
|
+
# Check if sqlalchemy is available
|
9
|
+
SQLALCHEMY_AVAILABLE = False
|
10
|
+
try:
|
11
|
+
spec = importlib.util.find_spec("sqlalchemy")
|
12
|
+
SQLALCHEMY_AVAILABLE = spec is not None
|
13
|
+
if SQLALCHEMY_AVAILABLE:
|
14
|
+
from sqlalchemy import create_engine, text
|
15
|
+
from sqlalchemy.exc import SQLAlchemyError
|
16
|
+
except ImportError:
|
17
|
+
pass
|
8
18
|
|
9
19
|
from quantalogic.tools.tool import Tool, ToolArgument
|
10
20
|
|
@@ -63,7 +73,13 @@ class SQLQueryTool(Tool):
|
|
63
73
|
Raises:
|
64
74
|
ValueError: For invalid parameters or query errors
|
65
75
|
RuntimeError: For database connection issues
|
76
|
+
ImportError: When sqlalchemy is not available
|
66
77
|
"""
|
78
|
+
# Check if required dependencies are available
|
79
|
+
if not SQLALCHEMY_AVAILABLE:
|
80
|
+
raise ImportError("The 'sqlalchemy' package is required to use SQLQueryTool. "
|
81
|
+
"Install it with 'pip install sqlalchemy' or include it in your dependencies.")
|
82
|
+
|
67
83
|
try:
|
68
84
|
# Convert and validate row numbers
|
69
85
|
start = self._convert_row_number(start_row, "start_row")
|
@@ -105,12 +121,13 @@ class SQLQueryTool(Tool):
|
|
105
121
|
|
106
122
|
return "\n".join(markdown)
|
107
123
|
|
108
|
-
except SQLAlchemyError as e:
|
109
|
-
raise ValueError(f"SQL Error: {str(e)}") from e
|
110
|
-
except ValidationError as e:
|
111
|
-
raise ValueError(f"Validation Error: {str(e)}") from e
|
112
124
|
except Exception as e:
|
113
|
-
|
125
|
+
if SQLALCHEMY_AVAILABLE and isinstance(e, SQLAlchemyError):
|
126
|
+
raise ValueError(f"SQL Error: {str(e)}") from e
|
127
|
+
elif isinstance(e, ValidationError):
|
128
|
+
raise ValueError(f"Validation Error: {str(e)}") from e
|
129
|
+
else:
|
130
|
+
raise RuntimeError(f"Database Error: {str(e)}") from e
|
114
131
|
|
115
132
|
def _convert_row_number(self, value: Any, field_name: str) -> int:
|
116
133
|
"""Convert and validate row number input."""
|
@@ -1,12 +1,62 @@
|
|
1
|
+
import importlib.util
|
1
2
|
import random
|
2
3
|
from datetime import datetime, timedelta
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
4
|
+
from typing import Optional
|
5
|
+
|
6
|
+
# Check if faker is available
|
7
|
+
FAKER_AVAILABLE = False
|
8
|
+
try:
|
9
|
+
spec = importlib.util.find_spec("faker")
|
10
|
+
FAKER_AVAILABLE = spec is not None
|
11
|
+
except ImportError:
|
12
|
+
pass
|
13
|
+
|
14
|
+
# Check if sqlalchemy is available
|
15
|
+
SQLALCHEMY_AVAILABLE = False
|
16
|
+
try:
|
17
|
+
spec = importlib.util.find_spec("sqlalchemy")
|
18
|
+
SQLALCHEMY_AVAILABLE = spec is not None
|
19
|
+
except ImportError:
|
20
|
+
pass
|
21
|
+
|
22
|
+
# Only import if available
|
23
|
+
if FAKER_AVAILABLE:
|
24
|
+
from faker import Faker
|
25
|
+
else:
|
26
|
+
# Create a dummy Faker class
|
27
|
+
class Faker:
|
28
|
+
def __init__(self):
|
29
|
+
pass
|
30
|
+
|
31
|
+
def name(self) -> str:
|
32
|
+
return "Sample Name"
|
33
|
+
|
34
|
+
def email(self) -> str:
|
35
|
+
return "sample@example.com"
|
36
|
+
|
37
|
+
def street_address(self) -> str:
|
38
|
+
return "123 Sample St"
|
39
|
+
|
40
|
+
def city(self) -> str:
|
41
|
+
return "Sample City"
|
42
|
+
|
43
|
+
def word(self) -> str:
|
44
|
+
return "sample"
|
45
|
+
|
46
|
+
def date_between(self, start_date: datetime) -> datetime:
|
47
|
+
return start_date + timedelta(days=random.randint(1, 365))
|
48
|
+
|
49
|
+
if SQLALCHEMY_AVAILABLE:
|
50
|
+
from sqlalchemy import Column, Date, Float, ForeignKey, Integer, String, create_engine
|
51
|
+
from sqlalchemy.orm import declarative_base, relationship, sessionmaker
|
52
|
+
|
53
|
+
# Initialize these only if the required modules are available
|
54
|
+
Base = None
|
55
|
+
fake = None
|
56
|
+
if SQLALCHEMY_AVAILABLE:
|
57
|
+
Base = declarative_base()
|
58
|
+
if FAKER_AVAILABLE:
|
59
|
+
fake = Faker()
|
10
60
|
|
11
61
|
|
12
62
|
def create_sample_database(db_path: str) -> None:
|
@@ -16,6 +66,13 @@ def create_sample_database(db_path: str) -> None:
|
|
16
66
|
Args:
|
17
67
|
db_path: Path to the SQLite database file (e.g., 'sample.db')
|
18
68
|
"""
|
69
|
+
# Check if required dependencies are available
|
70
|
+
if not SQLALCHEMY_AVAILABLE:
|
71
|
+
raise ImportError("The 'sqlalchemy' package is required to use create_sample_database. "
|
72
|
+
"Install it with 'pip install sqlalchemy' or include it in your dependencies.")
|
73
|
+
if not FAKER_AVAILABLE:
|
74
|
+
raise ImportError("The 'faker' package is required to use create_sample_database. "
|
75
|
+
"Install it with 'pip install faker' or include it in your dependencies.")
|
19
76
|
|
20
77
|
# Define database schema
|
21
78
|
class Customer(Base):
|
@@ -1,9 +1,34 @@
|
|
1
|
+
import importlib.util
|
1
2
|
from datetime import UTC, datetime
|
2
|
-
from typing import Dict, List
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
from typing import Any, Dict, List, Optional, TYPE_CHECKING
|
4
|
+
|
5
|
+
# Check if networkx is available
|
6
|
+
NETWORKX_AVAILABLE = False
|
7
|
+
try:
|
8
|
+
spec = importlib.util.find_spec("networkx")
|
9
|
+
NETWORKX_AVAILABLE = spec is not None
|
10
|
+
except ImportError:
|
11
|
+
pass
|
12
|
+
|
13
|
+
# Check if sqlalchemy is available
|
14
|
+
SQLALCHEMY_AVAILABLE = False
|
15
|
+
try:
|
16
|
+
spec = importlib.util.find_spec("sqlalchemy")
|
17
|
+
SQLALCHEMY_AVAILABLE = spec is not None
|
18
|
+
except ImportError:
|
19
|
+
pass
|
20
|
+
|
21
|
+
# Only import if available
|
22
|
+
if NETWORKX_AVAILABLE:
|
23
|
+
import networkx as nx
|
24
|
+
if SQLALCHEMY_AVAILABLE:
|
25
|
+
from sqlalchemy import create_engine, inspect, text
|
26
|
+
from sqlalchemy.engine import Inspector
|
27
|
+
|
28
|
+
# Type checking imports
|
29
|
+
if TYPE_CHECKING:
|
30
|
+
import networkx as nx
|
31
|
+
from sqlalchemy.engine import Inspector
|
7
32
|
|
8
33
|
|
9
34
|
def generate_database_report(connection_string: str) -> str:
|
@@ -16,6 +41,14 @@ def generate_database_report(connection_string: str) -> str:
|
|
16
41
|
Returns:
|
17
42
|
Markdown-formatted report as a string
|
18
43
|
"""
|
44
|
+
# Check if required dependencies are available
|
45
|
+
if not SQLALCHEMY_AVAILABLE:
|
46
|
+
raise ImportError("The 'sqlalchemy' package is required to use generate_database_report. "
|
47
|
+
"Install it with 'pip install sqlalchemy' or include it in your dependencies.")
|
48
|
+
if not NETWORKX_AVAILABLE:
|
49
|
+
raise ImportError("The 'networkx' package is required to use generate_database_report. "
|
50
|
+
"Install it with 'pip install networkx' or include it in your dependencies.")
|
51
|
+
|
19
52
|
# Setup database connection and inspection
|
20
53
|
engine = create_engine(connection_string)
|
21
54
|
inspector = inspect(engine)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: quantalogic
|
3
|
-
Version: 0.50.
|
3
|
+
Version: 0.50.7
|
4
4
|
Summary: QuantaLogic ReAct Agents
|
5
5
|
Author: Raphaël MANSUY
|
6
6
|
Author-email: raphael.mansuy@gmail.com
|
@@ -9,6 +9,7 @@ Classifier: Programming Language :: Python :: 3
|
|
9
9
|
Classifier: Programming Language :: Python :: 3.12
|
10
10
|
Classifier: Programming Language :: Python :: 3.13
|
11
11
|
Requires-Dist: click (>=8.1.8,<9.0.0)
|
12
|
+
Requires-Dist: faker (>=36.1.1,<37.0.0)
|
12
13
|
Requires-Dist: instructor (>=1.7.2,<2.0.0)
|
13
14
|
Requires-Dist: jinja2 (>=3.1.5,<4.0.0)
|
14
15
|
Requires-Dist: litellm (>=1.56.4,<2.0.0)
|
@@ -38,11 +38,11 @@ quantalogic/server/templates/index.html,sha256=nDnXJoQEm1vXbhXtgaYk0G5VXj0wwzE6K
|
|
38
38
|
quantalogic/task_file_reader.py,sha256=oPcB4vTxJ__Y8o7VVABIPOkVw3tGDMdQYwdK27PERlE,1440
|
39
39
|
quantalogic/task_runner.py,sha256=c2QVGKZfHA0wZIBUvehpjMvtRaKZuhuYQerjIiCC9iY,10053
|
40
40
|
quantalogic/tool_manager.py,sha256=vNA7aBKgdU3wpw_goom6i9rg_64pNZapNxvg4cUhhCI,6983
|
41
|
-
quantalogic/tools/__init__.py,sha256=
|
41
|
+
quantalogic/tools/__init__.py,sha256=0ZwUnszv8GFW_Ml56ih_V0ilUkALmRfTK22vengmP5s,5139
|
42
42
|
quantalogic/tools/agent_tool.py,sha256=MXCXxWHRch7VK4UWhtRP1jeI8Np9Ne2CUGo8vm1oZiM,3064
|
43
43
|
quantalogic/tools/composio/composio.py,sha256=l12notWc2okQYq_vrXRirLZyfc4WiTwY1AyLP96qidQ,19657
|
44
44
|
quantalogic/tools/database/generate_database_report_tool.py,sha256=lGgER2VuHqnxliPM806tbwJh7WRW9HJcbBLL7QMvVBQ,1861
|
45
|
-
quantalogic/tools/database/sql_query_tool_advanced.py,sha256=
|
45
|
+
quantalogic/tools/database/sql_query_tool_advanced.py,sha256=kOe0u24r1GIsBjs3glpEgZtkP6H7FGJ6Iz9k9gILZIc,10027
|
46
46
|
quantalogic/tools/document_tools/markdown_to_docx_tool.py,sha256=r5AOyQfpcDoqQ6_g2uYyVjTEPtfeNn4mDmmefNZmJyM,22553
|
47
47
|
quantalogic/tools/document_tools/markdown_to_epub_tool.py,sha256=iFIUTty7bIuOV7nbSfCuzBvOWJBmSP1TBFxf74184X4,14031
|
48
48
|
quantalogic/tools/document_tools/markdown_to_html_tool.py,sha256=ngwU3RAj05Ghua2yqmpkpws09XYfjDpcg4MuONHNvO8,12030
|
@@ -109,7 +109,7 @@ quantalogic/tools/safe_python_interpreter_tool.py,sha256=yibIVmtkcfU4dS6KNcbJPxE
|
|
109
109
|
quantalogic/tools/search_definition_names.py,sha256=zqtaqq8aS5jdDQOkbd4wMUPFyL6Bq-4q9NWyLKdXL1E,18771
|
110
110
|
quantalogic/tools/sequence_tool.py,sha256=Hb2FSjWWACvXZX7rmJXPk5lnnnqaDeRTbhQQRtCd8hI,11169
|
111
111
|
quantalogic/tools/serpapi_search_tool.py,sha256=sX-Noch77kGP2XiwislPNFyy3_4TH6TwMK6C81L3q9Y,5316
|
112
|
-
quantalogic/tools/sql_query_tool.py,sha256=
|
112
|
+
quantalogic/tools/sql_query_tool.py,sha256=CWDNdqHJDWfmL_XSMWPbQPl-RlIu6y_FuAYkNavrg2A,6768
|
113
113
|
quantalogic/tools/task_complete_tool.py,sha256=L8tuyVoN07Q2hOsxx17JTW0C5Jd_N-C0i_0PtCUQUKU,929
|
114
114
|
quantalogic/tools/tool.py,sha256=2XlveQf7NVuDlPz-IgE0gURye8rIp9iH3YhWhoOsnog,11232
|
115
115
|
quantalogic/tools/unified_diff_tool.py,sha256=o7OiYnCM5MjbPlQTpB2OmkMQRI9zjdToQmgVkhiTvOI,14148
|
@@ -117,8 +117,8 @@ quantalogic/tools/utilities/csv_processor_tool.py,sha256=Mu_EPVj6iYAclNaVX_vbkek
|
|
117
117
|
quantalogic/tools/utilities/download_file_tool.py,sha256=hw_tO6RD0tA_LH46Tathf-LzSxRl7kgEiiP76rTGdds,6616
|
118
118
|
quantalogic/tools/utilities/mermaid_validator_tool.py,sha256=Brd6pt8OxpUgf8dm6kHqJJs_IU8V4Kc-8VDP-n1eCUM,25886
|
119
119
|
quantalogic/tools/utils/__init__.py,sha256=-NtMSwxRt_G79Oo_DcDaCdLU2vLvuXIoCd34TOYEUmI,334
|
120
|
-
quantalogic/tools/utils/create_sample_database.py,sha256=
|
121
|
-
quantalogic/tools/utils/generate_database_report.py,sha256=
|
120
|
+
quantalogic/tools/utils/create_sample_database.py,sha256=xc0I1oWr_XYSQ79Ar8Mpr93dqooQOxtEXZPyoXbv8kM,5517
|
121
|
+
quantalogic/tools/utils/generate_database_report.py,sha256=MbImXDX2j7KRQrCo6kvW-WZRnhrQQjVGQPFVhI25uZE,11294
|
122
122
|
quantalogic/tools/wikipedia_search_tool.py,sha256=LXQSPH8961Efw2QNxKe-cD5ZiIYD3ufEgrxH4y5uB74,5180
|
123
123
|
quantalogic/tools/write_file_tool.py,sha256=_mx9_Zjg2oMAAVzlcHEKjZVZUxQVgbRfcoMKgWnoZcg,3764
|
124
124
|
quantalogic/utils/__init__.py,sha256=hsS3hXH5lsBQcZh2QBANY1Af2Zs1jtrgxA7kXJEWi58,680
|
@@ -141,8 +141,8 @@ quantalogic/version_check.py,sha256=JyQFTNMDWtpHCLnN-BiakzB2cyXf6kUFsTjvmSruZi4,
|
|
141
141
|
quantalogic/welcome_message.py,sha256=o4tHdgabNuIV9kbIDPgS3_2yzJhayK30oKad2UouYDc,3020
|
142
142
|
quantalogic/xml_parser.py,sha256=AKuMdJC3QAX3Z_tErHVlZ-msjPemWaZUFiTwkHz76jg,11614
|
143
143
|
quantalogic/xml_tool_parser.py,sha256=Vz4LEgDbelJynD1siLOVkJ3gLlfHsUk65_gCwbYJyGc,3784
|
144
|
-
quantalogic-0.50.
|
145
|
-
quantalogic-0.50.
|
146
|
-
quantalogic-0.50.
|
147
|
-
quantalogic-0.50.
|
148
|
-
quantalogic-0.50.
|
144
|
+
quantalogic-0.50.7.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
145
|
+
quantalogic-0.50.7.dist-info/METADATA,sha256=TlYrGZR6hhDIMqndrpPcGLsBCJrbSty-J7s6iGmyhn8,22825
|
146
|
+
quantalogic-0.50.7.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
147
|
+
quantalogic-0.50.7.dist-info/entry_points.txt,sha256=h74O_Q3qBRCrDR99qvwB4BpBGzASPUIjCfxHq6Qnups,183
|
148
|
+
quantalogic-0.50.7.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|