quantalogic 0.50.3__py3-none-any.whl → 0.50.6__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.
@@ -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", False),
37
- "SQLQueryToolAdvanced": (".database.sql_query_tool_advanced", False),
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", False),
79
+ "SQLQueryTool": (".sql_query_tool", True),
80
80
  "TaskCompleteTool": (".task_complete_tool", False),
81
81
  "Tool": (".tool", False),
82
82
  "ToolArgument": (".tool", False),
@@ -1,28 +1,31 @@
1
1
  """Tool for interacting with Composio API services."""
2
2
 
3
+ import importlib
4
+ import importlib.util
3
5
  import json
4
6
  import os
5
7
  import traceback
6
8
  from datetime import datetime
7
- from typing import Any, Dict, Optional, Union
9
+ from typing import Any, Dict, Optional, Union, TYPE_CHECKING
10
+
11
+ # Type checking imports - these are only used for type hints and not at runtime
12
+ if TYPE_CHECKING:
13
+ from composio import ComposioToolSet
8
14
 
9
15
  from loguru import logger
10
16
  from pydantic import BaseModel, ConfigDict, Field
11
17
 
12
- # Try to import composio, but don't fail if it's not installed
18
+ from quantalogic.tools.tool import Tool, ToolArgument
19
+
20
+ # Flag to check if composio is available
21
+ COMPOSIO_AVAILABLE = False
22
+
23
+ # Try to check if composio is importable without actually importing it
13
24
  try:
14
- from composio import Action, ComposioToolSet
15
- COMPOSIO_AVAILABLE = True
25
+ spec = importlib.util.find_spec("composio")
26
+ COMPOSIO_AVAILABLE = spec is not None
16
27
  except ImportError:
17
- logger.warning("composio module not installed. ComposioTool will not be available.")
18
- COMPOSIO_AVAILABLE = False
19
- # Create dummy classes to avoid errors
20
- class Action:
21
- pass
22
- class ComposioToolSet:
23
- pass
24
-
25
- from quantalogic.tools.tool import Tool, ToolArgument
28
+ pass
26
29
 
27
30
 
28
31
  def setup_logger():
@@ -84,7 +87,7 @@ class ComposioTool(Tool):
84
87
  )
85
88
  action: str = Field(default="") # Single action per tool instance
86
89
  action_schema: Optional[ActionSchema] = None
87
- toolset: Optional[ComposioToolSet] = None
90
+ toolset: Optional['ComposioToolSet'] = None
88
91
 
89
92
  # Performance tracking
90
93
  _last_execution_time: Optional[datetime] = None
@@ -113,6 +116,14 @@ class ComposioTool(Tool):
113
116
  logger.error("ComposioTool cannot be initialized: composio module is not installed")
114
117
  raise ImportError("The 'composio' package is required to use ComposioTool. "
115
118
  "Install it with 'pip install composio' or include it in your dependencies.")
119
+
120
+ # Import composio only when needed
121
+ try:
122
+ from composio import Action, ComposioToolSet
123
+ except ImportError:
124
+ logger.error("Failed to import composio module")
125
+ raise ImportError("The 'composio' package is required to use ComposioTool. "
126
+ "Install it with 'pip install composio' or include it in your dependencies.")
116
127
 
117
128
  logger.info(f"Initializing ComposioTool for action: {action}")
118
129
  start_time = datetime.now()
@@ -168,6 +179,14 @@ class ComposioTool(Tool):
168
179
 
169
180
  def _setup_action(self) -> None:
170
181
  """Set up the Composio action with its schema and parameters."""
182
+ # Import composio only when needed
183
+ try:
184
+ from composio import Action, ComposioToolSet
185
+ except ImportError:
186
+ logger.error("Failed to import composio module")
187
+ raise ImportError("The 'composio' package is required to use ComposioTool. "
188
+ "Install it with 'pip install composio' or include it in your dependencies.")
189
+
171
190
  logger.debug(f"Setting up action: {self.action}")
172
191
  start_time = datetime.now()
173
192
 
