-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
fix: wrapper defects - scheduler timeout, tool loading, and YAML surface #1741
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
bcd4ddd
04caea0
0eebd11
e89ce7b
45dcaa9
775d4f1
1713eec
e4e9bad
7cadf19
3e9a8aa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -454,37 +454,66 @@ def get_local_tool_classes(self) -> Dict[str, Any]: | |
| module = load_user_module(self._tools_py_path, name="tools_module") | ||
| if module is None: | ||
| return {} | ||
| return self._extract_tool_classes(module) | ||
| except Exception as e: | ||
| logger.warning(f"Error loading tool classes from {self._tools_py_path}: {e}") | ||
| return {} | ||
|
|
||
| def get_local_tool_classes_from_dir(self, tools_dir: "os.PathLike|str") -> Dict[str, Any]: | ||
| """Load BaseTool/langchain classes from every *.py in a tools/ directory. | ||
|
|
||
| Args: | ||
| tools_dir: Path to the tools directory | ||
|
|
||
| # Import the necessary classes (matching agents_generator.py logic) | ||
| BaseTool = None | ||
| PRAISONAI_TOOLS_AVAILABLE = False | ||
| Returns: | ||
| Dictionary mapping class names to instantiated tool objects | ||
| """ | ||
| from pathlib import Path | ||
| from ._safe_loader import load_user_module | ||
|
|
||
| classes: Dict[str, Any] = {} | ||
| for py_file in Path(tools_dir).glob("*.py"): | ||
| if py_file.name.startswith("__"): | ||
| continue | ||
| try: | ||
| from praisonai_tools import BaseTool | ||
| module = load_user_module(py_file, name=f"tools_{py_file.stem}") | ||
| if module is not None: | ||
| classes.update(self._extract_tool_classes(module)) | ||
| except Exception as e: | ||
| logger.warning(f"Error loading tool classes from file {py_file}: {e}") | ||
| return classes | ||
|
|
||
| def _extract_tool_classes(self, module): | ||
| """Extract tool classes from a loaded module that inherit from BaseTool | ||
| or are part of langchain_community.tools package. | ||
| """ | ||
| # Import the necessary classes (matching agents_generator.py logic) | ||
| BaseTool = None | ||
| PRAISONAI_TOOLS_AVAILABLE = False | ||
| try: | ||
| from praisonai_tools import BaseTool | ||
| PRAISONAI_TOOLS_AVAILABLE = True | ||
| except ImportError: | ||
| try: | ||
| from praisonai.tools import BaseTool | ||
| PRAISONAI_TOOLS_AVAILABLE = True | ||
| except ImportError: | ||
| try: | ||
| from praisonai.tools import BaseTool | ||
| PRAISONAI_TOOLS_AVAILABLE = True | ||
| except ImportError: | ||
| pass | ||
|
|
||
| result = {} | ||
| for name, obj in inspect.getmembers(module, | ||
| lambda x: inspect.isclass(x) and ( | ||
| x.__module__.startswith('langchain_community.tools') or | ||
| (PRAISONAI_TOOLS_AVAILABLE and BaseTool and issubclass(x, BaseTool)) | ||
| ) and x is not BaseTool): | ||
| try: | ||
| result[name] = obj() | ||
| logger.debug(f"Loaded local tool class: {name}") | ||
| except Exception as e: | ||
| logger.warning(f"Error instantiating tool class {name}: {e}") | ||
| continue | ||
|
|
||
| return result | ||
| except Exception as e: | ||
| logger.warning(f"Error loading tool classes from {self._tools_py_path}: {e}") | ||
| return {} | ||
| pass | ||
|
greptile-apps[bot] marked this conversation as resolved.
|
||
|
|
||
| result = {} | ||
| for name, obj in inspect.getmembers(module, | ||
| lambda x: inspect.isclass(x) and ( | ||
| x.__module__.startswith('langchain_community.tools') or | ||
| (PRAISONAI_TOOLS_AVAILABLE and BaseTool and issubclass(x, BaseTool)) | ||
| ) and x is not BaseTool): | ||
| try: | ||
| result[name] = obj() | ||
| logger.debug(f"Loaded tool class: {name}") | ||
| except Exception as e: | ||
| logger.warning(f"Error instantiating tool class {name}: {e}") | ||
| continue | ||
|
|
||
| return result | ||
|
Comment on lines
+486
to
+516
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win Reuse this helper from
Proposed refactor def get_local_tool_classes(self) -> Dict[str, Any]:
"""Get BaseTool/langchain class instances from tools.py (path B semantics).
Returns:
Dictionary mapping class names to instantiated tool objects
"""
try:
# Use the same safe loader to get the module
module = load_user_module(self._tools_py_path, name="tools_module")
if module is None:
return {}
-
- # Import the necessary classes (matching agents_generator.py logic)
- BaseTool = None
- PRAISONAI_TOOLS_AVAILABLE = False
- try:
- from praisonai_tools import BaseTool
- PRAISONAI_TOOLS_AVAILABLE = True
- except ImportError:
- try:
- from praisonai.tools import BaseTool
- PRAISONAI_TOOLS_AVAILABLE = True
- except ImportError:
- pass
-
- result = {}
- for name, obj in inspect.getmembers(module,
- lambda x: inspect.isclass(x) and (
- x.__module__.startswith('langchain_community.tools') or
- (PRAISONAI_TOOLS_AVAILABLE and BaseTool and issubclass(x, BaseTool))
- ) and x is not BaseTool):
- try:
- result[name] = obj()
- logger.debug(f"Loaded local tool class: {name}")
- except Exception as e:
- logger.warning(f"Error instantiating tool class {name}: {e}")
- continue
-
- return result
+ return self._extract_tool_classes(module)
except Exception as e:
logger.warning(f"Error loading tool classes from {self._tools_py_path}: {e}")
return {}🧰 Tools🪛 Ruff (0.15.13)[warning] 539-539: Do not catch blind exception: (BLE001) 🤖 Prompt for AI Agents |
||
|
|
||
|
|
||
| # Process-level lazy singleton for performance (matches profiler.py pattern) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: MervinPraison/PraisonAI
Length of output: 406
🏁 Script executed:
Repository: MervinPraison/PraisonAI
Length of output: 172
🏁 Script executed:
Repository: MervinPraison/PraisonAI
Length of output: 10497
🏁 Script executed:
Repository: MervinPraison/PraisonAI
Length of output: 4253
🏁 Script executed:
Repository: MervinPraison/PraisonAI
Length of output: 423
Fix unresolved
BaseToolingenerate_crew_and_kickoff()src/praisonai/praisonai/agents_generator.pyreferencesBaseToolingenerate_crew_and_kickoff()(issubclass(tool_class, BaseTool), line ~613), but this file has noBaseToolimport/assignment (only a comment/docstring mention). Ifself.toolscontains any classes, this will raiseNameErrorbefore tools get registered. Replace the check with the base tool type provided byToolResolver(or reintroduce a safe import/definition).🤖 Prompt for AI Agents