@@ -363,6 +382,14 @@ class ComposioTool(Tool):
363
382
 
364
383
  def execute(self, **kwargs: Any) -> str:
365
384
  """Execute the Composio action with the given parameters."""
385
+ # Import composio only when needed
386
+ try:
387
+ from composio import Action, ComposioToolSet
388
+ except ImportError:
389
+ logger.error("Failed to import composio module")
390
+ raise ImportError("The 'composio' package is required to use ComposioTool. "
391
+ "Install it with 'pip install composio' or include it in your dependencies.")
392
+
366
393
  start_time = datetime.now()
367
394
  self._execution_count += 1
368
395
  self._last_execution_time = start_time
@@ -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
- from sqlalchemy import create_engine, inspect, text
10
- from sqlalchemy.engine import Engine
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
- from typing import Any, Dict, List
3
+ import importlib.util
4
+ from typing import Any, Dict, List, TYPE_CHECKING
4
5
 
5
6
  from pydantic import Field, ValidationError
6
- from sqlalchemy import create_engine, text
7
- from sqlalchemy.exc import SQLAlchemyError
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
- raise RuntimeError(f"Database Error: {str(e)}") from e
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
- from faker import Faker
5
- from sqlalchemy import Column, Date, Float, ForeignKey, Integer, String, create_engine
6
- from sqlalchemy.orm import declarative_base, relationship, sessionmaker
7
-
8
- Base = declarative_base()
9
- fake = Faker()
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
- import networkx as nx
5
- from sqlalchemy import create_engine, inspect, text
6
- from sqlalchemy.engine import Inspector
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
3
+ Version: 0.50.6
4
4
  Summary: QuantaLogic ReAct Agents
5
5
  Author: Raphaël MANSUY
6
6
  Author-email: raphael.mansuy@gmail.com
@@ -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=Hpgt8RslYAwAfaKYunTFz_tsNdIZUXH5ovssNZu0H0c,5142
41
+ quantalogic/tools/__init__.py,sha256=0ZwUnszv8GFW_Ml56ih_V0ilUkALmRfTK22vengmP5s,5139
42
42
  quantalogic/tools/agent_tool.py,sha256=MXCXxWHRch7VK4UWhtRP1jeI8Np9Ne2CUGo8vm1oZiM,3064
43
- quantalogic/tools/composio/composio.py,sha256=1FJ8lyZUslQpewX7WUF-sanF0f52gmL0-ZQFBXkiqaE,18373
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=Vale-5nR3e-Mm4joOBII8T1PbLcshXYbM8Mp4TJsS30,9425
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=jEDZLlxOsB2bzsWlEqsqvTKiyovnRuk0XvgtwW7-WSQ,6055
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=h5c_uxv3eztQvHlloTZxzWt5gEzai8zfnR8-_QrUqxU,3724
121
- quantalogic/tools/utils/generate_database_report.py,sha256=3PT34ClMvZ2O62-24cp_5lOyZHY_pBjVObMHpfyVi-s,10140
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.3.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
145
- quantalogic-0.50.3.dist-info/METADATA,sha256=8yPjleuhCSPRiv7lwPRB5vObHFWMyrU0Ih7A4W2PA1Y,22785
146
- quantalogic-0.50.3.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
147
- quantalogic-0.50.3.dist-info/entry_points.txt,sha256=h74O_Q3qBRCrDR99qvwB4BpBGzASPUIjCfxHq6Qnups,183
148
- quantalogic-0.50.3.dist-info/RECORD,,
144
+ quantalogic-0.50.6.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
145
+ quantalogic-0.50.6.dist-info/METADATA,sha256=eVBh6BPUPZPaaeJ9b8JQVdk0ntzzAeXAajF-l5FAAn0,22785
146
+ quantalogic-0.50.6.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
147
+ quantalogic-0.50.6.dist-info/entry_points.txt,sha256=h74O_Q3qBRCrDR99qvwB4BpBGzASPUIjCfxHq6Qnups,183
148
+ quantalogic-0.50.6.dist-info/RECORD,,