feat: Add human-in-the-loop approval system for dangerous tool operations#566
Conversation
…ions Implements human approval framework for dangerous operations like shell commands, code execution, and file operations to enhance security and user control. Key features: - @require_approval decorator for marking dangerous tools - Risk-based approval (critical, high, medium, low) - Console approval interface with rich formatting - Custom approval callbacks for automated policies - Async/sync support for all workflows - Runtime configuration of approval requirements Protected operations: - Critical: execute_command, kill_process, execute_code - High: write_file, delete_file, move_file, copy_file - Medium: evaluate, crawl, scrape_page Files modified: - New approval.py module with core framework - Enhanced main.py with approval callback support - Modified agent.py to check approvals before tool execution - Added @require_approval decorators to dangerous tools - Comprehensive example and test implementations Resolves: #12 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: MervinPraison <MervinPraison@users.noreply.github.com>
WalkthroughA comprehensive human-in-the-loop approval framework is introduced for PraisonAI agents, enforcing explicit approval before executing potentially dangerous operations. This includes decorators for risk classification, customizable approval callbacks, synchronous and asynchronous support, runtime configuration, and extensive tests and examples demonstrating integration with agent tools for Python execution, file, and shell operations. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Agent
participant ApprovalSystem
participant Tool
User->>Agent: Initiate task (e.g., run Python code)
Agent->>ApprovalSystem: Check if approval required for tool
alt Approval required
ApprovalSystem->>User: Prompt for approval (console/async/callback)
User-->>ApprovalSystem: Approve or Deny
ApprovalSystem->>Agent: Return approval decision
alt Approved
Agent->>Tool: Execute tool with arguments
Tool-->>Agent: Return result
else Denied
Agent-->>User: Report denial, abort execution
end
else No approval required
Agent->>Tool: Execute tool
Tool-->>Agent: Return result
end
Agent-->>User: Return result or error
Assessment against linked issues
Assessment against linked issues: Out-of-scope changesNo out-of-scope functional code changes were identified. All changes are directly related to implementing, integrating, or testing the human approval system for agent operations as described in the linked issue. Poem
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Hello @MervinPraison, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!
Summary of Changes
Hello team, Gemini here providing a summary of this pull request. This PR introduces a crucial human-in-the-loop approval system for potentially dangerous tool operations executed by agents. The primary goal is to enhance security and provide users with explicit control over actions like executing shell commands, running code, or performing file system modifications. The implementation includes a new approval module, integration points within the Agent class for both sync and async execution, decorators to mark tools requiring approval, a default console-based approval interface using rich, support for custom approval callbacks, and runtime configuration options for approval requirements. A comprehensive example and basic tests are also included.
Highlights
- Human-in-the-Loop Approval: Introduces a framework requiring human approval before agents execute certain predefined 'dangerous' tool functions.
- Risk Level Classification: Tools are assigned risk levels (critical, high, medium, low) to help prioritize and inform approval decisions.
- Flexible Approval Callbacks: Provides a default console-based interactive approval prompt and allows registering custom callbacks for automated policies or alternative interfaces. Supports modifying tool arguments during approval.
- Sync and Async Support: The approval flow is integrated into both synchronous (
execute_tool) and asynchronous (execute_tool_async) agent execution paths. - Runtime Configuration: Approval requirements can be added or removed dynamically at runtime using dedicated functions.
- Tool Decorators: Uses the
@require_approvaldecorator to easily mark specific tool functions and assign their risk level.
Changelog
Click here to see the changelog
- examples/python/general/human_approval_example.py
- Added a new example script demonstrating the human approval system.
- Includes examples of default console approval, custom callback implementation, and manual requirement configuration.
- Shows how to use the system with both sync and async agent processes.
- src/praisonai-agents/praisonaiagents/agent/agent.py
- Imported necessary functions and the global approval callback from the new
approvalandmainmodules (around lines 19-20). - Integrated approval check and flow into the synchronous
execute_toolmethod (around lines 574-598). - Integrated approval check and flow into the asynchronous
execute_tool_asyncmethod (around lines 1449-1461).
- Imported necessary functions and the global approval callback from the new
- src/praisonai-agents/praisonaiagents/approval.py
- Added a new module containing the core logic for the human approval framework.
- Defines global registries for required tools and risk levels.
- Introduces the
ApprovalDecisionclass andset_approval_callbackfunction. - Implements the
@require_approvaldecorator. - Provides
console_approval_callbackas the default interactive handler usingrich. - Implements the async
request_approvalfunction to manage the approval flow, including handling sync callbacks in an executor. - Defines default dangerous tools and functions for runtime configuration (
add_approval_requirement,remove_approval_requirement).
- src/praisonai-agents/praisonaiagents/main.py
- Added a global
approval_callbackvariable (around line 47). - Added
register_approval_callbackfunction to set the global callback (around lines 74-81). - Exported new approval-related items in
__all__(around lines 53-57).
- Added a global
- src/praisonai-agents/praisonaiagents/tools/file_tools.py
- Imported the
require_approvaldecorator (around line 19). - Applied
@require_approval(risk_level="high")towrite_file(line 45),copy_file(line 139),move_file(line 162), anddelete_file(line 185).
- Imported the
- src/praisonai-agents/praisonaiagents/tools/python_tools.py
- Imported the
require_approvaldecorator (around line 18). - Applied
@require_approval(risk_level="critical")toexecute_code(line 40).
- Imported the
- src/praisonai-agents/praisonaiagents/tools/shell_tools.py
- Imported the
require_approvaldecorator (around line 16). - Applied
@require_approval(risk_level="critical")toexecute_command(line 35) andkill_process(line 151).
- Imported the
- test_approval_basic.py
- Added a new basic test script to verify the core components of the approval system.
- Tests imports, the
ApprovalDecisionclass, requirement configuration functions, and default dangerous tool configuration.
Using Gemini Code Assist
The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.
Invoking Gemini
You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.
| Feature | Command | Description |
|---|---|---|
| Code Review | /gemini review |
Performs a code review for the current pull request in its current state. |
| Pull Request Summary | /gemini summary |
Provides a summary of the current pull request in its current state. |
| Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in issue comments and review comments. |
| Help | /gemini help |
Displays a list of available commands. |
Customization
To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.
Limitations & Feedback
Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments to provide feedback.
You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.
Agent plans a risky deed,
A human eye is what we need.
'Execute?' it asks with dread,
'Approve' or 'Deny' is said.
Safety first, the code agreed.
Footnotes
-
Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩
There was a problem hiding this comment.
Code Review
This pull request introduces a robust human-in-the-loop approval system for dangerous tool operations. The core logic is well-implemented in the new approval.py module, and the integration into the agent's tool execution flow covers both synchronous and asynchronous paths. The use of rich for console interactions and the dynamic configuration options are excellent additions. The provided example script is very helpful for understanding and testing the new functionality.
One critical area for attention is ensuring the custom approval callback registered via the main API is consistently applied in both sync and async tool executions. Additionally, enhancing test coverage for the end-to-end approval flow would further solidify this feature.
Summary of Findings
- Inconsistent Custom Approval Callback Usage (Async vs. Sync): The custom approval callback registered via
praisonaiagents.main.register_approval_callbackis correctly used by the synchronousagent.execute_toolpath but not by the asynchronousagent.execute_tool_asyncpath. The async path relies onpraisonaiagents.approval.request_approval, which usespraisonaiagents.approval.approval_callback. This can lead to the custom callback being ignored in async scenarios. - Test Coverage for Approval Flow: The current tests in
test_approval_basic.pycover basic imports and configuration. It's recommended to add integration tests that mock user input or the approval callback to verify the end-to-end approval flow within an agent's tool execution.
Merge Readiness
This pull request introduces a significant and well-implemented security feature. However, there is a high-severity issue regarding the consistent application of custom approval callbacks in asynchronous scenarios that should be addressed before merging. Additionally, considering enhancements to test coverage would be beneficial. I am unable to approve pull requests, but I recommend that these changes be made and then the PR be reviewed again before merging.
| def register_approval_callback(callback_fn): | ||
| """Register a global approval callback function for dangerous tool operations. | ||
|
|
||
| Args: | ||
| callback_fn: Function that takes (function_name, arguments, risk_level) and returns ApprovalDecision | ||
| """ | ||
| global approval_callback | ||
| approval_callback = callback_fn |
There was a problem hiding this comment.
It appears there's a potential inconsistency in how the custom approval callback is applied between synchronous and asynchronous tool executions.
This register_approval_callback function sets praisonaiagents.main.approval_callback.
- The synchronous
Agent.execute_toolmethod correctly uses thismain.approval_callback. - However, the asynchronous
Agent.execute_tool_asyncmethod callspraisonaiagents.approval.request_approval, which in turn usespraisonaiagents.approval.approval_callback(a different global variable from theapprovalmodule itself).
This means a callback registered via main.register_approval_callback might not be invoked during asynchronous tool operations, potentially falling back to the default console approval.
Could we ensure that main.register_approval_callback also updates the callback used by the approval module, perhaps by calling approval.set_approval_callback within this function? This would ensure consistent behavior.
def register_approval_callback(callback_fn):
"""Register a global approval callback function for dangerous tool operations.
Args:
callback_fn: Function that takes (function_name, arguments, risk_level) and returns ApprovalDecision
"""
global approval_callback
approval_callback = callback_fn
# Ensure the approval module also uses this callback for consistency in async paths
from . import approval as approval_module
if hasattr(approval_module, 'set_approval_callback'):
approval_module.set_approval_callback(callback_fn)| def test_imports(): | ||
| """Test that all the new approval imports work correctly.""" | ||
| try: | ||
| print("Testing approval module import...") | ||
| from praisonaiagents.approval import ( | ||
| require_approval, | ||
| ApprovalDecision, | ||
| console_approval_callback, | ||
| request_approval, | ||
| is_approval_required, | ||
| get_risk_level, | ||
| add_approval_requirement, | ||
| remove_approval_requirement | ||
| ) | ||
| print("✅ Approval module imports successful") | ||
|
|
||
| print("Testing main module approval functions...") | ||
| from praisonaiagents.main import register_approval_callback, approval_callback | ||
| print("✅ Main module approval functions imported successfully") | ||
|
|
||
| print("Testing agent modifications...") | ||
| from praisonaiagents.agent import Agent | ||
| print("✅ Agent class imports successfully") | ||
|
|
||
| print("Testing tool decorators...") | ||
| from praisonaiagents.tools.shell_tools import ShellTools | ||
| from praisonaiagents.tools.python_tools import PythonTools | ||
| from praisonaiagents.tools.file_tools import FileTools | ||
| print("✅ Tool classes with decorators imported successfully") | ||
|
|
||
| return True | ||
|
|
||
| except ImportError as e: | ||
| print(f"❌ Import error: {e}") | ||
| return False | ||
| except Exception as e: | ||
| print(f"❌ Unexpected error: {e}") | ||
| return False | ||
|
|
||
| def test_approval_decision(): | ||
| """Test the ApprovalDecision class.""" | ||
| try: | ||
| from praisonaiagents.approval import ApprovalDecision | ||
|
|
||
| # Test approved decision | ||
| decision = ApprovalDecision(approved=True, reason="Test approval") | ||
| assert decision.approved == True | ||
| assert decision.reason == "Test approval" | ||
| print("✅ ApprovalDecision class works correctly") | ||
|
|
||
| return True | ||
| except Exception as e: | ||
| print(f"❌ ApprovalDecision test failed: {e}") | ||
| return False | ||
|
|
||
| def test_approval_requirements(): | ||
| """Test approval requirement configuration.""" | ||
| try: | ||
| from praisonaiagents.approval import ( | ||
| add_approval_requirement, | ||
| remove_approval_requirement, | ||
| is_approval_required, | ||
| get_risk_level | ||
| ) | ||
|
|
||
| # Test adding requirement | ||
| add_approval_requirement("test_function", "high") | ||
| assert is_approval_required("test_function") == True | ||
| assert get_risk_level("test_function") == "high" | ||
|
|
||
| # Test removing requirement | ||
| remove_approval_requirement("test_function") | ||
| assert is_approval_required("test_function") == False | ||
| assert get_risk_level("test_function") is None | ||
|
|
||
| print("✅ Approval requirement configuration works correctly") | ||
| return True | ||
|
|
||
| except Exception as e: | ||
| print(f"❌ Approval requirements test failed: {e}") | ||
| return False | ||
|
|
||
| def test_default_dangerous_tools(): | ||
| """Test that default dangerous tools are configured.""" | ||
| try: | ||
| from praisonaiagents.approval import is_approval_required, get_risk_level | ||
|
|
||
| # Check some default dangerous tools | ||
| dangerous_tools = ["execute_command", "execute_code", "write_file", "delete_file"] | ||
|
|
||
| for tool in dangerous_tools: | ||
| if is_approval_required(tool): | ||
| risk = get_risk_level(tool) | ||
| print(f"✅ {tool} requires approval (risk: {risk})") | ||
| else: | ||
| print(f"⚠️ {tool} does not require approval") | ||
|
|
||
| return True | ||
|
|
||
| except Exception as e: | ||
| print(f"❌ Default dangerous tools test failed: {e}") | ||
| return False | ||
|
|
||
| def main(): | ||
| """Run all basic tests.""" | ||
| print("🧪 Basic Human Approval System Tests") | ||
| print("=" * 40) | ||
|
|
||
| tests = [ | ||
| ("Import Tests", test_imports), | ||
| ("ApprovalDecision Tests", test_approval_decision), | ||
| ("Approval Requirements Tests", test_approval_requirements), | ||
| ("Default Dangerous Tools Tests", test_default_dangerous_tools) | ||
| ] | ||
|
|
||
| passed = 0 | ||
| total = len(tests) | ||
|
|
||
| for test_name, test_func in tests: | ||
| print(f"\n📋 Running {test_name}...") | ||
| if test_func(): | ||
| passed += 1 | ||
|
|
||
| print(f"\n📊 Test Results: {passed}/{total} tests passed") | ||
|
|
||
| if passed == total: | ||
| print("🎉 All basic tests passed! Human approval system is working.") | ||
| else: | ||
| print("❌ Some tests failed. Check the implementation.") | ||
|
|
||
| return passed == total |
There was a problem hiding this comment.
The basic tests for the approval system are a good start, covering imports and configuration aspects. To further ensure the robustness of this critical security feature, would it be beneficial to add integration tests?
For instance, tests could:
- Simulate an agent attempting to execute a dangerous tool.
- Mock the
input()function forconsole_approval_callbackor provide a mock custom approval callback. - Verify that the approval flow is triggered correctly.
- Check that operations are allowed or denied based on the (mocked) user's decision.
- Test the modification of arguments via
ApprovalDecision.modified_args.
This would help confirm that the end-to-end approval mechanism works as expected within the agent lifecycle.
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (14)
src/praisonai-agents/praisonaiagents/main.py (2)
46-47: Consider renaming global variable to follow naming convention.The global variable works correctly but doesn't follow Python naming conventions for module-level constants.
Consider renaming to follow the UPPER_CASE convention:
-# Global approval callback registry -approval_callback = None +# Global approval callback registry +APPROVAL_CALLBACK = NoneAnd update the function accordingly:
- global approval_callback - approval_callback = callback_fn + global APPROVAL_CALLBACK + APPROVAL_CALLBACK = callback_fn🧰 Tools
🪛 Pylint (3.3.7)
[convention] 47-47: Constant name "approval_callback" doesn't conform to UPPER_CASE naming style
(C0103)
74-82: Function implementation is correct with minor style suggestion.The
register_approval_callbackfunction correctly implements the global callback registration mechanism.Consider shortening the docstring line to meet the 100-character limit:
- callback_fn: Function that takes (function_name, arguments, risk_level) and returns ApprovalDecision + callback_fn: Function that returns ApprovalDecision for tool approval requests🧰 Tools
🪛 Pylint (3.3.7)
[convention] 78-78: Line too long (108/100)
(C0301)
[warning] 80-80: Using the global statement
(W0603)
test_approval_basic.py (2)
94-114: Clean up imports and improve readability.The test validates important default configurations correctly.
Minor style improvement:
def test_default_dangerous_tools(): """Test that default dangerous tools are configured.""" try: - from praisonaiagents.approval import is_approval_required, get_risk_level - # Check some default dangerous tools dangerous_tools = ["execute_command", "execute_code", "write_file", "delete_file"] - for tool in dangerous_tools: if is_approval_required(tool): risk = get_risk_level(tool) print(f"✅ {tool} requires approval (risk: {risk})") else: print(f"⚠️ {tool} does not require approval") - return True - except Exception as e: print(f"❌ Default dangerous tools test failed: {e}") return False🧰 Tools
🪛 Pylint (3.3.7)
[convention] 98-98: Trailing whitespace
(C0303)
[convention] 101-101: Trailing whitespace
(C0303)
[convention] 108-108: Trailing whitespace
(C0303)
[convention] 110-110: Trailing whitespace
(C0303)
[warning] 111-111: Catching too general exception Exception
(W0718)
[error] 97-97: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 97-97: Import outside toplevel (praisonaiagents.approval.is_approval_required, praisonaiagents.approval.get_risk_level)
(C0415)
144-146: Add missing final newline.The script structure is good but missing the final newline.
Add a final newline at the end of the file:
if __name__ == "__main__": success = main() sys.exit(0 if success else 1) +🧰 Tools
🪛 Pylint (3.3.7)
[convention] 146-146: Final newline missing
(C0304)
[convention] 145-145: Constant name "success" doesn't conform to UPPER_CASE naming style
(C0103)
src/praisonai-agents/praisonaiagents/agent/agent.py (3)
574-599: Fix formatting issues and improve logging efficiency.The approval checking logic is well-implemented with proper error handling and decision processing. However, there are some formatting and code quality issues to address:
Apply this diff to fix the formatting and logging issues:
- # Check if approval is required for this tool - from ..approval import is_approval_required, console_approval_callback, get_risk_level - if is_approval_required(function_name): - risk_level = get_risk_level(function_name) - logging.info(f"Tool {function_name} requires approval (risk level: {risk_level})") - - # Use global approval callback or default console callback - callback = approval_callback or console_approval_callback - - try: - decision = callback(function_name, arguments, risk_level) - if not decision.approved: - error_msg = f"Tool execution denied: {decision.reason}" - logging.warning(error_msg) - return {"error": error_msg, "approval_denied": True} - - # Use modified arguments if provided - if decision.modified_args: - arguments = decision.modified_args - logging.info(f"Using modified arguments: {arguments}") - - except Exception as e: - error_msg = f"Error during approval process: {str(e)}" - logging.error(error_msg) - return {"error": error_msg, "approval_error": True} + # Check if approval is required for this tool + from ..approval import is_approval_required, console_approval_callback, get_risk_level + if is_approval_required(function_name): + risk_level = get_risk_level(function_name) + logging.info("Tool %s requires approval (risk level: %s)", function_name, risk_level) + + # Use global approval callback or default console callback + callback = approval_callback or console_approval_callback + + try: + decision = callback(function_name, arguments, risk_level) + if not decision.approved: + error_msg = f"Tool execution denied: {decision.reason}" + logging.warning(error_msg) + return {"error": error_msg, "approval_denied": True} + + # Use modified arguments if provided + if decision.modified_args: + arguments = decision.modified_args + logging.info("Using modified arguments: %s", arguments) + + except Exception as e: + error_msg = f"Error during approval process: {str(e)}" + logging.error(error_msg) + return {"error": error_msg, "approval_error": True}🧰 Tools
🪛 Pylint (3.3.7)
[convention] 579-579: Trailing whitespace
(C0303)
[convention] 582-582: Trailing whitespace
(C0303)
[convention] 589-589: Trailing whitespace
(C0303)
[convention] 594-594: Trailing whitespace
(C0303)
[convention] 575-575: Import outside toplevel (approval.is_approval_required, approval.console_approval_callback, approval.get_risk_level)
(C0415)
[warning] 578-578: Use lazy % formatting in logging functions
(W1203)
[warning] 595-595: Catching too general exception Exception
(W0718)
[warning] 593-593: Use lazy % formatting in logging functions
(W1203)
1448-1462: Fix formatting issues and improve logging efficiency in async method.The async approval checking logic is correctly implemented and mirrors the synchronous version appropriately. However, similar formatting and logging issues need to be addressed:
Apply this diff to fix the formatting and logging issues:
- - # Check if approval is required for this tool - from ..approval import is_approval_required, request_approval - if is_approval_required(function_name): - decision = await request_approval(function_name, arguments) - if not decision.approved: - error_msg = f"Tool execution denied: {decision.reason}" - logging.warning(error_msg) - return {"error": error_msg, "approval_denied": True} - - # Use modified arguments if provided - if decision.modified_args: - arguments = decision.modified_args - logging.info(f"Using modified arguments: {arguments}") - + + # Check if approval is required for this tool + from ..approval import is_approval_required, request_approval + if is_approval_required(function_name): + decision = await request_approval(function_name, arguments) + if not decision.approved: + error_msg = f"Tool execution denied: {decision.reason}" + logging.warning(error_msg) + return {"error": error_msg, "approval_denied": True} + + # Use modified arguments if provided + if decision.modified_args: + arguments = decision.modified_args + logging.info("Using modified arguments: %s", arguments)🧰 Tools
🪛 Pylint (3.3.7)
[convention] 1448-1448: Trailing whitespace
(C0303)
[convention] 1457-1457: Trailing whitespace
(C0303)
[convention] 1462-1462: Trailing whitespace
(C0303)
[convention] 1450-1450: Import outside toplevel (approval.is_approval_required, approval.request_approval)
(C0415)
[warning] 1461-1461: Use lazy % formatting in logging functions
(W1203)
574-599: Consider moving approval imports to module level for better performance.The current implementation imports approval functions inside the methods, which could impact performance if these methods are called frequently. Consider moving the imports to the module level for better efficiency.
Move the approval imports to the top of the file with the other imports:
from ..main import ( display_error, display_tool_call, display_instruction, display_interaction, display_generating, display_self_reflection, ReflectionOutput, client, adisplay_instruction, approval_callback ) +from ..approval import is_approval_required, console_approval_callback, get_risk_level, request_approval import inspect import uuid from dataclasses import dataclassThen update the method implementations to remove the local imports:
# Check if approval is required for this tool - from ..approval import is_approval_required, console_approval_callback, get_risk_level if is_approval_required(function_name):# Check if approval is required for this tool - from ..approval import is_approval_required, request_approval if is_approval_required(function_name):Also applies to: 1448-1462
🧰 Tools
🪛 Pylint (3.3.7)
[convention] 579-579: Trailing whitespace
(C0303)
[convention] 582-582: Trailing whitespace
(C0303)
[convention] 589-589: Trailing whitespace
(C0303)
[convention] 594-594: Trailing whitespace
(C0303)
[convention] 575-575: Import outside toplevel (approval.is_approval_required, approval.console_approval_callback, approval.get_risk_level)
(C0415)
[warning] 578-578: Use lazy % formatting in logging functions
(W1203)
[warning] 595-595: Catching too general exception Exception
(W0718)
[warning] 593-593: Use lazy % formatting in logging functions
(W1203)
examples/python/general/human_approval_example.py (3)
34-59: Remove unnecessary f-string prefix.The function logic is excellent, demonstrating automated approval policies. However, there's a minor syntax issue.
Apply this diff to fix the f-string without placeholders:
- print(f"\n🔒 CUSTOM APPROVAL REQUIRED") + print("\n🔒 CUSTOM APPROVAL REQUIRED")🧰 Tools
🪛 Ruff (0.11.9)
39-39: f-string without any placeholders
Remove extraneous
fprefix(F541)
🪛 Pylint (3.3.7)
[convention] 34-34: Line too long (103/100)
(C0301)
[convention] 43-43: Trailing whitespace
(C0303)
[convention] 48-48: Trailing whitespace
(C0303)
[convention] 51-51: Trailing whitespace
(C0303)
[convention] 56-56: Trailing whitespace
(C0303)
[warning] 39-39: Using an f-string that does not have any interpolated variables
(W1309)
119-122: Remove unnecessary f-string prefix.Apply this diff to fix the f-string without placeholders:
- print(f"\n✅ Process completed successfully!") + print("\n✅ Process completed successfully!")🧰 Tools
🪛 Ruff (0.11.9)
120-120: f-string without any placeholders
Remove extraneous
fprefix(F541)
🪛 Pylint (3.3.7)
[warning] 120-120: Using an f-string that does not have any interpolated variables
(W1309)
198-204: Add missing final newline and clean up formatting.The demo conclusion is well-structured with clear takeaways. However, there are formatting issues throughout the file.
Add a newline at the end of the file and consider running a formatter to remove trailing whitespace throughout the file. Many lines have trailing spaces that should be removed for cleaner code.
🧰 Tools
🪛 Pylint (3.3.7)
[convention] 204-204: Final newline missing
(C0304)
src/praisonai-agents/praisonaiagents/approval.py (4)
27-33: Consider using dataclass for ApprovalDecision.The class structure is correct, but could benefit from modern Python features.
Consider converting to a dataclass for better type hints and cleaner syntax:
+from dataclasses import dataclass, field + -class ApprovalDecision: - """Result of an approval request""" - def __init__(self, approved: bool, modified_args: Optional[Dict[str, Any]] = None, reason: str = ""): - self.approved = approved - self.modified_args = modified_args or {} - self.reason = reason +@dataclass +class ApprovalDecision: + """Result of an approval request""" + approved: bool + modified_args: Dict[str, Any] = field(default_factory=dict) + reason: str = ""🧰 Tools
🪛 Pylint (3.3.7)
[convention] 29-29: Line too long (105/100)
(C0301)
[refactor] 27-27: Too few public methods (0/2)
(R0903)
86-96: Remove unnecessary f-string prefix.The console display implementation is excellent with good formatting and truncation logic.
Apply this diff to fix the f-string without placeholders:
- tool_info += f"[bold]Arguments:[/]\n" + tool_info += "[bold]Arguments:[/]\n"🧰 Tools
🪛 Ruff (0.11.9)
88-88: f-string without any placeholders
Remove extraneous
fprefix(F541)
🪛 Pylint (3.3.7)
[convention] 89-89: Trailing whitespace
(C0303)
[convention] 96-96: Trailing whitespace
(C0303)
[warning] 88-88: Using an f-string that does not have any interpolated variables
(W1309)
125-158: Excellent async/sync callback handling.The function properly handles both synchronous and asynchronous approval callbacks, using
run_in_executorto prevent blocking the event loop for sync callbacks. The error handling is comprehensive.Consider using lazy formatting for the logging statement on line 156 to follow logging best practices:
- logging.error(f"Error in approval callback: {e}") + logging.error("Error in approval callback: %s", e)🧰 Tools
🪛 Pylint (3.3.7)
[convention] 138-138: Trailing whitespace
(C0303)
[convention] 140-140: Trailing whitespace
(C0303)
[convention] 143-143: Trailing whitespace
(C0303)
[convention] 151-151: Line too long (103/100)
(C0301)
[convention] 152-152: Trailing whitespace
(C0303)
[convention] 154-154: Trailing whitespace
(C0303)
[warning] 155-155: Catching too general exception Exception
(W0718)
[warning] 156-156: Use lazy % formatting in logging functions
(W1203)
159-204: Well-designed configuration system with sensible defaults.The default dangerous tools are appropriately categorized by risk level, and the helper functions provide good flexibility for runtime configuration.
Add a newline at the end of the file to follow standard file formatting conventions.
🧰 Tools
🪛 Pylint (3.3.7)
[convention] 165-165: Trailing whitespace
(C0303)
[convention] 172-172: Trailing whitespace
(C0303)
[convention] 204-204: Final newline missing
(C0304)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
examples/python/general/human_approval_example.py(1 hunks)src/praisonai-agents/praisonaiagents/agent/agent.py(3 hunks)src/praisonai-agents/praisonaiagents/approval.py(1 hunks)src/praisonai-agents/praisonaiagents/main.py(2 hunks)src/praisonai-agents/praisonaiagents/tools/file_tools.py(5 hunks)src/praisonai-agents/praisonaiagents/tools/python_tools.py(2 hunks)src/praisonai-agents/praisonaiagents/tools/shell_tools.py(3 hunks)test_approval_basic.py(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (7)
src/praisonai-agents/praisonaiagents/tools/python_tools.py (1)
src/praisonai-agents/praisonaiagents/approval.py (1)
require_approval(42-67)
src/praisonai-agents/praisonaiagents/tools/shell_tools.py (1)
src/praisonai-agents/praisonaiagents/approval.py (1)
require_approval(42-67)
test_approval_basic.py (3)
src/praisonai-agents/praisonaiagents/approval.py (8)
require_approval(42-67)ApprovalDecision(27-32)console_approval_callback(69-123)request_approval(125-157)is_approval_required(195-197)get_risk_level(199-201)add_approval_requirement(185-188)remove_approval_requirement(190-193)src/praisonai-agents/praisonaiagents/main.py (1)
register_approval_callback(74-81)src/praisonai-agents/praisonaiagents/agent/agent.py (1)
Agent(205-1827)
src/praisonai-agents/praisonaiagents/agent/agent.py (1)
src/praisonai-agents/praisonaiagents/approval.py (4)
is_approval_required(195-197)console_approval_callback(69-123)get_risk_level(199-201)request_approval(125-157)
examples/python/general/human_approval_example.py (3)
src/praisonai-agents/praisonaiagents/agent/agent.py (2)
Agent(205-1827)run(1436-1438)src/praisonai-agents/praisonaiagents/main.py (1)
register_approval_callback(74-81)src/praisonai-agents/praisonaiagents/approval.py (4)
console_approval_callback(69-123)ApprovalDecision(27-32)add_approval_requirement(185-188)remove_approval_requirement(190-193)
src/praisonai-agents/praisonaiagents/tools/file_tools.py (1)
src/praisonai-agents/praisonaiagents/approval.py (1)
require_approval(42-67)
src/praisonai-agents/praisonaiagents/approval.py (1)
src/praisonai-agents/praisonaiagents/mcp/mcp_sse.py (1)
get_event_loop(22-28)
🪛 Pylint (3.3.7)
src/praisonai-agents/praisonaiagents/main.py
[convention] 47-47: Constant name "approval_callback" doesn't conform to UPPER_CASE naming style
(C0103)
[convention] 78-78: Line too long (108/100)
(C0301)
[warning] 80-80: Using the global statement
(W0603)
test_approval_basic.py
[convention] 9-9: Trailing whitespace
(C0303)
[convention] 27-27: Trailing whitespace
(C0303)
[convention] 31-31: Trailing whitespace
(C0303)
[convention] 35-35: Trailing whitespace
(C0303)
[convention] 38-38: Trailing whitespace
(C0303)
[convention] 41-41: Trailing whitespace
(C0303)
[convention] 43-43: Trailing whitespace
(C0303)
[convention] 55-55: Trailing whitespace
(C0303)
[convention] 61-61: Trailing whitespace
(C0303)
[convention] 76-76: Trailing whitespace
(C0303)
[convention] 81-81: Trailing whitespace
(C0303)
[convention] 86-86: Trailing whitespace
(C0303)
[convention] 89-89: Trailing whitespace
(C0303)
[convention] 98-98: Trailing whitespace
(C0303)
[convention] 101-101: Trailing whitespace
(C0303)
[convention] 108-108: Trailing whitespace
(C0303)
[convention] 110-110: Trailing whitespace
(C0303)
[convention] 119-119: Trailing whitespace
(C0303)
[convention] 126-126: Trailing whitespace
(C0303)
[convention] 129-129: Trailing whitespace
(C0303)
[convention] 134-134: Trailing whitespace
(C0303)
[convention] 136-136: Trailing whitespace
(C0303)
[convention] 141-141: Trailing whitespace
(C0303)
[convention] 146-146: Final newline missing
(C0304)
[warning] 47-47: Catching too general exception Exception
(W0718)
[convention] 16-25: Import outside toplevel (praisonaiagents.approval.require_approval, praisonaiagents.approval.ApprovalDecision, praisonaiagents.approval.console_approval_callback, praisonaiagents.approval.request_approval, praisonaiagents.approval.is_approval_required, praisonaiagents.approval.get_risk_level, praisonaiagents.approval.add_approval_requirement, praisonaiagents.approval.remove_approval_requirement)
(C0415)
[convention] 29-29: Import outside toplevel (praisonaiagents.main.register_approval_callback, praisonaiagents.main.approval_callback)
(C0415)
[convention] 33-33: Import outside toplevel (praisonaiagents.agent.Agent)
(C0415)
[convention] 37-37: Import outside toplevel (praisonaiagents.tools.shell_tools.ShellTools)
(C0415)
[convention] 38-38: Import outside toplevel (praisonaiagents.tools.python_tools.PythonTools)
(C0415)
[convention] 39-39: Import outside toplevel (praisonaiagents.tools.file_tools.FileTools)
(C0415)
[warning] 16-25: Unused require_approval imported from praisonaiagents.approval
(W0611)
[warning] 16-25: Unused ApprovalDecision imported from praisonaiagents.approval
(W0611)
[warning] 16-25: Unused console_approval_callback imported from praisonaiagents.approval
(W0611)
[warning] 16-25: Unused request_approval imported from praisonaiagents.approval
(W0611)
[warning] 16-25: Unused is_approval_required imported from praisonaiagents.approval
(W0611)
[warning] 16-25: Unused get_risk_level imported from praisonaiagents.approval
(W0611)
[warning] 16-25: Unused add_approval_requirement imported from praisonaiagents.approval
(W0611)
[warning] 16-25: Unused remove_approval_requirement imported from praisonaiagents.approval
(W0611)
[warning] 29-29: Unused register_approval_callback imported from praisonaiagents.main
(W0611)
[warning] 29-29: Unused approval_callback imported from praisonaiagents.main
(W0611)
[warning] 33-33: Unused Agent imported from praisonaiagents.agent
(W0611)
[warning] 37-37: Unused ShellTools imported from praisonaiagents.tools.shell_tools
(W0611)
[warning] 38-38: Unused PythonTools imported from praisonaiagents.tools.python_tools
(W0611)
[warning] 39-39: Unused FileTools imported from praisonaiagents.tools.file_tools
(W0611)
[warning] 63-63: Catching too general exception Exception
(W0718)
[error] 54-54: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 54-54: Import outside toplevel (praisonaiagents.approval.ApprovalDecision)
(C0415)
[convention] 58-58: Comparison 'decision.approved == True' should be 'decision.approved is True' if checking for the singleton value True, or 'decision.approved' if testing for truthiness
(C0121)
[warning] 90-90: Catching too general exception Exception
(W0718)
[error] 70-75: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 70-75: Import outside toplevel (praisonaiagents.approval.add_approval_requirement, praisonaiagents.approval.remove_approval_requirement, praisonaiagents.approval.is_approval_required, praisonaiagents.approval.get_risk_level)
(C0415)
[convention] 79-79: Comparison 'is_approval_required('test_function') == True' should be 'is_approval_required('test_function') is True' if checking for the singleton value True, or 'is_approval_required('test_function')' if testing for truthiness
(C0121)
[convention] 84-84: Comparison 'is_approval_required('test_function') == False' should be 'is_approval_required('test_function') is False' if checking for the singleton value False, or 'not is_approval_required('test_function')' if testing for falsiness
(C0121)
[warning] 111-111: Catching too general exception Exception
(W0718)
[error] 97-97: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 97-97: Import outside toplevel (praisonaiagents.approval.is_approval_required, praisonaiagents.approval.get_risk_level)
(C0415)
[convention] 145-145: Constant name "success" doesn't conform to UPPER_CASE naming style
(C0103)
src/praisonai-agents/praisonaiagents/agent/agent.py
[convention] 579-579: Trailing whitespace
(C0303)
[convention] 582-582: Trailing whitespace
(C0303)
[convention] 589-589: Trailing whitespace
(C0303)
[convention] 594-594: Trailing whitespace
(C0303)
[convention] 575-575: Import outside toplevel (approval.is_approval_required, approval.console_approval_callback, approval.get_risk_level)
(C0415)
[warning] 578-578: Use lazy % formatting in logging functions
(W1203)
[warning] 595-595: Catching too general exception Exception
(W0718)
[warning] 593-593: Use lazy % formatting in logging functions
(W1203)
[convention] 1448-1448: Trailing whitespace
(C0303)
[convention] 1457-1457: Trailing whitespace
(C0303)
[convention] 1462-1462: Trailing whitespace
(C0303)
[convention] 1450-1450: Import outside toplevel (approval.is_approval_required, approval.request_approval)
(C0415)
[warning] 1461-1461: Use lazy % formatting in logging functions
(W1203)
examples/python/general/human_approval_example.py
[convention] 25-25: Trailing whitespace
(C0303)
[convention] 34-34: Line too long (103/100)
(C0301)
[convention] 43-43: Trailing whitespace
(C0303)
[convention] 48-48: Trailing whitespace
(C0303)
[convention] 51-51: Trailing whitespace
(C0303)
[convention] 56-56: Trailing whitespace
(C0303)
[convention] 62-62: Trailing whitespace
(C0303)
[convention] 68-68: Trailing whitespace
(C0303)
[convention] 73-73: Trailing whitespace
(C0303)
[convention] 82-82: Trailing whitespace
(C0303)
[convention] 106-106: Trailing whitespace
(C0303)
[convention] 113-113: Trailing whitespace
(C0303)
[convention] 117-117: Trailing whitespace
(C0303)
[convention] 129-129: Trailing whitespace
(C0303)
[convention] 132-132: Trailing whitespace
(C0303)
[convention] 136-136: Trailing whitespace
(C0303)
[convention] 140-140: Trailing whitespace
(C0303)
[convention] 148-148: Trailing whitespace
(C0303)
[convention] 151-151: Trailing whitespace
(C0303)
[convention] 155-155: Trailing whitespace
(C0303)
[convention] 160-160: Trailing whitespace
(C0303)
[convention] 167-167: Trailing whitespace
(C0303)
[convention] 173-173: Trailing whitespace
(C0303)
[convention] 182-182: Trailing whitespace
(C0303)
[convention] 185-185: Trailing whitespace
(C0303)
[convention] 188-188: Trailing whitespace
(C0303)
[convention] 197-197: Trailing whitespace
(C0303)
[convention] 204-204: Final newline missing
(C0304)
[error] 21-21: Unable to import 'praisonaiagents'
(E0401)
[error] 22-22: Unable to import 'praisonaiagents.tools'
(E0401)
[error] 23-23: Unable to import 'praisonaiagents.main'
(E0401)
[error] 24-29: Unable to import 'praisonaiagents.approval'
(E0401)
[warning] 39-39: Using an f-string that does not have any interpolated variables
(W1309)
[warning] 124-124: Catching too general exception Exception
(W0718)
[warning] 120-120: Using an f-string that does not have any interpolated variables
(W1309)
[error] 142-142: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 142-142: Import outside toplevel (praisonaiagents.approval.APPROVAL_REQUIRED_TOOLS, praisonaiagents.approval.TOOL_RISK_LEVELS)
(C0415)
[warning] 177-177: Catching too general exception Exception
(W0718)
[warning] 23-23: Unused register_approval_callback imported from praisonaiagents.main
(W0611)
src/praisonai-agents/praisonaiagents/approval.py
[convention] 29-29: Line too long (105/100)
(C0301)
[convention] 52-52: Trailing whitespace
(C0303)
[convention] 56-56: Trailing whitespace
(C0303)
[convention] 60-60: Trailing whitespace
(C0303)
[convention] 66-66: Trailing whitespace
(C0303)
[convention] 69-69: Line too long (114/100)
(C0301)
[convention] 75-75: Trailing whitespace
(C0303)
[convention] 84-84: Trailing whitespace
(C0303)
[convention] 89-89: Trailing whitespace
(C0303)
[convention] 96-96: Trailing whitespace
(C0303)
[convention] 103-103: Trailing whitespace
(C0303)
[convention] 110-110: Trailing whitespace
(C0303)
[convention] 117-117: Trailing whitespace
(C0303)
[convention] 138-138: Trailing whitespace
(C0303)
[convention] 140-140: Trailing whitespace
(C0303)
[convention] 143-143: Trailing whitespace
(C0303)
[convention] 151-151: Line too long (103/100)
(C0301)
[convention] 152-152: Trailing whitespace
(C0303)
[convention] 154-154: Trailing whitespace
(C0303)
[convention] 165-165: Trailing whitespace
(C0303)
[convention] 172-172: Trailing whitespace
(C0303)
[convention] 204-204: Final newline missing
(C0304)
[refactor] 27-27: Too few public methods (0/2)
(R0903)
[warning] 39-39: Using the global statement
(W0603)
[refactor] 62-65: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it
(R1705)
[warning] 88-88: Using an f-string that does not have any interpolated variables
(W1309)
[warning] 121-121: Catching too general exception Exception
(W0718)
[refactor] 111-116: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it
(R1705)
[warning] 155-155: Catching too general exception Exception
(W0718)
[warning] 156-156: Use lazy % formatting in logging functions
(W1203)
[warning] 14-14: Unused Text imported from rich.text
(W0611)
🪛 Ruff (0.11.9)
test_approval_basic.py
17-17: praisonaiagents.approval.require_approval imported but unused; consider using importlib.util.find_spec to test for availability
(F401)
18-18: praisonaiagents.approval.ApprovalDecision imported but unused; consider using importlib.util.find_spec to test for availability
(F401)
19-19: praisonaiagents.approval.console_approval_callback imported but unused; consider using importlib.util.find_spec to test for availability
(F401)
20-20: praisonaiagents.approval.request_approval imported but unused; consider using importlib.util.find_spec to test for availability
(F401)
21-21: praisonaiagents.approval.is_approval_required imported but unused; consider using importlib.util.find_spec to test for availability
(F401)
22-22: praisonaiagents.approval.get_risk_level imported but unused; consider using importlib.util.find_spec to test for availability
(F401)
23-23: praisonaiagents.approval.add_approval_requirement imported but unused; consider using importlib.util.find_spec to test for availability
(F401)
24-24: praisonaiagents.approval.remove_approval_requirement imported but unused; consider using importlib.util.find_spec to test for availability
(F401)
29-29: praisonaiagents.main.register_approval_callback imported but unused; consider using importlib.util.find_spec to test for availability
(F401)
29-29: praisonaiagents.main.approval_callback imported but unused; consider using importlib.util.find_spec to test for availability
(F401)
33-33: praisonaiagents.agent.Agent imported but unused; consider using importlib.util.find_spec to test for availability
(F401)
37-37: praisonaiagents.tools.shell_tools.ShellTools imported but unused; consider using importlib.util.find_spec to test for availability
(F401)
38-38: praisonaiagents.tools.python_tools.PythonTools imported but unused; consider using importlib.util.find_spec to test for availability
(F401)
39-39: praisonaiagents.tools.file_tools.FileTools imported but unused; consider using importlib.util.find_spec to test for availability
(F401)
58-58: Avoid equality comparisons to True; use if decision.approved: for truth checks
Replace with decision.approved
(E712)
79-79: Avoid equality comparisons to True; use if is_approval_required("test_function"): for truth checks
Replace with is_approval_required("test_function")
(E712)
84-84: Avoid equality comparisons to False; use if not is_approval_required("test_function"): for false checks
Replace with not is_approval_required("test_function")
(E712)
examples/python/general/human_approval_example.py
23-23: praisonaiagents.main.register_approval_callback imported but unused
Remove unused import: praisonaiagents.main.register_approval_callback
(F401)
39-39: f-string without any placeholders
Remove extraneous f prefix
(F541)
120-120: f-string without any placeholders
Remove extraneous f prefix
(F541)
src/praisonai-agents/praisonaiagents/approval.py
14-14: rich.text.Text imported but unused
Remove unused import: rich.text.Text
(F401)
88-88: f-string without any placeholders
Remove extraneous f prefix
(F541)
⏰ Context from checks skipped due to timeout of 90000ms (2)
- GitHub Check: quick-test
- GitHub Check: test-core (3.11)
🔇 Additional comments (15)
src/praisonai-agents/praisonaiagents/tools/python_tools.py (2)
18-18: Import statement looks good.The import of
require_approvalfrom the approval module is properly placed and follows the existing import structure.
40-40: Excellent security enhancement with appropriate risk level.Adding the
@require_approval(risk_level="critical")decorator to theexecute_codemethod is a crucial security improvement. Code execution is indeed a critical risk operation that should require explicit human approval before proceeding.src/praisonai-agents/praisonaiagents/tools/shell_tools.py (3)
16-16: Import statement is correctly placed.The import of
require_approvalfollows the proper import structure and integrates well with existing imports.
35-35: Critical security improvement for shell command execution.Adding the
@require_approval(risk_level="critical")decorator toexecute_commandis essential for security. Shell command execution poses significant risks and absolutely should require human approval.
151-151: Appropriate security measure for process termination.The
@require_approval(risk_level="critical")decorator onkill_processis well-justified. Process termination can have severe system impacts and requiring approval is a prudent security measure.src/praisonai-agents/praisonaiagents/main.py (1)
53-58: Exports are properly configured.The addition of approval-related exports to
__all__is correctly implemented and maintains the module's public API.src/praisonai-agents/praisonaiagents/tools/file_tools.py (5)
19-19: LGTM: Approval system import added correctly.The import statement properly brings in the
require_approvaldecorator from the approval module to enable human-in-the-loop approval for dangerous file operations.
44-46: LGTM: Write operation properly protected with approval.The
write_filemethod is correctly decorated with@require_approval(risk_level="high"), which is appropriate since writing files can overwrite existing content and potentially cause data loss. The decorator placement above the method definition follows Python conventions.🧰 Tools
🪛 Pylint (3.3.7)
[warning] 46-46: Redefining name 'content' from outer scope (line 235)
(W0621)
138-140: LGTM: Copy operation properly protected with approval.The
copy_filemethod is correctly decorated with@require_approval(risk_level="high"), which is appropriate since copying files can overwrite existing files at the destination. The risk level aligns with other file modification operations.
161-163: LGTM: Move operation properly protected with approval.The
move_filemethod is correctly decorated with@require_approval(risk_level="high"), which is appropriate since moving files can overwrite existing files and remove files from their original location. The risk level is consistent with other destructive file operations.
184-186: LGTM: Delete operation properly protected with approval.The
delete_filemethod is correctly decorated with@require_approval(risk_level="high"), which is appropriate since deleting files is irreversible and can cause data loss. The risk level matches other potentially destructive file operations.src/praisonai-agents/praisonaiagents/agent/agent.py (1)
19-21: LGTM: Approval callback import added correctly.The import of
approval_callbackfrom the main module enables access to the global approval callback configuration, which is necessary for the approval system integration.examples/python/general/human_approval_example.py (2)
19-29: LGTM! Well-organized imports.The imports are properly structured and include all necessary components for demonstrating the approval system.
🧰 Tools
🪛 Ruff (0.11.9)
23-23:
praisonaiagents.main.register_approval_callbackimported but unusedRemove unused import:
praisonaiagents.main.register_approval_callback(F401)
🪛 Pylint (3.3.7)
[convention] 25-25: Trailing whitespace
(C0303)
[error] 21-21: Unable to import 'praisonaiagents'
(E0401)
[error] 22-22: Unable to import 'praisonaiagents.tools'
(E0401)
[error] 23-23: Unable to import 'praisonaiagents.main'
(E0401)
[error] 24-29: Unable to import 'praisonaiagents.approval'
(E0401)
[warning] 23-23: Unused register_approval_callback imported from praisonaiagents.main
(W0611)
127-145: Good demonstration of dynamic approval configuration.This function effectively shows how to add and remove approval requirements at runtime, which is valuable for users who need to customize the approval system.
🧰 Tools
🪛 Pylint (3.3.7)
[convention] 129-129: Trailing whitespace
(C0303)
[convention] 132-132: Trailing whitespace
(C0303)
[convention] 136-136: Trailing whitespace
(C0303)
[convention] 140-140: Trailing whitespace
(C0303)
[error] 142-142: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 142-142: Import outside toplevel (praisonaiagents.approval.APPROVAL_REQUIRED_TOOLS, praisonaiagents.approval.TOOL_RISK_LEVELS)
(C0415)
src/praisonai-agents/praisonaiagents/approval.py (1)
42-68: Well-designed decorator pattern.The decorator effectively marks tools for approval while preserving their original behavior. The actual approval enforcement happens in the Agent class, which is a good separation of concerns.
🧰 Tools
🪛 Pylint (3.3.7)
[convention] 52-52: Trailing whitespace
(C0303)
[convention] 56-56: Trailing whitespace
(C0303)
[convention] 60-60: Trailing whitespace
(C0303)
[convention] 66-66: Trailing whitespace
(C0303)
[refactor] 62-65: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it
(R1705)
| def test_approval_decision(): | ||
| """Test the ApprovalDecision class.""" | ||
| try: | ||
| from praisonaiagents.approval import ApprovalDecision | ||
|
|
||
| # Test approved decision | ||
| decision = ApprovalDecision(approved=True, reason="Test approval") | ||
| assert decision.approved == True | ||
| assert decision.reason == "Test approval" | ||
| print("✅ ApprovalDecision class works correctly") | ||
|
|
||
| return True | ||
| except Exception as e: | ||
| print(f"❌ ApprovalDecision test failed: {e}") | ||
| return False | ||
|
|
There was a problem hiding this comment.
🛠️ Refactor suggestion
Fix boolean comparison and move imports to top level.
The test logic is correct but needs style improvements.
Apply these fixes:
def test_approval_decision():
"""Test the ApprovalDecision class."""
try:
- from praisonaiagents.approval import ApprovalDecision
-
# Test approved decision
decision = ApprovalDecision(approved=True, reason="Test approval")
- assert decision.approved == True
+ assert decision.approved
assert decision.reason == "Test approval"
print("✅ ApprovalDecision class works correctly")
-
return True
except Exception as e:
print(f"❌ ApprovalDecision test failed: {e}")
return FalseCommittable suggestion skipped: line range outside the PR's diff.
🧰 Tools
🪛 Ruff (0.11.9)
58-58: Avoid equality comparisons to True; use if decision.approved: for truth checks
Replace with decision.approved
(E712)
🪛 Pylint (3.3.7)
[convention] 55-55: Trailing whitespace
(C0303)
[convention] 61-61: Trailing whitespace
(C0303)
[warning] 63-63: Catching too general exception Exception
(W0718)
[error] 54-54: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 54-54: Import outside toplevel (praisonaiagents.approval.ApprovalDecision)
(C0415)
[convention] 58-58: Comparison 'decision.approved == True' should be 'decision.approved is True' if checking for the singleton value True, or 'decision.approved' if testing for truthiness
(C0121)
🤖 Prompt for AI Agents
In test_approval_basic.py around lines 51 to 66, the test function compares
booleans using '== True', which is unnecessary and should be simplified to
direct boolean checks. Also, move the import statement for ApprovalDecision to
the top of the file outside the test function to follow best practices. Update
the assertions to use direct boolean evaluation and relocate the import
accordingly.
| def test_approval_requirements(): | ||
| """Test approval requirement configuration.""" | ||
| try: | ||
| from praisonaiagents.approval import ( | ||
| add_approval_requirement, | ||
| remove_approval_requirement, | ||
| is_approval_required, | ||
| get_risk_level | ||
| ) | ||
|
|
||
| # Test adding requirement | ||
| add_approval_requirement("test_function", "high") | ||
| assert is_approval_required("test_function") == True | ||
| assert get_risk_level("test_function") == "high" | ||
|
|
||
| # Test removing requirement | ||
| remove_approval_requirement("test_function") | ||
| assert is_approval_required("test_function") == False | ||
| assert get_risk_level("test_function") is None | ||
|
|
||
| print("✅ Approval requirement configuration works correctly") | ||
| return True | ||
|
|
||
| except Exception as e: | ||
| print(f"❌ Approval requirements test failed: {e}") | ||
| return False | ||
|
|
There was a problem hiding this comment.
🛠️ Refactor suggestion
Fix boolean comparisons and improve code style.
The test logic is sound but needs boolean comparison fixes.
Apply these improvements:
def test_approval_requirements():
"""Test approval requirement configuration."""
try:
- from praisonaiagents.approval import (
- add_approval_requirement,
- remove_approval_requirement,
- is_approval_required,
- get_risk_level
- )
-
# Test adding requirement
add_approval_requirement("test_function", "high")
- assert is_approval_required("test_function") == True
+ assert is_approval_required("test_function")
assert get_risk_level("test_function") == "high"
-
# Test removing requirement
remove_approval_requirement("test_function")
- assert is_approval_required("test_function") == False
+ assert not is_approval_required("test_function")
assert get_risk_level("test_function") is None
-
print("✅ Approval requirement configuration works correctly")
return True
-
except Exception as e:
print(f"❌ Approval requirements test failed: {e}")
return FalseCommittable suggestion skipped: line range outside the PR's diff.
🧰 Tools
🪛 Ruff (0.11.9)
79-79: Avoid equality comparisons to True; use if is_approval_required("test_function"): for truth checks
Replace with is_approval_required("test_function")
(E712)
84-84: Avoid equality comparisons to False; use if not is_approval_required("test_function"): for false checks
Replace with not is_approval_required("test_function")
(E712)
🪛 Pylint (3.3.7)
[convention] 76-76: Trailing whitespace
(C0303)
[convention] 81-81: Trailing whitespace
(C0303)
[convention] 86-86: Trailing whitespace
(C0303)
[convention] 89-89: Trailing whitespace
(C0303)
[warning] 90-90: Catching too general exception Exception
(W0718)
[error] 70-75: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 70-75: Import outside toplevel (praisonaiagents.approval.add_approval_requirement, praisonaiagents.approval.remove_approval_requirement, praisonaiagents.approval.is_approval_required, praisonaiagents.approval.get_risk_level)
(C0415)
[convention] 79-79: Comparison 'is_approval_required('test_function') == True' should be 'is_approval_required('test_function') is True' if checking for the singleton value True, or 'is_approval_required('test_function')' if testing for truthiness
(C0121)
[convention] 84-84: Comparison 'is_approval_required('test_function') == False' should be 'is_approval_required('test_function') is False' if checking for the singleton value False, or 'not is_approval_required('test_function')' if testing for falsiness
(C0121)
🤖 Prompt for AI Agents
In test_approval_basic.py around lines 67 to 93, the boolean comparisons should
be fixed by using explicit True or False checks with 'is' instead of '=='.
Update the assertions to use 'is True' or 'is False' for clarity and
correctness. Also, improve code style by ensuring consistent spacing and
removing unnecessary comments or redundant code to make the test cleaner and
more readable.
| def test_imports(): | ||
| """Test that all the new approval imports work correctly.""" | ||
| try: | ||
| print("Testing approval module import...") | ||
| from praisonaiagents.approval import ( | ||
| require_approval, | ||
| ApprovalDecision, | ||
| console_approval_callback, | ||
| request_approval, | ||
| is_approval_required, | ||
| get_risk_level, | ||
| add_approval_requirement, | ||
| remove_approval_requirement | ||
| ) | ||
| print("✅ Approval module imports successful") | ||
|
|
||
| print("Testing main module approval functions...") | ||
| from praisonaiagents.main import register_approval_callback, approval_callback | ||
| print("✅ Main module approval functions imported successfully") | ||
|
|
||
| print("Testing agent modifications...") | ||
| from praisonaiagents.agent import Agent | ||
| print("✅ Agent class imports successfully") | ||
|
|
||
| print("Testing tool decorators...") | ||
| from praisonaiagents.tools.shell_tools import ShellTools | ||
| from praisonaiagents.tools.python_tools import PythonTools | ||
| from praisonaiagents.tools.file_tools import FileTools | ||
| print("✅ Tool classes with decorators imported successfully") | ||
|
|
||
| return True | ||
|
|
||
| except ImportError as e: | ||
| print(f"❌ Import error: {e}") | ||
| return False | ||
| except Exception as e: | ||
| print(f"❌ Unexpected error: {e}") | ||
| return False | ||
|
|
There was a problem hiding this comment.
🛠️ Refactor suggestion
Refactor import testing to follow best practices.
The test logic is sound but has several style issues that should be addressed.
Consider this refactored approach to fix the import issues and style problems:
+# Move imports to top level
+import sys
+import os
+
+# Add the src directory to Python path
+sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src', 'praisonai-agents'))
+
+# Import all modules at top level
+try:
+ from praisonaiagents.approval import (
+ require_approval,
+ ApprovalDecision,
+ console_approval_callback,
+ request_approval,
+ is_approval_required,
+ get_risk_level,
+ add_approval_requirement,
+ remove_approval_requirement
+ )
+ from praisonaiagents.main import register_approval_callback, approval_callback
+ from praisonaiagents.agent import Agent
+ from praisonaiagents.tools.shell_tools import ShellTools
+ from praisonaiagents.tools.python_tools import PythonTools
+ from praisonaiagents.tools.file_tools import FileTools
+ IMPORTS_AVAILABLE = True
+except ImportError as e:
+ IMPORTS_AVAILABLE = False
+ IMPORT_ERROR = e
def test_imports():
"""Test that all the new approval imports work correctly."""
- try:
- print("Testing approval module import...")
- from praisonaiagents.approval import (
- require_approval,
- ApprovalDecision,
- console_approval_callback,
- request_approval,
- is_approval_required,
- get_risk_level,
- add_approval_requirement,
- remove_approval_requirement
- )
- print("✅ Approval module imports successful")
-
- print("Testing main module approval functions...")
- from praisonaiagents.main import register_approval_callback, approval_callback
- print("✅ Main module approval functions imported successfully")
-
- print("Testing agent modifications...")
- from praisonaiagents.agent import Agent
- print("✅ Agent class imports successfully")
-
- print("Testing tool decorators...")
- from praisonaiagents.tools.shell_tools import ShellTools
- from praisonaiagents.tools.python_tools import PythonTools
- from praisonaiagents.tools.file_tools import FileTools
- print("✅ Tool classes with decorators imported successfully")
-
+ if IMPORTS_AVAILABLE:
+ print("✅ All approval system imports successful")
return True
-
- except ImportError as e:
- print(f"❌ Import error: {e}")
+ else:
+ print(f"❌ Import error: {IMPORT_ERROR}")
return False
- except Exception as e:
- print(f"❌ Unexpected error: {e}")
- return False📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| def test_imports(): | |
| """Test that all the new approval imports work correctly.""" | |
| try: | |
| print("Testing approval module import...") | |
| from praisonaiagents.approval import ( | |
| require_approval, | |
| ApprovalDecision, | |
| console_approval_callback, | |
| request_approval, | |
| is_approval_required, | |
| get_risk_level, | |
| add_approval_requirement, | |
| remove_approval_requirement | |
| ) | |
| print("✅ Approval module imports successful") | |
| print("Testing main module approval functions...") | |
| from praisonaiagents.main import register_approval_callback, approval_callback | |
| print("✅ Main module approval functions imported successfully") | |
| print("Testing agent modifications...") | |
| from praisonaiagents.agent import Agent | |
| print("✅ Agent class imports successfully") | |
| print("Testing tool decorators...") | |
| from praisonaiagents.tools.shell_tools import ShellTools | |
| from praisonaiagents.tools.python_tools import PythonTools | |
| from praisonaiagents.tools.file_tools import FileTools | |
| print("✅ Tool classes with decorators imported successfully") | |
| return True | |
| except ImportError as e: | |
| print(f"❌ Import error: {e}") | |
| return False | |
| except Exception as e: | |
| print(f"❌ Unexpected error: {e}") | |
| return False | |
| import sys | |
| import os | |
| # Add the src directory to Python path | |
| sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src', 'praisonai-agents')) | |
| # Import all modules at top level | |
| try: | |
| from praisonaiagents.approval import ( | |
| require_approval, | |
| ApprovalDecision, | |
| console_approval_callback, | |
| request_approval, | |
| is_approval_required, | |
| get_risk_level, | |
| add_approval_requirement, | |
| remove_approval_requirement | |
| ) | |
| from praisonaiagents.main import register_approval_callback, approval_callback | |
| from praisonaiagents.agent import Agent | |
| from praisonaiagents.tools.shell_tools import ShellTools | |
| from praisonaiagents.tools.python_tools import PythonTools | |
| from praisonaiagents.tools.file_tools import FileTools | |
| IMPORTS_AVAILABLE = True | |
| except ImportError as e: | |
| IMPORTS_AVAILABLE = False | |
| IMPORT_ERROR = e | |
| def test_imports(): | |
| """Test that all the new approval imports work correctly.""" | |
| if IMPORTS_AVAILABLE: | |
| print("✅ All approval system imports successful") | |
| return True | |
| else: | |
| print(f"❌ Import error: {IMPORT_ERROR}") | |
| return False |
🧰 Tools
🪛 Ruff (0.11.9)
17-17: praisonaiagents.approval.require_approval imported but unused; consider using importlib.util.find_spec to test for availability
(F401)
18-18: praisonaiagents.approval.ApprovalDecision imported but unused; consider using importlib.util.find_spec to test for availability
(F401)
19-19: praisonaiagents.approval.console_approval_callback imported but unused; consider using importlib.util.find_spec to test for availability
(F401)
20-20: praisonaiagents.approval.request_approval imported but unused; consider using importlib.util.find_spec to test for availability
(F401)
21-21: praisonaiagents.approval.is_approval_required imported but unused; consider using importlib.util.find_spec to test for availability
(F401)
22-22: praisonaiagents.approval.get_risk_level imported but unused; consider using importlib.util.find_spec to test for availability
(F401)
23-23: praisonaiagents.approval.add_approval_requirement imported but unused; consider using importlib.util.find_spec to test for availability
(F401)
24-24: praisonaiagents.approval.remove_approval_requirement imported but unused; consider using importlib.util.find_spec to test for availability
(F401)
29-29: praisonaiagents.main.register_approval_callback imported but unused; consider using importlib.util.find_spec to test for availability
(F401)
29-29: praisonaiagents.main.approval_callback imported but unused; consider using importlib.util.find_spec to test for availability
(F401)
33-33: praisonaiagents.agent.Agent imported but unused; consider using importlib.util.find_spec to test for availability
(F401)
37-37: praisonaiagents.tools.shell_tools.ShellTools imported but unused; consider using importlib.util.find_spec to test for availability
(F401)
38-38: praisonaiagents.tools.python_tools.PythonTools imported but unused; consider using importlib.util.find_spec to test for availability
(F401)
39-39: praisonaiagents.tools.file_tools.FileTools imported but unused; consider using importlib.util.find_spec to test for availability
(F401)
🪛 Pylint (3.3.7)
[convention] 27-27: Trailing whitespace
(C0303)
[convention] 31-31: Trailing whitespace
(C0303)
[convention] 35-35: Trailing whitespace
(C0303)
[convention] 38-38: Trailing whitespace
(C0303)
[convention] 41-41: Trailing whitespace
(C0303)
[convention] 43-43: Trailing whitespace
(C0303)
[warning] 47-47: Catching too general exception Exception
(W0718)
[convention] 16-25: Import outside toplevel (praisonaiagents.approval.require_approval, praisonaiagents.approval.ApprovalDecision, praisonaiagents.approval.console_approval_callback, praisonaiagents.approval.request_approval, praisonaiagents.approval.is_approval_required, praisonaiagents.approval.get_risk_level, praisonaiagents.approval.add_approval_requirement, praisonaiagents.approval.remove_approval_requirement)
(C0415)
[convention] 29-29: Import outside toplevel (praisonaiagents.main.register_approval_callback, praisonaiagents.main.approval_callback)
(C0415)
[convention] 33-33: Import outside toplevel (praisonaiagents.agent.Agent)
(C0415)
[convention] 37-37: Import outside toplevel (praisonaiagents.tools.shell_tools.ShellTools)
(C0415)
[convention] 38-38: Import outside toplevel (praisonaiagents.tools.python_tools.PythonTools)
(C0415)
[convention] 39-39: Import outside toplevel (praisonaiagents.tools.file_tools.FileTools)
(C0415)
[warning] 16-25: Unused require_approval imported from praisonaiagents.approval
(W0611)
[warning] 16-25: Unused ApprovalDecision imported from praisonaiagents.approval
(W0611)
[warning] 16-25: Unused console_approval_callback imported from praisonaiagents.approval
(W0611)
[warning] 16-25: Unused request_approval imported from praisonaiagents.approval
(W0611)
[warning] 16-25: Unused is_approval_required imported from praisonaiagents.approval
(W0611)
[warning] 16-25: Unused get_risk_level imported from praisonaiagents.approval
(W0611)
[warning] 16-25: Unused add_approval_requirement imported from praisonaiagents.approval
(W0611)
[warning] 16-25: Unused remove_approval_requirement imported from praisonaiagents.approval
(W0611)
[warning] 29-29: Unused register_approval_callback imported from praisonaiagents.main
(W0611)
[warning] 29-29: Unused approval_callback imported from praisonaiagents.main
(W0611)
[warning] 33-33: Unused Agent imported from praisonaiagents.agent
(W0611)
[warning] 37-37: Unused ShellTools imported from praisonaiagents.tools.shell_tools
(W0611)
[warning] 38-38: Unused PythonTools imported from praisonaiagents.tools.python_tools
(W0611)
[warning] 39-39: Unused FileTools imported from praisonaiagents.tools.file_tools
(W0611)
🤖 Prompt for AI Agents
In test_approval_basic.py around lines 12 to 50, the import testing function
uses print statements and broad exception handling which is not ideal for test
clarity and style. Refactor the test to use assert statements instead of prints,
remove the broad Exception catch, and only catch ImportError to fail the test if
imports fail. This will make the test cleaner, more idiomatic, and easier to
maintain.
| import logging | ||
| import asyncio | ||
| from typing import Dict, Set, Optional, Callable, Any, Literal | ||
| from functools import wraps | ||
| from rich.console import Console | ||
| from rich.panel import Panel | ||
| from rich.text import Text | ||
| from rich.prompt import Confirm | ||
|
|
There was a problem hiding this comment.
Remove unused import.
Apply this diff to remove the unused import:
from rich.console import Console
from rich.panel import Panel
-from rich.text import Text
from rich.prompt import Confirm📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| import logging | |
| import asyncio | |
| from typing import Dict, Set, Optional, Callable, Any, Literal | |
| from functools import wraps | |
| from rich.console import Console | |
| from rich.panel import Panel | |
| from rich.text import Text | |
| from rich.prompt import Confirm | |
| import logging | |
| import asyncio | |
| from typing import Dict, Set, Optional, Callable, Any, Literal | |
| from functools import wraps | |
| from rich.console import Console | |
| from rich.panel import Panel | |
| from rich.prompt import Confirm |
🧰 Tools
🪛 Ruff (0.11.9)
14-14: rich.text.Text imported but unused
Remove unused import: rich.text.Text
(F401)
🪛 Pylint (3.3.7)
[warning] 14-14: Unused Text imported from rich.text
(W0611)
🤖 Prompt for AI Agents
In src/praisonai-agents/praisonaiagents/approval.py between lines 8 and 16, the
import 'wraps' from functools is not used anywhere in the code. Remove the line
importing 'wraps' to clean up unused imports and improve code clarity.
This commit deletes the outdated test_approval_basic.py file, which contained basic tests for the human approval system. The tests are no longer necessary as the functionality has been integrated into other components. Files modified: - Deleted test_approval_basic.py
This commit modifies the import paths in the test files for the approval agent to ensure they correctly reference the local development path. The changes streamline the path structure for better integration with the existing codebase. Files modified: - Updated import paths in test_approval_agent_integration.py - Updated import paths in test_approval_basic.py - Updated import paths in test_approval_interactive.py
This commit introduces a context-aware auto-approval mechanism for the approval system, allowing non-interactive execution in CI environments. It modifies the test files to include a skip condition for interactive approvals and updates the approval callback logic to support automatic approvals when user input is not required. Files modified: - Updated test_approval_agent_integration.py to include auto-approval logic - Updated test_approval_basic.py to include skip condition for interactive tests - Updated test_approval_interactive.py to include auto-approval logic - Enhanced approval.py with context management for approval tracking - Modified agent.py to prevent double approval in context This change improves the usability of the approval system in automated workflows while maintaining security.
There was a problem hiding this comment.
Actionable comments posted: 6
♻️ Duplicate comments (1)
src/praisonai-agents/praisonaiagents/approval.py (1)
15-15: Remove unused import.from rich.console import Console from rich.panel import Panel -from rich.text import Text from rich.prompt import Confirm🧰 Tools
🪛 Ruff (0.11.9)
15-15:
rich.text.Textimported but unusedRemove unused import:
rich.text.Text(F401)
🪛 Pylint (3.3.7)
[warning] 15-15: Unused Text imported from rich.text
(W0611)
🧹 Nitpick comments (16)
src/praisonai/tests/unit/test_decorator_enforcement.py (1)
35-35: Remove unused variable assignment.The
resultvariable is assigned but never used, which creates unnecessary code.- result = shell_tools.execute_command('echo "This should be denied"') + shell_tools.execute_command('echo "This should be denied"')🧰 Tools
🪛 Ruff (0.11.9)
35-35: Local variable
resultis assigned to but never usedRemove assignment to unused variable
result(F841)
🪛 Pylint (3.3.7)
[warning] 35-35: Unused variable 'result'
(W0612)
src/praisonai/tests/unit/test_approval_basic.py (1)
44-44: Remove unused import.The
TOOL_RISK_LEVELSimport is not used in this function.from praisonaiagents.approval import ( add_approval_requirement, remove_approval_requirement, is_approval_required, get_risk_level, - APPROVAL_REQUIRED_TOOLS, - TOOL_RISK_LEVELS + APPROVAL_REQUIRED_TOOLS )🧰 Tools
🪛 Ruff (0.11.9)
44-44:
praisonaiagents.approval.TOOL_RISK_LEVELSimported but unusedRemove unused import:
praisonaiagents.approval.TOOL_RISK_LEVELS(F401)
src/praisonai-agents/praisonaiagents/agent/agent.py (1)
1451-1465: Fix trailing whitespace and improve logging in async approval integrationThe async approval integration follows the same pattern as the sync version, which is good for consistency.
Apply this diff to fix formatting issues:
- + # Check if approval is required for this tool from ..approval import is_approval_required, request_approval if is_approval_required(function_name): decision = await request_approval(function_name, arguments) if not decision.approved: error_msg = f"Tool execution denied: {decision.reason}" logging.warning(error_msg) return {"error": error_msg, "approval_denied": True} - + # Use modified arguments if provided if decision.modified_args: arguments = decision.modified_args - logging.info(f"Using modified arguments: {arguments}") - + logging.info("Using modified arguments: %s", arguments) +Issues addressed:
- Removed trailing whitespace (Pylint C0303)
- Applied lazy logging formatting for consistency (Pylint W1203)
🧰 Tools
🪛 Pylint (3.3.7)
[convention] 1451-1451: Trailing whitespace
(C0303)
[convention] 1460-1460: Trailing whitespace
(C0303)
[convention] 1465-1465: Trailing whitespace
(C0303)
[convention] 1453-1453: Import outside toplevel (approval.is_approval_required, approval.request_approval)
(C0415)
[warning] 1464-1464: Use lazy % formatting in logging functions
(W1203)
src/praisonai/tests/unit/test_approval_agent_integration.py (1)
1-318: Comprehensive test suite with formatting issues to fixExcellent test coverage for the approval system integration! The test scenarios cover interactive approval, auto-approval, auto-denial, and multiple tool types (shell, Python, file operations). The structure is well-organized with a user-friendly CLI interface.
However, there are several formatting and import issues to clean up:
Issues to fix:
- Remove unused
asyncioimport (line 11)- Extensive trailing whitespace throughout the file
- Missing final newline
- Unused parameters in callback functions
Apply this diff for key fixes:
import sys import os -import asyncio import pytest# Create auto-approval callback - def auto_approve_callback(function_name, arguments, risk_level): + def auto_approve_callback(function_name, _arguments, risk_level): print(f"🤖 Auto-approving {function_name} (risk: {risk_level})") return ApprovalDecision(approved=True, reason="Auto-approved for testing")# Create auto-denial callback - def auto_deny_callback(function_name, arguments, risk_level): + def auto_deny_callback(function_name, _arguments, risk_level): print(f"🚫 Auto-denying {function_name} (risk: {risk_level})") return ApprovalDecision(approved=False, reason="Auto-denied for testing")# Create auto-approval for this test - def auto_approve_callback(function_name, arguments, risk_level): + def auto_approve_callback(function_name, _arguments, risk_level): print(f"🤖 Auto-approving {function_name} (risk: {risk_level})") return ApprovalDecision(approved=True, reason="Auto-approved for testing")# Create auto-approval for this test - def auto_approve_callback(function_name, arguments, risk_level): + def auto_approve_callback(function_name, _arguments, risk_level): print(f"🤖 Auto-approving {function_name} (risk: {risk_level})") return ApprovalDecision(approved=True, reason="Auto-approved for testing")Additional cleanup needed:
- Remove trailing whitespace from all lines (too many to list individually)
- Add final newline at end of file
Note: The import errors flagged by Pylint are expected in test files and can be ignored since they're testing the actual modules that exist in the codebase.
🧰 Tools
🪛 Ruff (0.11.9)
11-11:
asyncioimported but unusedRemove unused import:
asyncio(F401)
🪛 Pylint (3.3.7)
[convention] 23-23: Trailing whitespace
(C0303)
[convention] 27-27: Line too long (111/100)
(C0301)
[convention] 28-28: Trailing whitespace
(C0303)
[convention] 37-37: Trailing whitespace
(C0303)
[convention] 46-46: Trailing whitespace
(C0303)
[convention] 49-49: Trailing whitespace
(C0303)
[convention] 51-51: Line too long (112/100)
(C0301)
[convention] 52-52: Trailing whitespace
(C0303)
[convention] 59-59: Trailing whitespace
(C0303)
[convention] 61-61: Trailing whitespace
(C0303)
[convention] 70-70: Trailing whitespace
(C0303)
[convention] 75-75: Trailing whitespace
(C0303)
[convention] 80-80: Trailing whitespace
(C0303)
[convention] 82-82: Trailing whitespace
(C0303)
[convention] 91-91: Trailing whitespace
(C0303)
[convention] 93-93: Line too long (109/100)
(C0301)
[convention] 94-94: Trailing whitespace
(C0303)
[convention] 99-99: Trailing whitespace
(C0303)
[convention] 101-101: Trailing whitespace
(C0303)
[convention] 110-110: Trailing whitespace
(C0303)
[convention] 115-115: Trailing whitespace
(C0303)
[convention] 120-120: Trailing whitespace
(C0303)
[convention] 122-122: Trailing whitespace
(C0303)
[convention] 131-131: Trailing whitespace
(C0303)
[convention] 134-134: Trailing whitespace
(C0303)
[convention] 141-141: Trailing whitespace
(C0303)
[convention] 143-143: Trailing whitespace
(C0303)
[convention] 152-152: Trailing whitespace
(C0303)
[convention] 157-157: Trailing whitespace
(C0303)
[convention] 162-162: Trailing whitespace
(C0303)
[convention] 164-164: Trailing whitespace
(C0303)
[convention] 173-173: Trailing whitespace
(C0303)
[convention] 179-179: Trailing whitespace
(C0303)
[convention] 182-182: Trailing whitespace
(C0303)
[convention] 187-187: Trailing whitespace
(C0303)
[convention] 189-189: Trailing whitespace
(C0303)
[convention] 198-198: Trailing whitespace
(C0303)
[convention] 203-203: Trailing whitespace
(C0303)
[convention] 208-208: Trailing whitespace
(C0303)
[convention] 210-210: Trailing whitespace
(C0303)
[convention] 219-219: Trailing whitespace
(C0303)
[convention] 226-226: Trailing whitespace
(C0303)
[convention] 229-229: Trailing whitespace
(C0303)
[convention] 233-233: Trailing whitespace
(C0303)
[convention] 240-240: Trailing whitespace
(C0303)
[convention] 242-242: Trailing whitespace
(C0303)
[convention] 253-253: Trailing whitespace
(C0303)
[convention] 263-263: Trailing whitespace
(C0303)
[convention] 266-266: Trailing whitespace
(C0303)
[convention] 279-279: Trailing whitespace
(C0303)
[convention] 288-288: Trailing whitespace
(C0303)
[convention] 295-295: Trailing whitespace
(C0303)
[convention] 303-303: Trailing whitespace
(C0303)
[convention] 311-311: Trailing whitespace
(C0303)
[convention] 318-318: Final newline missing
(C0304)
[warning] 62-62: Catching too general exception Exception
(W0718)
[error] 25-25: Unable to import 'praisonaiagents'
(E0401)
[convention] 25-25: Import outside toplevel (praisonaiagents.Agent)
(C0415)
[error] 26-26: Unable to import 'praisonaiagents.tools.shell_tools'
(E0401)
[convention] 26-26: Import outside toplevel (praisonaiagents.tools.shell_tools.ShellTools)
(C0415)
[error] 27-27: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 27-27: Import outside toplevel (praisonaiagents.approval.set_approval_callback, praisonaiagents.approval.console_approval_callback, praisonaiagents.approval.ApprovalDecision)
(C0415)
[warning] 34-34: Unused argument 'function_name'
(W0613)
[warning] 34-34: Unused argument 'arguments'
(W0613)
[warning] 34-34: Unused argument 'risk_level'
(W0613)
[warning] 102-102: Catching too general exception Exception
(W0718)
[error] 72-72: Unable to import 'praisonaiagents'
(E0401)
[convention] 72-72: Import outside toplevel (praisonaiagents.Agent)
(C0415)
[error] 73-73: Unable to import 'praisonaiagents.tools.shell_tools'
(E0401)
[convention] 73-73: Import outside toplevel (praisonaiagents.tools.shell_tools.ShellTools)
(C0415)
[error] 74-74: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 74-74: Import outside toplevel (praisonaiagents.approval.set_approval_callback, praisonaiagents.approval.ApprovalDecision)
(C0415)
[warning] 77-77: Unused argument 'arguments'
(W0613)
[warning] 144-144: Catching too general exception Exception
(W0718)
[error] 112-112: Unable to import 'praisonaiagents'
(E0401)
[convention] 112-112: Import outside toplevel (praisonaiagents.Agent)
(C0415)
[error] 113-113: Unable to import 'praisonaiagents.tools.shell_tools'
(E0401)
[convention] 113-113: Import outside toplevel (praisonaiagents.tools.shell_tools.ShellTools)
(C0415)
[error] 114-114: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 114-114: Import outside toplevel (praisonaiagents.approval.set_approval_callback, praisonaiagents.approval.ApprovalDecision)
(C0415)
[warning] 117-117: Unused argument 'arguments'
(W0613)
[warning] 190-190: Catching too general exception Exception
(W0718)
[error] 154-154: Unable to import 'praisonaiagents'
(E0401)
[convention] 154-154: Import outside toplevel (praisonaiagents.Agent)
(C0415)
[error] 155-155: Unable to import 'praisonaiagents.tools.python_tools'
(E0401)
[convention] 155-155: Import outside toplevel (praisonaiagents.tools.python_tools.PythonTools)
(C0415)
[error] 156-156: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 156-156: Import outside toplevel (praisonaiagents.approval.set_approval_callback, praisonaiagents.approval.ApprovalDecision)
(C0415)
[warning] 159-159: Unused argument 'arguments'
(W0613)
[warning] 243-243: Catching too general exception Exception
(W0718)
[error] 200-200: Unable to import 'praisonaiagents'
(E0401)
[convention] 200-200: Import outside toplevel (praisonaiagents.Agent)
(C0415)
[error] 201-201: Unable to import 'praisonaiagents.tools.file_tools'
(E0401)
[convention] 201-201: Import outside toplevel (praisonaiagents.tools.file_tools.FileTools)
(C0415)
[error] 202-202: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 202-202: Import outside toplevel (praisonaiagents.approval.set_approval_callback, praisonaiagents.approval.ApprovalDecision)
(C0415)
[warning] 205-205: Unused argument 'arguments'
(W0613)
[warning] 314-314: Catching too general exception Exception
(W0718)
[refactor] 247-247: Too many statements (57/50)
(R0915)
[warning] 11-11: Unused import asyncio
(W0611)
examples/python/general/human_approval_example.py (8)
45-45: Remove unnecessary f-string prefix.The string doesn't contain any placeholders.
- print(f"\n🔒 CUSTOM APPROVAL REQUIRED") + print("\n🔒 CUSTOM APPROVAL REQUIRED")🧰 Tools
🪛 Ruff (0.11.9)
45-45: f-string without any placeholders
Remove extraneous
fprefix(F541)
🪛 Pylint (3.3.7)
[warning] 45-45: Using an f-string that does not have any interpolated variables
(W1309)
126-126: Remove unnecessary f-string prefix.The string doesn't contain any placeholders.
- print(f"\n✅ Process completed successfully!") + print("\n✅ Process completed successfully!")🧰 Tools
🪛 Ruff (0.11.9)
126-126: f-string without any placeholders
Remove extraneous
fprefix(F541)
🪛 Pylint (3.3.7)
[warning] 126-126: Using an f-string that does not have any interpolated variables
(W1309)
1-210: Clean up trailing whitespace throughout the file.Static analysis detected trailing whitespace on multiple lines. Consider configuring your editor to automatically remove trailing whitespace on save.
🧰 Tools
🪛 Ruff (0.11.9)
29-29:
praisonaiagents.main.register_approval_callbackimported but unusedRemove unused import:
praisonaiagents.main.register_approval_callback(F401)
45-45: f-string without any placeholders
Remove extraneous
fprefix(F541)
126-126: f-string without any placeholders
Remove extraneous
fprefix(F541)
🪛 Pylint (3.3.7)
[convention] 25-25: Line too long (101/100)
(C0301)
[convention] 31-31: Trailing whitespace
(C0303)
[convention] 40-40: Line too long (103/100)
(C0301)
[convention] 49-49: Trailing whitespace
(C0303)
[convention] 54-54: Trailing whitespace
(C0303)
[convention] 57-57: Trailing whitespace
(C0303)
[convention] 62-62: Trailing whitespace
(C0303)
[convention] 68-68: Trailing whitespace
(C0303)
[convention] 74-74: Trailing whitespace
(C0303)
[convention] 79-79: Trailing whitespace
(C0303)
[convention] 88-88: Trailing whitespace
(C0303)
[convention] 112-112: Trailing whitespace
(C0303)
[convention] 119-119: Trailing whitespace
(C0303)
[convention] 123-123: Trailing whitespace
(C0303)
[convention] 135-135: Trailing whitespace
(C0303)
[convention] 138-138: Trailing whitespace
(C0303)
[convention] 142-142: Trailing whitespace
(C0303)
[convention] 146-146: Trailing whitespace
(C0303)
[convention] 154-154: Trailing whitespace
(C0303)
[convention] 157-157: Trailing whitespace
(C0303)
[convention] 161-161: Trailing whitespace
(C0303)
[convention] 166-166: Trailing whitespace
(C0303)
[convention] 173-173: Trailing whitespace
(C0303)
[convention] 179-179: Trailing whitespace
(C0303)
[convention] 188-188: Trailing whitespace
(C0303)
[convention] 191-191: Trailing whitespace
(C0303)
[convention] 194-194: Trailing whitespace
(C0303)
[convention] 203-203: Trailing whitespace
(C0303)
[convention] 210-210: Final newline missing
(C0304)
[error] 27-27: Unable to import 'praisonaiagents'
(E0401)
[convention] 27-27: Import "from praisonaiagents import Agent, Task, PraisonAIAgents" should be placed at the top of the module
(C0413)
[error] 28-28: Unable to import 'praisonaiagents.tools'
(E0401)
[convention] 28-28: Import "from praisonaiagents.tools import python_tools, file_tools, shell_tools" should be placed at the top of the module
(C0413)
[error] 29-29: Unable to import 'praisonaiagents.main'
(E0401)
[convention] 29-29: Import "from praisonaiagents.main import register_approval_callback" should be placed at the top of the module
(C0413)
[error] 30-35: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 30-35: Import "from praisonaiagents.approval import console_approval_callback, ApprovalDecision, add_approval_requirement, remove_approval_requirement" should be placed at the top of the module
(C0413)
[warning] 45-45: Using an f-string that does not have any interpolated variables
(W1309)
[warning] 130-130: Catching too general exception Exception
(W0718)
[warning] 126-126: Using an f-string that does not have any interpolated variables
(W1309)
[error] 148-148: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 148-148: Import outside toplevel (praisonaiagents.approval.APPROVAL_REQUIRED_TOOLS, praisonaiagents.approval.TOOL_RISK_LEVELS)
(C0415)
[warning] 183-183: Catching too general exception Exception
(W0718)
[warning] 29-29: Unused register_approval_callback imported from praisonaiagents.main
(W0611)
24-35: Fix import organization and remove unused import.The imports have several issues that should be addressed:
- The
register_approval_callbackimport is unused (as flagged by static analysis)- Imports should be placed after the path modification for consistency
-from praisonaiagents.main import register_approval_callback from praisonaiagents.approval import ( - console_approval_callback, + console_approval_callback, ApprovalDecision, add_approval_requirement, remove_approval_requirement )Also consider moving all
praisonaiagentsimports after thesys.path.appendline for clarity.🧰 Tools
🪛 Ruff (0.11.9)
29-29:
praisonaiagents.main.register_approval_callbackimported but unusedRemove unused import:
praisonaiagents.main.register_approval_callback(F401)
🪛 Pylint (3.3.7)
[convention] 25-25: Line too long (101/100)
(C0301)
[convention] 31-31: Trailing whitespace
(C0303)
[error] 27-27: Unable to import 'praisonaiagents'
(E0401)
[convention] 27-27: Import "from praisonaiagents import Agent, Task, PraisonAIAgents" should be placed at the top of the module
(C0413)
[error] 28-28: Unable to import 'praisonaiagents.tools'
(E0401)
[convention] 28-28: Import "from praisonaiagents.tools import python_tools, file_tools, shell_tools" should be placed at the top of the module
(C0413)
[error] 29-29: Unable to import 'praisonaiagents.main'
(E0401)
[convention] 29-29: Import "from praisonaiagents.main import register_approval_callback" should be placed at the top of the module
(C0413)
[error] 30-35: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 30-35: Import "from praisonaiagents.approval import console_approval_callback, ApprovalDecision, add_approval_requirement, remove_approval_requirement" should be placed at the top of the module
(C0413)
[warning] 29-29: Unused register_approval_callback imported from praisonaiagents.main
(W0611)
45-45: Remove unnecessary f-string prefixes.Two f-strings don't contain any placeholders and should use regular strings for better performance and clarity.
- print(f"\n🔒 CUSTOM APPROVAL REQUIRED") + print("\n🔒 CUSTOM APPROVAL REQUIRED")- print(f"\n✅ Process completed successfully!") + print("\n✅ Process completed successfully!")Also applies to: 126-126
🧰 Tools
🪛 Ruff (0.11.9)
45-45: f-string without any placeholders
Remove extraneous
fprefix(F541)
🪛 Pylint (3.3.7)
[warning] 45-45: Using an f-string that does not have any interpolated variables
(W1309)
76-78: Consider demonstrating the custom approval callback.The custom approval callback is defined but commented out. Consider either:
- Uncommenting it to show its usage in the demo, or
- Adding a separate demo section that specifically showcases custom callbacks
This would make the example more comprehensive by actually demonstrating the custom approval logic in action.
148-148: Consider moving imports to module level.The import inside the function should be moved to the top of the file for better organization and to avoid import-time side effects.
+from praisonaiagents.approval import APPROVAL_REQUIRED_TOOLS, TOOL_RISK_LEVELS def demo_manual_approval_configuration(): """Demonstrate how to manually configure approval requirements.""" # ... existing code ... - # Show current approval requirements - from praisonaiagents.approval import APPROVAL_REQUIRED_TOOLS, TOOL_RISK_LEVELS print(f"\nCurrent approval-required tools: {list(APPROVAL_REQUIRED_TOOLS)}")🧰 Tools
🪛 Pylint (3.3.7)
[error] 148-148: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 148-148: Import outside toplevel (praisonaiagents.approval.APPROVAL_REQUIRED_TOOLS, praisonaiagents.approval.TOOL_RISK_LEVELS)
(C0415)
1-210: Address formatting issues flagged by static analysis.The file has several formatting issues that should be cleaned up:
- Multiple trailing whitespace occurrences
- Missing final newline
- Some lines exceed 100 characters
Consider running a formatter like
blackor manually cleaning up the trailing whitespace and adding a final newline to improve code quality.🧰 Tools
🪛 Ruff (0.11.9)
29-29:
praisonaiagents.main.register_approval_callbackimported but unusedRemove unused import:
praisonaiagents.main.register_approval_callback(F401)
45-45: f-string without any placeholders
Remove extraneous
fprefix(F541)
126-126: f-string without any placeholders
Remove extraneous
fprefix(F541)
🪛 Pylint (3.3.7)
[convention] 25-25: Line too long (101/100)
(C0301)
[convention] 31-31: Trailing whitespace
(C0303)
[convention] 40-40: Line too long (103/100)
(C0301)
[convention] 49-49: Trailing whitespace
(C0303)
[convention] 54-54: Trailing whitespace
(C0303)
[convention] 57-57: Trailing whitespace
(C0303)
[convention] 62-62: Trailing whitespace
(C0303)
[convention] 68-68: Trailing whitespace
(C0303)
[convention] 74-74: Trailing whitespace
(C0303)
[convention] 79-79: Trailing whitespace
(C0303)
[convention] 88-88: Trailing whitespace
(C0303)
[convention] 112-112: Trailing whitespace
(C0303)
[convention] 119-119: Trailing whitespace
(C0303)
[convention] 123-123: Trailing whitespace
(C0303)
[convention] 135-135: Trailing whitespace
(C0303)
[convention] 138-138: Trailing whitespace
(C0303)
[convention] 142-142: Trailing whitespace
(C0303)
[convention] 146-146: Trailing whitespace
(C0303)
[convention] 154-154: Trailing whitespace
(C0303)
[convention] 157-157: Trailing whitespace
(C0303)
[convention] 161-161: Trailing whitespace
(C0303)
[convention] 166-166: Trailing whitespace
(C0303)
[convention] 173-173: Trailing whitespace
(C0303)
[convention] 179-179: Trailing whitespace
(C0303)
[convention] 188-188: Trailing whitespace
(C0303)
[convention] 191-191: Trailing whitespace
(C0303)
[convention] 194-194: Trailing whitespace
(C0303)
[convention] 203-203: Trailing whitespace
(C0303)
[convention] 210-210: Final newline missing
(C0304)
[error] 27-27: Unable to import 'praisonaiagents'
(E0401)
[convention] 27-27: Import "from praisonaiagents import Agent, Task, PraisonAIAgents" should be placed at the top of the module
(C0413)
[error] 28-28: Unable to import 'praisonaiagents.tools'
(E0401)
[convention] 28-28: Import "from praisonaiagents.tools import python_tools, file_tools, shell_tools" should be placed at the top of the module
(C0413)
[error] 29-29: Unable to import 'praisonaiagents.main'
(E0401)
[convention] 29-29: Import "from praisonaiagents.main import register_approval_callback" should be placed at the top of the module
(C0413)
[error] 30-35: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 30-35: Import "from praisonaiagents.approval import console_approval_callback, ApprovalDecision, add_approval_requirement, remove_approval_requirement" should be placed at the top of the module
(C0413)
[warning] 45-45: Using an f-string that does not have any interpolated variables
(W1309)
[warning] 130-130: Catching too general exception Exception
(W0718)
[warning] 126-126: Using an f-string that does not have any interpolated variables
(W1309)
[error] 148-148: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 148-148: Import outside toplevel (praisonaiagents.approval.APPROVAL_REQUIRED_TOOLS, praisonaiagents.approval.TOOL_RISK_LEVELS)
(C0415)
[warning] 183-183: Catching too general exception Exception
(W0718)
[warning] 29-29: Unused register_approval_callback imported from praisonaiagents.main
(W0611)
src/praisonai/tests/unit/test_approval_interactive.py (1)
287-287: Add missing final newline.Files should end with a newline character.
if __name__ == "__main__": - main() + main() +🧰 Tools
🪛 Pylint (3.3.7)
[convention] 287-287: Final newline missing
(C0304)
src/praisonai-agents/praisonaiagents/approval.py (3)
29-29: Avoid mutable default for ContextVar.While it works in this case, using mutable defaults is generally discouraged. Consider using None as default and creating the set when needed.
-_approved_context: ContextVar[Set[str]] = ContextVar('approved_context', default=set()) +_approved_context: ContextVar[Optional[Set[str]]] = ContextVar('approved_context', default=None)Then update the helper functions:
def mark_approved(tool_name: str): """Mark a tool as approved in the current context.""" approved = _approved_context.get() if approved is None: approved = set() approved.add(tool_name) _approved_context.set(approved) def is_already_approved(tool_name: str) -> bool: """Check if a tool is already approved in the current context.""" approved = _approved_context.get() return approved is not None and tool_name in approved🧰 Tools
🪛 Ruff (0.11.9)
29-29: Do not use mutable data structures for
ContextVardefaults(B039)
147-147: Remove unnecessary f-string prefix.The string doesn't contain any placeholders.
- tool_info += f"[bold]Arguments:[/]\n" + tool_info += "[bold]Arguments:[/]\n"🧰 Tools
🪛 Ruff (0.11.9)
147-147: f-string without any placeholders
Remove extraneous
fprefix(F541)
🪛 Pylint (3.3.7)
[warning] 147-147: Using an f-string that does not have any interpolated variables
(W1309)
263-263: Add missing final newline.Files should end with a newline character.
# Initialize with defaults -configure_default_approvals() +configure_default_approvals() +🧰 Tools
🪛 Pylint (3.3.7)
[convention] 263-263: Final newline missing
(C0304)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
examples/python/general/human_approval_example.py(1 hunks)src/praisonai-agents/praisonaiagents/agent/agent.py(3 hunks)src/praisonai-agents/praisonaiagents/approval.py(1 hunks)src/praisonai/tests/unit/test_approval_agent_integration.py(1 hunks)src/praisonai/tests/unit/test_approval_basic.py(1 hunks)src/praisonai/tests/unit/test_approval_interactive.py(1 hunks)src/praisonai/tests/unit/test_decorator_enforcement.py(1 hunks)src/praisonai/tests/unit/test_decorator_simple.py(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
src/praisonai-agents/praisonaiagents/approval.py (3)
src/praisonai-agents/praisonaiagents/agent/agent.py (1)
run(1439-1441)src/praisonai-ts/src/utils/pretty-logger.ts (1)
warning(120-136)src/praisonai-agents/praisonaiagents/mcp/mcp_sse.py (1)
get_event_loop(22-28)
src/praisonai-agents/praisonaiagents/agent/agent.py (1)
src/praisonai-agents/praisonaiagents/approval.py (6)
is_approval_required(254-256)console_approval_callback(128-182)get_risk_level(258-260)mark_approved(46-50)ApprovalDecision(31-36)request_approval(184-216)
🪛 Ruff (0.11.9)
src/praisonai/tests/unit/test_decorator_enforcement.py
35-35: Local variable result is assigned to but never used
Remove assignment to unused variable result
(F841)
src/praisonai/tests/unit/test_approval_basic.py
19-19: praisonaiagents.approval.require_approval imported but unused; consider using importlib.util.find_spec to test for availability
(F401)
20-20: praisonaiagents.approval.ApprovalDecision imported but unused; consider using importlib.util.find_spec to test for availability
(F401)
21-21: praisonaiagents.approval.console_approval_callback imported but unused; consider using importlib.util.find_spec to test for availability
(F401)
22-22: praisonaiagents.approval.request_approval imported but unused; consider using importlib.util.find_spec to test for availability
(F401)
23-23: praisonaiagents.approval.add_approval_requirement imported but unused; consider using importlib.util.find_spec to test for availability
(F401)
24-24: praisonaiagents.approval.remove_approval_requirement imported but unused; consider using importlib.util.find_spec to test for availability
(F401)
25-25: praisonaiagents.approval.is_approval_required imported but unused; consider using importlib.util.find_spec to test for availability
(F401)
26-26: praisonaiagents.approval.get_risk_level imported but unused; consider using importlib.util.find_spec to test for availability
(F401)
27-27: praisonaiagents.approval.APPROVAL_REQUIRED_TOOLS imported but unused; consider using importlib.util.find_spec to test for availability
(F401)
28-28: praisonaiagents.approval.TOOL_RISK_LEVELS imported but unused; consider using importlib.util.find_spec to test for availability
(F401)
44-44: praisonaiagents.approval.TOOL_RISK_LEVELS imported but unused
Remove unused import: praisonaiagents.approval.TOOL_RISK_LEVELS
(F401)
100-100: Local variable shell_tools is assigned to but never used
Remove assignment to unused variable shell_tools
(F841)
117-117: Local variable python_tools is assigned to but never used
Remove assignment to unused variable python_tools
(F841)
129-129: Local variable file_tools is assigned to but never used
Remove assignment to unused variable file_tools
(F841)
194-194: Local variable agent is assigned to but never used
Remove assignment to unused variable agent
(F841)
src/praisonai/tests/unit/test_approval_agent_integration.py
11-11: asyncio imported but unused
Remove unused import: asyncio
(F401)
examples/python/general/human_approval_example.py
29-29: praisonaiagents.main.register_approval_callback imported but unused
Remove unused import: praisonaiagents.main.register_approval_callback
(F401)
45-45: f-string without any placeholders
Remove extraneous f prefix
(F541)
126-126: f-string without any placeholders
Remove extraneous f prefix
(F541)
src/praisonai-agents/praisonaiagents/approval.py
15-15: rich.text.Text imported but unused
Remove unused import: rich.text.Text
(F401)
29-29: Do not use mutable data structures for ContextVar defaults
(B039)
147-147: f-string without any placeholders
Remove extraneous f prefix
(F541)
src/praisonai/tests/unit/test_approval_interactive.py
11-11: asyncio imported but unused
Remove unused import: asyncio
(F401)
src/praisonai-agents/praisonaiagents/agent/agent.py
575-575: ..approval.ApprovalDecision imported but unused
Remove unused import: ..approval.ApprovalDecision
(F401)
🪛 Pylint (3.3.7)
src/praisonai/tests/unit/test_decorator_enforcement.py
[convention] 17-17: Trailing whitespace
(C0303)
[convention] 21-21: Trailing whitespace
(C0303)
[convention] 26-26: Trailing whitespace
(C0303)
[convention] 28-28: Trailing whitespace
(C0303)
[convention] 30-30: Trailing whitespace
(C0303)
[convention] 32-32: Trailing whitespace
(C0303)
[convention] 44-44: Trailing whitespace
(C0303)
[convention] 55-55: Final newline missing
(C0304)
[warning] 45-45: Catching too general exception Exception
(W0718)
[error] 19-19: Unable to import 'praisonaiagents.tools.shell_tools'
(E0401)
[convention] 19-19: Import outside toplevel (praisonaiagents.tools.shell_tools.ShellTools)
(C0415)
[error] 20-20: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 20-20: Import outside toplevel (praisonaiagents.approval.set_approval_callback, praisonaiagents.approval.ApprovalDecision)
(C0415)
[warning] 23-23: Unused argument 'arguments'
(W0613)
[warning] 41-41: Catching too general exception Exception
(W0718)
[warning] 35-35: Unused variable 'result'
(W0612)
[convention] 50-50: Constant name "success" doesn't conform to UPPER_CASE naming style
(C0103)
src/praisonai/tests/unit/test_approval_basic.py
[convention] 39-39: Trailing whitespace
(C0303)
[convention] 40-40: Trailing whitespace
(C0303)
[convention] 41-41: Trailing whitespace
(C0303)
[convention] 46-46: Trailing whitespace
(C0303)
[convention] 48-48: Trailing whitespace
(C0303)
[convention] 54-54: Trailing whitespace
(C0303)
[convention] 60-60: Trailing whitespace
(C0303)
[convention] 62-62: Line too long (104/100)
(C0301)
[convention] 63-63: Line too long (101/100)
(C0301)
[convention] 65-65: Trailing whitespace
(C0303)
[convention] 72-72: Trailing whitespace
(C0303)
[convention] 74-74: Trailing whitespace
(C0303)
[convention] 80-80: Trailing whitespace
(C0303)
[convention] 82-82: Line too long (104/100)
(C0301)
[convention] 85-85: Trailing whitespace
(C0303)
[convention] 90-90: Trailing whitespace
(C0303)
[convention] 96-96: Trailing whitespace
(C0303)
[convention] 101-101: Trailing whitespace
(C0303)
[convention] 106-106: Trailing whitespace
(C0303)
[convention] 110-110: Trailing whitespace
(C0303)
[convention] 113-113: Trailing whitespace
(C0303)
[convention] 118-118: Trailing whitespace
(C0303)
[convention] 122-122: Trailing whitespace
(C0303)
[convention] 125-125: Trailing whitespace
(C0303)
[convention] 130-130: Trailing whitespace
(C0303)
[convention] 134-134: Trailing whitespace
(C0303)
[convention] 138-138: Trailing whitespace
(C0303)
[convention] 141-141: Trailing whitespace
(C0303)
[convention] 147-147: Trailing whitespace
(C0303)
[convention] 149-149: Trailing whitespace
(C0303)
[convention] 154-154: Trailing whitespace
(C0303)
[convention] 159-159: Trailing whitespace
(C0303)
[convention] 163-163: Trailing whitespace
(C0303)
[convention] 168-168: Trailing whitespace
(C0303)
[convention] 169-169: Trailing whitespace
(C0303)
[convention] 171-171: Trailing whitespace
(C0303)
[convention] 176-176: Trailing whitespace
(C0303)
[convention] 182-182: Trailing whitespace
(C0303)
[convention] 188-188: Trailing whitespace
(C0303)
[convention] 192-192: Trailing whitespace
(C0303)
[convention] 201-201: Trailing whitespace
(C0303)
[convention] 203-203: Trailing whitespace
(C0303)
[convention] 207-207: Trailing whitespace
(C0303)
[convention] 209-209: Trailing whitespace
(C0303)
[convention] 218-218: Trailing whitespace
(C0303)
[convention] 220-220: Trailing whitespace
(C0303)
[convention] 227-227: Trailing whitespace
(C0303)
[convention] 235-235: Trailing whitespace
(C0303)
[convention] 240-240: Trailing whitespace
(C0303)
[convention] 243-243: Trailing whitespace
(C0303)
[convention] 251-251: Trailing whitespace
(C0303)
[convention] 255-255: Trailing whitespace
(C0303)
[convention] 265-265: Final newline missing
(C0304)
[convention] 18-29: Import outside toplevel (praisonaiagents.approval.require_approval, praisonaiagents.approval.ApprovalDecision, praisonaiagents.approval.console_approval_callback, praisonaiagents.approval.request_approval, praisonaiagents.approval.add_approval_requirement, praisonaiagents.approval.remove_approval_requirement, praisonaiagents.approval.is_approval_required, praisonaiagents.approval.get_risk_level, praisonaiagents.approval.APPROVAL_REQUIRED_TOOLS, praisonaiagents.approval.TOOL_RISK_LEVELS)
(C0415)
[warning] 18-29: Unused require_approval imported from praisonaiagents.approval
(W0611)
[warning] 18-29: Unused ApprovalDecision imported from praisonaiagents.approval
(W0611)
[warning] 18-29: Unused console_approval_callback imported from praisonaiagents.approval
(W0611)
[warning] 18-29: Unused request_approval imported from praisonaiagents.approval
(W0611)
[warning] 18-29: Unused add_approval_requirement imported from praisonaiagents.approval
(W0611)
[warning] 18-29: Unused remove_approval_requirement imported from praisonaiagents.approval
(W0611)
[warning] 18-29: Unused is_approval_required imported from praisonaiagents.approval
(W0611)
[warning] 18-29: Unused get_risk_level imported from praisonaiagents.approval
(W0611)
[warning] 18-29: Unused APPROVAL_REQUIRED_TOOLS imported from praisonaiagents.approval
(W0611)
[warning] 18-29: Unused TOOL_RISK_LEVELS imported from praisonaiagents.approval
(W0611)
[error] 38-45: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 38-45: Import outside toplevel (praisonaiagents.approval.add_approval_requirement, praisonaiagents.approval.remove_approval_requirement, praisonaiagents.approval.is_approval_required, praisonaiagents.approval.get_risk_level, praisonaiagents.approval.APPROVAL_REQUIRED_TOOLS, praisonaiagents.approval.TOOL_RISK_LEVELS)
(C0415)
[warning] 38-45: Unused TOOL_RISK_LEVELS imported from praisonaiagents.approval
(W0611)
[error] 71-71: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 71-71: Import outside toplevel (praisonaiagents.approval.require_approval, praisonaiagents.approval.is_approval_required, praisonaiagents.approval.get_risk_level)
(C0415)
[warning] 111-111: Catching too general exception Exception
(W0718)
[error] 99-99: Unable to import 'praisonaiagents.tools.shell_tools'
(E0401)
[convention] 99-99: Import outside toplevel (praisonaiagents.tools.shell_tools.ShellTools)
(C0415)
[error] 103-103: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 103-103: Import outside toplevel (praisonaiagents.approval.is_approval_required)
(C0415)
[warning] 123-123: Catching too general exception Exception
(W0718)
[error] 116-116: Unable to import 'praisonaiagents.tools.python_tools'
(E0401)
[convention] 116-116: Import outside toplevel (praisonaiagents.tools.python_tools.PythonTools)
(C0415)
[warning] 139-139: Catching too general exception Exception
(W0718)
[error] 128-128: Unable to import 'praisonaiagents.tools.file_tools'
(E0401)
[convention] 128-128: Import outside toplevel (praisonaiagents.tools.file_tools.FileTools)
(C0415)
[warning] 100-100: Unused variable 'shell_tools'
(W0612)
[warning] 117-117: Unused variable 'python_tools'
(W0612)
[warning] 129-129: Unused variable 'file_tools'
(W0612)
[error] 148-148: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 148-148: Import outside toplevel (praisonaiagents.approval.request_approval, praisonaiagents.approval.ApprovalDecision)
(C0415)
[warning] 151-151: Unused argument 'arguments'
(W0613)
[warning] 156-156: Unused argument 'arguments'
(W0613)
[error] 161-161: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 161-161: Import outside toplevel (praisonaiagents.approval.set_approval_callback)
(C0415)
[warning] 210-210: Catching too general exception Exception
(W0718)
[error] 190-190: Unable to import 'praisonaiagents'
(E0401)
[convention] 190-190: Import outside toplevel (praisonaiagents.Agent)
(C0415)
[error] 191-191: Unable to import 'praisonaiagents.tools.shell_tools'
(E0401)
[convention] 191-191: Import outside toplevel (praisonaiagents.tools.shell_tools.ShellTools)
(C0415)
[error] 205-205: Unable to import 'praisonaiagents.main'
(E0401)
[convention] 205-205: Import outside toplevel (praisonaiagents.main.approval_callback)
(C0415)
[warning] 194-194: Unused variable 'agent'
(W0612)
[warning] 232-232: Catching too general exception Exception
(W0718)
[refactor] 256-261: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it
(R1705)
[convention] 264-264: Constant name "success" doesn't conform to UPPER_CASE naming style
(C0103)
src/praisonai/tests/unit/test_approval_agent_integration.py
[convention] 23-23: Trailing whitespace
(C0303)
[convention] 27-27: Line too long (111/100)
(C0301)
[convention] 28-28: Trailing whitespace
(C0303)
[convention] 37-37: Trailing whitespace
(C0303)
[convention] 46-46: Trailing whitespace
(C0303)
[convention] 49-49: Trailing whitespace
(C0303)
[convention] 51-51: Line too long (112/100)
(C0301)
[convention] 52-52: Trailing whitespace
(C0303)
[convention] 59-59: Trailing whitespace
(C0303)
[convention] 61-61: Trailing whitespace
(C0303)
[convention] 70-70: Trailing whitespace
(C0303)
[convention] 75-75: Trailing whitespace
(C0303)
[convention] 80-80: Trailing whitespace
(C0303)
[convention] 82-82: Trailing whitespace
(C0303)
[convention] 91-91: Trailing whitespace
(C0303)
[convention] 93-93: Line too long (109/100)
(C0301)
[convention] 94-94: Trailing whitespace
(C0303)
[convention] 99-99: Trailing whitespace
(C0303)
[convention] 101-101: Trailing whitespace
(C0303)
[convention] 110-110: Trailing whitespace
(C0303)
[convention] 115-115: Trailing whitespace
(C0303)
[convention] 120-120: Trailing whitespace
(C0303)
[convention] 122-122: Trailing whitespace
(C0303)
[convention] 131-131: Trailing whitespace
(C0303)
[convention] 134-134: Trailing whitespace
(C0303)
[convention] 141-141: Trailing whitespace
(C0303)
[convention] 143-143: Trailing whitespace
(C0303)
[convention] 152-152: Trailing whitespace
(C0303)
[convention] 157-157: Trailing whitespace
(C0303)
[convention] 162-162: Trailing whitespace
(C0303)
[convention] 164-164: Trailing whitespace
(C0303)
[convention] 173-173: Trailing whitespace
(C0303)
[convention] 179-179: Trailing whitespace
(C0303)
[convention] 182-182: Trailing whitespace
(C0303)
[convention] 187-187: Trailing whitespace
(C0303)
[convention] 189-189: Trailing whitespace
(C0303)
[convention] 198-198: Trailing whitespace
(C0303)
[convention] 203-203: Trailing whitespace
(C0303)
[convention] 208-208: Trailing whitespace
(C0303)
[convention] 210-210: Trailing whitespace
(C0303)
[convention] 219-219: Trailing whitespace
(C0303)
[convention] 226-226: Trailing whitespace
(C0303)
[convention] 229-229: Trailing whitespace
(C0303)
[convention] 233-233: Trailing whitespace
(C0303)
[convention] 240-240: Trailing whitespace
(C0303)
[convention] 242-242: Trailing whitespace
(C0303)
[convention] 253-253: Trailing whitespace
(C0303)
[convention] 263-263: Trailing whitespace
(C0303)
[convention] 266-266: Trailing whitespace
(C0303)
[convention] 279-279: Trailing whitespace
(C0303)
[convention] 288-288: Trailing whitespace
(C0303)
[convention] 295-295: Trailing whitespace
(C0303)
[convention] 303-303: Trailing whitespace
(C0303)
[convention] 311-311: Trailing whitespace
(C0303)
[convention] 318-318: Final newline missing
(C0304)
[warning] 62-62: Catching too general exception Exception
(W0718)
[error] 25-25: Unable to import 'praisonaiagents'
(E0401)
[convention] 25-25: Import outside toplevel (praisonaiagents.Agent)
(C0415)
[error] 26-26: Unable to import 'praisonaiagents.tools.shell_tools'
(E0401)
[convention] 26-26: Import outside toplevel (praisonaiagents.tools.shell_tools.ShellTools)
(C0415)
[error] 27-27: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 27-27: Import outside toplevel (praisonaiagents.approval.set_approval_callback, praisonaiagents.approval.console_approval_callback, praisonaiagents.approval.ApprovalDecision)
(C0415)
[warning] 34-34: Unused argument 'function_name'
(W0613)
[warning] 34-34: Unused argument 'arguments'
(W0613)
[warning] 34-34: Unused argument 'risk_level'
(W0613)
[warning] 102-102: Catching too general exception Exception
(W0718)
[error] 72-72: Unable to import 'praisonaiagents'
(E0401)
[convention] 72-72: Import outside toplevel (praisonaiagents.Agent)
(C0415)
[error] 73-73: Unable to import 'praisonaiagents.tools.shell_tools'
(E0401)
[convention] 73-73: Import outside toplevel (praisonaiagents.tools.shell_tools.ShellTools)
(C0415)
[error] 74-74: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 74-74: Import outside toplevel (praisonaiagents.approval.set_approval_callback, praisonaiagents.approval.ApprovalDecision)
(C0415)
[warning] 77-77: Unused argument 'arguments'
(W0613)
[warning] 144-144: Catching too general exception Exception
(W0718)
[error] 112-112: Unable to import 'praisonaiagents'
(E0401)
[convention] 112-112: Import outside toplevel (praisonaiagents.Agent)
(C0415)
[error] 113-113: Unable to import 'praisonaiagents.tools.shell_tools'
(E0401)
[convention] 113-113: Import outside toplevel (praisonaiagents.tools.shell_tools.ShellTools)
(C0415)
[error] 114-114: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 114-114: Import outside toplevel (praisonaiagents.approval.set_approval_callback, praisonaiagents.approval.ApprovalDecision)
(C0415)
[warning] 117-117: Unused argument 'arguments'
(W0613)
[warning] 190-190: Catching too general exception Exception
(W0718)
[error] 154-154: Unable to import 'praisonaiagents'
(E0401)
[convention] 154-154: Import outside toplevel (praisonaiagents.Agent)
(C0415)
[error] 155-155: Unable to import 'praisonaiagents.tools.python_tools'
(E0401)
[convention] 155-155: Import outside toplevel (praisonaiagents.tools.python_tools.PythonTools)
(C0415)
[error] 156-156: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 156-156: Import outside toplevel (praisonaiagents.approval.set_approval_callback, praisonaiagents.approval.ApprovalDecision)
(C0415)
[warning] 159-159: Unused argument 'arguments'
(W0613)
[warning] 243-243: Catching too general exception Exception
(W0718)
[error] 200-200: Unable to import 'praisonaiagents'
(E0401)
[convention] 200-200: Import outside toplevel (praisonaiagents.Agent)
(C0415)
[error] 201-201: Unable to import 'praisonaiagents.tools.file_tools'
(E0401)
[convention] 201-201: Import outside toplevel (praisonaiagents.tools.file_tools.FileTools)
(C0415)
[error] 202-202: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 202-202: Import outside toplevel (praisonaiagents.approval.set_approval_callback, praisonaiagents.approval.ApprovalDecision)
(C0415)
[warning] 205-205: Unused argument 'arguments'
(W0613)
[warning] 314-314: Catching too general exception Exception
(W0718)
[refactor] 247-247: Too many statements (57/50)
(R0915)
[warning] 11-11: Unused import asyncio
(W0611)
src/praisonai/tests/unit/test_decorator_simple.py
[convention] 16-16: Trailing whitespace
(C0303)
[convention] 22-22: Trailing whitespace
(C0303)
[convention] 25-25: Trailing whitespace
(C0303)
[convention] 30-30: Trailing whitespace
(C0303)
[convention] 32-32: Trailing whitespace
(C0303)
[convention] 35-35: Trailing whitespace
(C0303)
[convention] 38-38: Trailing whitespace
(C0303)
[convention] 40-40: Trailing whitespace
(C0303)
[convention] 46-46: Trailing whitespace
(C0303)
[convention] 49-49: Trailing whitespace
(C0303)
[convention] 51-51: Trailing whitespace
(C0303)
[convention] 57-57: Trailing whitespace
(C0303)
[convention] 60-60: Trailing whitespace
(C0303)
[convention] 62-62: Trailing whitespace
(C0303)
[convention] 65-65: Trailing whitespace
(C0303)
[convention] 67-67: Trailing whitespace
(C0303)
[convention] 73-73: Trailing whitespace
(C0303)
[convention] 76-76: Trailing whitespace
(C0303)
[convention] 81-81: Trailing whitespace
(C0303)
[convention] 83-83: Trailing whitespace
(C0303)
[convention] 101-101: Trailing whitespace
(C0303)
[convention] 102-102: Final newline missing
(C0304)
[warning] 84-84: Catching too general exception Exception
(W0718)
[convention] 18-21: Import outside toplevel (praisonaiagents.approval.require_approval, praisonaiagents.approval.set_approval_callback, praisonaiagents.approval.ApprovalDecision, praisonaiagents.approval.mark_approved, praisonaiagents.approval.is_already_approved, praisonaiagents.approval.clear_approval_context)
(C0415)
[warning] 36-36: Unused argument 'function_name'
(W0613)
[warning] 36-36: Unused argument 'arguments'
(W0613)
[warning] 36-36: Unused argument 'risk_level'
(W0613)
[warning] 55-55: Catching too general exception Exception
(W0718)
[warning] 63-63: Unused argument 'function_name'
(W0613)
[warning] 63-63: Unused argument 'arguments'
(W0613)
[warning] 63-63: Unused argument 'risk_level'
(W0613)
[warning] 71-71: Catching too general exception Exception
(W0718)
[convention] 86-86: Import outside toplevel (traceback)
(C0415)
[convention] 91-91: Constant name "success" doesn't conform to UPPER_CASE naming style
(C0103)
examples/python/general/human_approval_example.py
[convention] 25-25: Line too long (101/100)
(C0301)
[convention] 31-31: Trailing whitespace
(C0303)
[convention] 40-40: Line too long (103/100)
(C0301)
[convention] 49-49: Trailing whitespace
(C0303)
[convention] 54-54: Trailing whitespace
(C0303)
[convention] 57-57: Trailing whitespace
(C0303)
[convention] 62-62: Trailing whitespace
(C0303)
[convention] 68-68: Trailing whitespace
(C0303)
[convention] 74-74: Trailing whitespace
(C0303)
[convention] 79-79: Trailing whitespace
(C0303)
[convention] 88-88: Trailing whitespace
(C0303)
[convention] 112-112: Trailing whitespace
(C0303)
[convention] 119-119: Trailing whitespace
(C0303)
[convention] 123-123: Trailing whitespace
(C0303)
[convention] 135-135: Trailing whitespace
(C0303)
[convention] 138-138: Trailing whitespace
(C0303)
[convention] 142-142: Trailing whitespace
(C0303)
[convention] 146-146: Trailing whitespace
(C0303)
[convention] 154-154: Trailing whitespace
(C0303)
[convention] 157-157: Trailing whitespace
(C0303)
[convention] 161-161: Trailing whitespace
(C0303)
[convention] 166-166: Trailing whitespace
(C0303)
[convention] 173-173: Trailing whitespace
(C0303)
[convention] 179-179: Trailing whitespace
(C0303)
[convention] 188-188: Trailing whitespace
(C0303)
[convention] 191-191: Trailing whitespace
(C0303)
[convention] 194-194: Trailing whitespace
(C0303)
[convention] 203-203: Trailing whitespace
(C0303)
[convention] 210-210: Final newline missing
(C0304)
[error] 27-27: Unable to import 'praisonaiagents'
(E0401)
[convention] 27-27: Import "from praisonaiagents import Agent, Task, PraisonAIAgents" should be placed at the top of the module
(C0413)
[error] 28-28: Unable to import 'praisonaiagents.tools'
(E0401)
[convention] 28-28: Import "from praisonaiagents.tools import python_tools, file_tools, shell_tools" should be placed at the top of the module
(C0413)
[error] 29-29: Unable to import 'praisonaiagents.main'
(E0401)
[convention] 29-29: Import "from praisonaiagents.main import register_approval_callback" should be placed at the top of the module
(C0413)
[error] 30-35: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 30-35: Import "from praisonaiagents.approval import console_approval_callback, ApprovalDecision, add_approval_requirement, remove_approval_requirement" should be placed at the top of the module
(C0413)
[warning] 45-45: Using an f-string that does not have any interpolated variables
(W1309)
[warning] 130-130: Catching too general exception Exception
(W0718)
[warning] 126-126: Using an f-string that does not have any interpolated variables
(W1309)
[error] 148-148: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 148-148: Import outside toplevel (praisonaiagents.approval.APPROVAL_REQUIRED_TOOLS, praisonaiagents.approval.TOOL_RISK_LEVELS)
(C0415)
[warning] 183-183: Catching too general exception Exception
(W0718)
[warning] 29-29: Unused register_approval_callback imported from praisonaiagents.main
(W0611)
src/praisonai-agents/praisonaiagents/approval.py
[convention] 33-33: Line too long (105/100)
(C0301)
[convention] 71-71: Trailing whitespace
(C0303)
[convention] 77-77: Trailing whitespace
(C0303)
[convention] 95-95: Trailing whitespace
(C0303)
[convention] 98-98: Trailing whitespace
(C0303)
[convention] 103-103: Trailing whitespace
(C0303)
[convention] 109-109: Trailing whitespace
(C0303)
[convention] 114-114: Trailing whitespace
(C0303)
[convention] 119-119: Trailing whitespace
(C0303)
[convention] 125-125: Trailing whitespace
(C0303)
[convention] 128-128: Line too long (114/100)
(C0301)
[convention] 134-134: Trailing whitespace
(C0303)
[convention] 143-143: Trailing whitespace
(C0303)
[convention] 148-148: Trailing whitespace
(C0303)
[convention] 155-155: Trailing whitespace
(C0303)
[convention] 162-162: Trailing whitespace
(C0303)
[convention] 169-169: Trailing whitespace
(C0303)
[convention] 176-176: Trailing whitespace
(C0303)
[convention] 197-197: Trailing whitespace
(C0303)
[convention] 199-199: Trailing whitespace
(C0303)
[convention] 202-202: Trailing whitespace
(C0303)
[convention] 210-210: Line too long (103/100)
(C0301)
[convention] 211-211: Trailing whitespace
(C0303)
[convention] 213-213: Trailing whitespace
(C0303)
[convention] 224-224: Trailing whitespace
(C0303)
[convention] 231-231: Trailing whitespace
(C0303)
[convention] 263-263: Final newline missing
(C0304)
[refactor] 31-31: Too few public methods (0/2)
(R0903)
[warning] 43-43: Using the global statement
(W0603)
[warning] 90-90: Catching too general exception Exception
(W0718)
[warning] 92-92: Use lazy % formatting in logging functions
(W1203)
[error] 96-96: Using variable 'decision' before assignment
(E0601)
[refactor] 121-124: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it
(R1705)
[warning] 147-147: Using an f-string that does not have any interpolated variables
(W1309)
[warning] 180-180: Catching too general exception Exception
(W0718)
[refactor] 170-175: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it
(R1705)
[warning] 214-214: Catching too general exception Exception
(W0718)
[warning] 215-215: Use lazy % formatting in logging functions
(W1203)
[warning] 15-15: Unused Text imported from rich.text
(W0611)
src/praisonai/tests/unit/test_approval_interactive.py
[convention] 22-22: Trailing whitespace
(C0303)
[convention] 25-25: Line too long (111/100)
(C0301)
[convention] 26-26: Trailing whitespace
(C0303)
[convention] 35-35: Trailing whitespace
(C0303)
[convention] 37-37: Trailing whitespace
(C0303)
[convention] 40-40: Trailing whitespace
(C0303)
[convention] 43-43: Trailing whitespace
(C0303)
[convention] 48-48: Trailing whitespace
(C0303)
[convention] 50-50: Trailing whitespace
(C0303)
[convention] 60-60: Trailing whitespace
(C0303)
[convention] 63-63: Line too long (111/100)
(C0301)
[convention] 64-64: Trailing whitespace
(C0303)
[convention] 73-73: Trailing whitespace
(C0303)
[convention] 75-75: Trailing whitespace
(C0303)
[convention] 78-78: Trailing whitespace
(C0303)
[convention] 85-85: Trailing whitespace
(C0303)
[convention] 87-87: Trailing whitespace
(C0303)
[convention] 92-92: Trailing whitespace
(C0303)
[convention] 94-94: Trailing whitespace
(C0303)
[convention] 104-104: Trailing whitespace
(C0303)
[convention] 107-107: Line too long (111/100)
(C0301)
[convention] 108-108: Trailing whitespace
(C0303)
[convention] 117-117: Trailing whitespace
(C0303)
[convention] 119-119: Trailing whitespace
(C0303)
[convention] 122-122: Trailing whitespace
(C0303)
[convention] 128-128: Trailing whitespace
(C0303)
[convention] 131-131: Trailing whitespace
(C0303)
[convention] 135-135: Trailing whitespace
(C0303)
[convention] 139-139: Line too long (109/100)
(C0301)
[convention] 142-142: Trailing whitespace
(C0303)
[convention] 144-144: Trailing whitespace
(C0303)
[convention] 153-153: Trailing whitespace
(C0303)
[convention] 157-157: Trailing whitespace
(C0303)
[convention] 162-162: Trailing whitespace
(C0303)
[convention] 164-164: Trailing whitespace
(C0303)
[convention] 166-166: Trailing whitespace
(C0303)
[convention] 169-169: Trailing whitespace
(C0303)
[convention] 174-174: Trailing whitespace
(C0303)
[convention] 176-176: Trailing whitespace
(C0303)
[convention] 185-185: Trailing whitespace
(C0303)
[convention] 189-189: Trailing whitespace
(C0303)
[convention] 194-194: Trailing whitespace
(C0303)
[convention] 196-196: Trailing whitespace
(C0303)
[convention] 198-198: Trailing whitespace
(C0303)
[convention] 201-201: Trailing whitespace
(C0303)
[convention] 208-208: Trailing whitespace
(C0303)
[convention] 210-210: Trailing whitespace
(C0303)
[convention] 222-222: Trailing whitespace
(C0303)
[convention] 232-232: Trailing whitespace
(C0303)
[convention] 235-235: Trailing whitespace
(C0303)
[convention] 248-248: Trailing whitespace
(C0303)
[convention] 255-255: Trailing whitespace
(C0303)
[convention] 262-262: Trailing whitespace
(C0303)
[convention] 272-272: Trailing whitespace
(C0303)
[convention] 280-280: Trailing whitespace
(C0303)
[convention] 287-287: Final newline missing
(C0304)
[warning] 51-51: Catching too general exception Exception
(W0718)
[error] 24-24: Unable to import 'praisonaiagents.tools.shell_tools'
(E0401)
[convention] 24-24: Import outside toplevel (praisonaiagents.tools.shell_tools.ShellTools)
(C0415)
[error] 25-25: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 25-25: Import outside toplevel (praisonaiagents.approval.set_approval_callback, praisonaiagents.approval.console_approval_callback, praisonaiagents.approval.ApprovalDecision)
(C0415)
[warning] 32-32: Unused argument 'function_name'
(W0613)
[warning] 32-32: Unused argument 'arguments'
(W0613)
[warning] 32-32: Unused argument 'risk_level'
(W0613)
[warning] 95-95: Catching too general exception Exception
(W0718)
[error] 62-62: Unable to import 'praisonaiagents.tools.python_tools'
(E0401)
[convention] 62-62: Import outside toplevel (praisonaiagents.tools.python_tools.PythonTools)
(C0415)
[error] 63-63: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 63-63: Import outside toplevel (praisonaiagents.approval.set_approval_callback, praisonaiagents.approval.console_approval_callback, praisonaiagents.approval.ApprovalDecision)
(C0415)
[warning] 70-70: Unused argument 'function_name'
(W0613)
[warning] 70-70: Unused argument 'arguments'
(W0613)
[warning] 70-70: Unused argument 'risk_level'
(W0613)
[warning] 145-145: Catching too general exception Exception
(W0718)
[error] 106-106: Unable to import 'praisonaiagents.tools.file_tools'
(E0401)
[convention] 106-106: Import outside toplevel (praisonaiagents.tools.file_tools.FileTools)
(C0415)
[error] 107-107: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 107-107: Import outside toplevel (praisonaiagents.approval.set_approval_callback, praisonaiagents.approval.console_approval_callback, praisonaiagents.approval.ApprovalDecision)
(C0415)
[warning] 114-114: Unused argument 'function_name'
(W0613)
[warning] 114-114: Unused argument 'arguments'
(W0613)
[warning] 114-114: Unused argument 'risk_level'
(W0613)
[warning] 177-177: Catching too general exception Exception
(W0718)
[error] 155-155: Unable to import 'praisonaiagents.tools.shell_tools'
(E0401)
[convention] 155-155: Import outside toplevel (praisonaiagents.tools.shell_tools.ShellTools)
(C0415)
[error] 156-156: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 156-156: Import outside toplevel (praisonaiagents.approval.set_approval_callback, praisonaiagents.approval.ApprovalDecision)
(C0415)
[warning] 159-159: Unused argument 'arguments'
(W0613)
[warning] 211-211: Catching too general exception Exception
(W0718)
[error] 187-187: Unable to import 'praisonaiagents.tools.shell_tools'
(E0401)
[convention] 187-187: Import outside toplevel (praisonaiagents.tools.shell_tools.ShellTools)
(C0415)
[error] 188-188: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 188-188: Import outside toplevel (praisonaiagents.approval.set_approval_callback, praisonaiagents.approval.ApprovalDecision)
(C0415)
[warning] 191-191: Unused argument 'arguments'
(W0613)
[warning] 283-283: Catching too general exception Exception
(W0718)
[refactor] 215-215: Too many statements (58/50)
(R0915)
[warning] 11-11: Unused import asyncio
(W0611)
src/praisonai-agents/praisonaiagents/agent/agent.py
[convention] 575-575: Line too long (127/100)
(C0301)
[convention] 579-579: Trailing whitespace
(C0303)
[convention] 582-582: Trailing whitespace
(C0303)
[convention] 589-589: Trailing whitespace
(C0303)
[convention] 592-592: Trailing whitespace
(C0303)
[convention] 597-597: Trailing whitespace
(C0303)
[convention] 575-575: Import outside toplevel (approval.is_approval_required, approval.console_approval_callback, approval.get_risk_level, approval.mark_approved, approval.ApprovalDecision)
(C0415)
[warning] 578-578: Use lazy % formatting in logging functions
(W1203)
[warning] 598-598: Catching too general exception Exception
(W0718)
[warning] 596-596: Use lazy % formatting in logging functions
(W1203)
[warning] 575-575: Unused ApprovalDecision imported from approval
(W0611)
[convention] 1451-1451: Trailing whitespace
(C0303)
[convention] 1460-1460: Trailing whitespace
(C0303)
[convention] 1465-1465: Trailing whitespace
(C0303)
[convention] 1453-1453: Import outside toplevel (approval.is_approval_required, approval.request_approval)
(C0415)
[warning] 1464-1464: Use lazy % formatting in logging functions
(W1203)
⏰ Context from checks skipped due to timeout of 90000ms (3)
- GitHub Check: quick-test
- GitHub Check: test-core (3.11)
- GitHub Check: quick-test
🔇 Additional comments (13)
src/praisonai/tests/unit/test_decorator_enforcement.py (1)
13-47: Test logic is well-structured and comprehensive.The test correctly:
- Sets up an auto-denial callback to ensure enforcement
- Attempts direct tool execution outside agent context
- Expects and catches the appropriate
PermissionError- Provides clear success/failure feedback
This effectively validates that the decorator enforcement works at the tool level.
🧰 Tools
🪛 Ruff (0.11.9)
35-35: Local variable
resultis assigned to but never usedRemove assignment to unused variable
result(F841)
🪛 Pylint (3.3.7)
[convention] 17-17: Trailing whitespace
(C0303)
[convention] 21-21: Trailing whitespace
(C0303)
[convention] 26-26: Trailing whitespace
(C0303)
[convention] 28-28: Trailing whitespace
(C0303)
[convention] 30-30: Trailing whitespace
(C0303)
[convention] 32-32: Trailing whitespace
(C0303)
[convention] 44-44: Trailing whitespace
(C0303)
[warning] 45-45: Catching too general exception Exception
(W0718)
[error] 19-19: Unable to import 'praisonaiagents.tools.shell_tools'
(E0401)
[convention] 19-19: Import outside toplevel (praisonaiagents.tools.shell_tools.ShellTools)
(C0415)
[error] 20-20: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 20-20: Import outside toplevel (praisonaiagents.approval.set_approval_callback, praisonaiagents.approval.ApprovalDecision)
(C0415)
[warning] 23-23: Unused argument 'arguments'
(W0613)
[warning] 41-41: Catching too general exception Exception
(W0718)
[warning] 35-35: Unused variable 'result'
(W0612)
src/praisonai/tests/unit/test_approval_basic.py (3)
15-34: Excellent test structure for import validation.The
test_imports()function effectively verifies that all critical approval system components can be imported successfully. The imports within the function are intentional for testing import capabilities, not for actual usage.🧰 Tools
🪛 Ruff (0.11.9)
19-19:
praisonaiagents.approval.require_approvalimported but unused; consider usingimportlib.util.find_specto test for availability(F401)
20-20:
praisonaiagents.approval.ApprovalDecisionimported but unused; consider usingimportlib.util.find_specto test for availability(F401)
21-21:
praisonaiagents.approval.console_approval_callbackimported but unused; consider usingimportlib.util.find_specto test for availability(F401)
22-22:
praisonaiagents.approval.request_approvalimported but unused; consider usingimportlib.util.find_specto test for availability(F401)
23-23:
praisonaiagents.approval.add_approval_requirementimported but unused; consider usingimportlib.util.find_specto test for availability(F401)
24-24:
praisonaiagents.approval.remove_approval_requirementimported but unused; consider usingimportlib.util.find_specto test for availability(F401)
25-25:
praisonaiagents.approval.is_approval_requiredimported but unused; consider usingimportlib.util.find_specto test for availability(F401)
26-26:
praisonaiagents.approval.get_risk_levelimported but unused; consider usingimportlib.util.find_specto test for availability(F401)
27-27:
praisonaiagents.approval.APPROVAL_REQUIRED_TOOLSimported but unused; consider usingimportlib.util.find_specto test for availability(F401)
28-28:
praisonaiagents.approval.TOOL_RISK_LEVELSimported but unused; consider usingimportlib.util.find_specto test for availability(F401)
🪛 Pylint (3.3.7)
[convention] 18-29: Import outside toplevel (praisonaiagents.approval.require_approval, praisonaiagents.approval.ApprovalDecision, praisonaiagents.approval.console_approval_callback, praisonaiagents.approval.request_approval, praisonaiagents.approval.add_approval_requirement, praisonaiagents.approval.remove_approval_requirement, praisonaiagents.approval.is_approval_required, praisonaiagents.approval.get_risk_level, praisonaiagents.approval.APPROVAL_REQUIRED_TOOLS, praisonaiagents.approval.TOOL_RISK_LEVELS)
(C0415)
[warning] 18-29: Unused require_approval imported from praisonaiagents.approval
(W0611)
[warning] 18-29: Unused ApprovalDecision imported from praisonaiagents.approval
(W0611)
[warning] 18-29: Unused console_approval_callback imported from praisonaiagents.approval
(W0611)
[warning] 18-29: Unused request_approval imported from praisonaiagents.approval
(W0611)
[warning] 18-29: Unused add_approval_requirement imported from praisonaiagents.approval
(W0611)
[warning] 18-29: Unused remove_approval_requirement imported from praisonaiagents.approval
(W0611)
[warning] 18-29: Unused is_approval_required imported from praisonaiagents.approval
(W0611)
[warning] 18-29: Unused get_risk_level imported from praisonaiagents.approval
(W0611)
[warning] 18-29: Unused APPROVAL_REQUIRED_TOOLS imported from praisonaiagents.approval
(W0611)
[warning] 18-29: Unused TOOL_RISK_LEVELS imported from praisonaiagents.approval
(W0611)
144-183: Comprehensive async approval callback testing.The async test function thoroughly validates:
- Denial callback behavior with proper error messaging
- Approval callback functionality
- Auto-approval for non-dangerous tools
- Proper
ApprovalDecisionobject handlingThis ensures the callback system works correctly in asynchronous contexts.
🧰 Tools
🪛 Pylint (3.3.7)
[convention] 147-147: Trailing whitespace
(C0303)
[convention] 149-149: Trailing whitespace
(C0303)
[convention] 154-154: Trailing whitespace
(C0303)
[convention] 159-159: Trailing whitespace
(C0303)
[convention] 163-163: Trailing whitespace
(C0303)
[convention] 168-168: Trailing whitespace
(C0303)
[convention] 169-169: Trailing whitespace
(C0303)
[convention] 171-171: Trailing whitespace
(C0303)
[convention] 176-176: Trailing whitespace
(C0303)
[convention] 182-182: Trailing whitespace
(C0303)
[error] 148-148: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 148-148: Import outside toplevel (praisonaiagents.approval.request_approval, praisonaiagents.approval.ApprovalDecision)
(C0415)
[warning] 151-151: Unused argument 'arguments'
(W0613)
[warning] 156-156: Unused argument 'arguments'
(W0613)
[error] 161-161: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 161-161: Import outside toplevel (praisonaiagents.approval.set_approval_callback)
(C0415)
214-261: Well-designed test orchestration and reporting.The
main()function provides:
- Systematic execution of all test categories
- Proper async test handling with
asyncio.run()- Clear summary reporting with pass/fail counts
- Appropriate exit codes for CI/CD integration
🧰 Tools
🪛 Pylint (3.3.7)
[convention] 218-218: Trailing whitespace
(C0303)
[convention] 220-220: Trailing whitespace
(C0303)
[convention] 227-227: Trailing whitespace
(C0303)
[convention] 235-235: Trailing whitespace
(C0303)
[convention] 240-240: Trailing whitespace
(C0303)
[convention] 243-243: Trailing whitespace
(C0303)
[convention] 251-251: Trailing whitespace
(C0303)
[convention] 255-255: Trailing whitespace
(C0303)
[warning] 232-232: Catching too general exception Exception
(W0718)
[refactor] 256-261: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it
(R1705)
src/praisonai/tests/unit/test_decorator_simple.py (2)
27-82: Excellent comprehensive testing of decorator context management.The test thoroughly validates:
- Decorator application and function marking
- Denial behavior without approval context
- Successful execution with approval context via
mark_approved()- Auto-approval callback functionality
- Context persistence verification with
is_already_approved()This provides excellent coverage of the improved decorator's context management capabilities.
🧰 Tools
🪛 Pylint (3.3.7)
[convention] 30-30: Trailing whitespace
(C0303)
[convention] 32-32: Trailing whitespace
(C0303)
[convention] 35-35: Trailing whitespace
(C0303)
[convention] 38-38: Trailing whitespace
(C0303)
[convention] 40-40: Trailing whitespace
(C0303)
[convention] 46-46: Trailing whitespace
(C0303)
[convention] 49-49: Trailing whitespace
(C0303)
[convention] 51-51: Trailing whitespace
(C0303)
[convention] 57-57: Trailing whitespace
(C0303)
[convention] 60-60: Trailing whitespace
(C0303)
[convention] 62-62: Trailing whitespace
(C0303)
[convention] 65-65: Trailing whitespace
(C0303)
[convention] 67-67: Trailing whitespace
(C0303)
[convention] 73-73: Trailing whitespace
(C0303)
[convention] 76-76: Trailing whitespace
(C0303)
[convention] 81-81: Trailing whitespace
(C0303)
[warning] 36-36: Unused argument 'function_name'
(W0613)
[warning] 36-36: Unused argument 'arguments'
(W0613)
[warning] 36-36: Unused argument 'risk_level'
(W0613)
[warning] 55-55: Catching too general exception Exception
(W0718)
[warning] 63-63: Unused argument 'function_name'
(W0613)
[warning] 63-63: Unused argument 'arguments'
(W0613)
[warning] 63-63: Unused argument 'risk_level'
(W0613)
[warning] 71-71: Catching too general exception Exception
(W0718)
90-101: Clear and informative test reporting.The test provides excellent feedback including:
- Success confirmation with specific improvements highlighted
- Key feature validation (context management, async handling, enforcement)
- Clear indication of the decorator's benefits and functionality
🧰 Tools
🪛 Pylint (3.3.7)
[convention] 101-101: Trailing whitespace
(C0303)
[convention] 91-91: Constant name "success" doesn't conform to UPPER_CASE naming style
(C0103)
src/praisonai-agents/praisonaiagents/agent/agent.py (1)
19-20: LGTM: Clean import additions for approval functionalityThe new imports for
adisplay_instructionandapproval_callbackare appropriately added to support the human approval system integration.src/praisonai-agents/praisonaiagents/approval.py (1)
61-127: Well-implemented decorator with proper sync/async support.The decorator correctly handles both synchronous and asynchronous functions, with appropriate fallback mechanisms and context management.
🧰 Tools
🪛 Pylint (3.3.7)
[convention] 71-71: Trailing whitespace
(C0303)
[convention] 77-77: Trailing whitespace
(C0303)
[convention] 95-95: Trailing whitespace
(C0303)
[convention] 98-98: Trailing whitespace
(C0303)
[convention] 103-103: Trailing whitespace
(C0303)
[convention] 109-109: Trailing whitespace
(C0303)
[convention] 114-114: Trailing whitespace
(C0303)
[convention] 119-119: Trailing whitespace
(C0303)
[convention] 125-125: Trailing whitespace
(C0303)
[warning] 90-90: Catching too general exception Exception
(W0718)
[warning] 92-92: Use lazy % formatting in logging functions
(W1203)
[error] 96-96: Using variable 'decision' before assignment
(E0601)
[refactor] 121-124: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it
(R1705)
examples/python/general/human_approval_example.py (5)
40-64: LGTM! Well-implemented custom approval callback.The custom approval callback demonstrates excellent examples of:
- Auto-approving low-risk operations
- Blocking dangerous commands with pattern matching
- Falling back to default console approval for other cases
The logic correctly handles different risk levels and provides meaningful feedback to users.
🧰 Tools
🪛 Ruff (0.11.9)
45-45: f-string without any placeholders
Remove extraneous
fprefix(F541)
🪛 Pylint (3.3.7)
[convention] 40-40: Line too long (103/100)
(C0301)
[convention] 49-49: Trailing whitespace
(C0303)
[convention] 54-54: Trailing whitespace
(C0303)
[convention] 57-57: Trailing whitespace
(C0303)
[convention] 62-62: Trailing whitespace
(C0303)
[warning] 45-45: Using an f-string that does not have any interpolated variables
(W1309)
89-111: Well-designed task examples covering different risk scenarios.The tasks effectively demonstrate various dangerous operations:
- Python code execution
- File system operations (create/delete)
- Shell commands
This provides a comprehensive showcase of the approval system across different tool categories.
133-150: LGTM! Excellent demonstration of runtime configuration.This function effectively shows how to:
- Add approval requirements for normally safe operations
- Remove requirements for dangerous operations
- Display current configuration state
The examples clearly illustrate the flexibility of the approval system.
🧰 Tools
🪛 Pylint (3.3.7)
[convention] 135-135: Trailing whitespace
(C0303)
[convention] 138-138: Trailing whitespace
(C0303)
[convention] 142-142: Trailing whitespace
(C0303)
[convention] 146-146: Trailing whitespace
(C0303)
[error] 148-148: Unable to import 'praisonaiagents.approval'
(E0401)
[convention] 148-148: Import outside toplevel (praisonaiagents.approval.APPROVAL_REQUIRED_TOOLS, praisonaiagents.approval.TOOL_RISK_LEVELS)
(C0415)
152-184: Good async demonstration with proper error handling.The async demo effectively shows how the approval system works in asynchronous contexts. The error handling is appropriate for this demonstration context.
🧰 Tools
🪛 Pylint (3.3.7)
[convention] 154-154: Trailing whitespace
(C0303)
[convention] 157-157: Trailing whitespace
(C0303)
[convention] 161-161: Trailing whitespace
(C0303)
[convention] 166-166: Trailing whitespace
(C0303)
[convention] 173-173: Trailing whitespace
(C0303)
[convention] 179-179: Trailing whitespace
(C0303)
[warning] 183-183: Catching too general exception Exception
(W0718)
196-202: Robust user input handling.The input handling properly catches
KeyboardInterruptand provides a good user experience with clear prompts and graceful error handling.
| import os | ||
|
|
||
| # Add the praisonai-agents module to path | ||
| sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src', 'praisonai-agents')) |
There was a problem hiding this comment.
Fix the path construction for module imports.
The current path construction may not work correctly depending on the test execution context. The path should be relative to the repository root structure.
-sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src', 'praisonai-agents'))
+sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', '..', 'praisonai-agents'))📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src', 'praisonai-agents')) | |
| -sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src', 'praisonai-agents')) | |
| +sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', '..', 'praisonai-agents')) |
🤖 Prompt for AI Agents
In src/praisonai/tests/unit/test_decorator_enforcement.py at line 11, the
sys.path insertion uses a relative path that may fail depending on where the
test is run. Modify the path construction to be relative to the repository root
by using an absolute path based on the repository root directory, ensuring
consistent module import resolution regardless of the current working directory.
| import asyncio | ||
|
|
||
| # Add the praisonai-agents module to path | ||
| sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', '..', 'praisonai-agents')) |
There was a problem hiding this comment.
Fix the path construction for module imports.
The current path construction may not work correctly. The path should be relative to the repository root structure.
-sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', '..', 'praisonai-agents'))
+sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', '..', '..', 'praisonai-agents'))📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', '..', 'praisonai-agents')) | |
| sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', '..', '..', 'praisonai-agents')) |
🤖 Prompt for AI Agents
In src/praisonai/tests/unit/test_approval_basic.py at line 13, the sys.path
insertion uses a relative path that may not correctly resolve from the
repository root. Update the path construction to be relative to the repository
root by adjusting the os.path.join arguments accordingly, ensuring it correctly
points to the 'praisonai-agents' directory from the root of the project.
| import os | ||
|
|
||
| # Add the praisonai-agents module to path | ||
| sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src', 'praisonai-agents')) |
There was a problem hiding this comment.
Fix the path construction for module imports.
The current path construction may not work correctly. The path should be relative to the repository root structure.
-sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src', 'praisonai-agents'))
+sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', '..', 'praisonai-agents'))📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src', 'praisonai-agents')) | |
| sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', '..', 'praisonai-agents')) |
🤖 Prompt for AI Agents
In src/praisonai/tests/unit/test_decorator_simple.py at line 10, the sys.path
insertion uses a path relative to the current file which may not correctly
resolve module imports. Modify the path construction to be relative to the
repository root by adjusting the os.path.join call to navigate from the repo
root to 'src/praisonai-agents', ensuring imports resolve correctly regardless of
the test file location.
| # Check if approval is required for this tool | ||
| from ..approval import is_approval_required, console_approval_callback, get_risk_level, mark_approved, ApprovalDecision | ||
| if is_approval_required(function_name): | ||
| risk_level = get_risk_level(function_name) | ||
| logging.info(f"Tool {function_name} requires approval (risk level: {risk_level})") | ||
|
|
||
| # Use global approval callback or default console callback | ||
| callback = approval_callback or console_approval_callback | ||
|
|
||
| try: | ||
| decision = callback(function_name, arguments, risk_level) | ||
| if not decision.approved: | ||
| error_msg = f"Tool execution denied: {decision.reason}" | ||
| logging.warning(error_msg) | ||
| return {"error": error_msg, "approval_denied": True} | ||
|
|
||
| # Mark as approved in context to prevent double approval in decorator | ||
| mark_approved(function_name) | ||
|
|
||
| # Use modified arguments if provided | ||
| if decision.modified_args: | ||
| arguments = decision.modified_args | ||
| logging.info(f"Using modified arguments: {arguments}") | ||
|
|
||
| except Exception as e: | ||
| error_msg = f"Error during approval process: {str(e)}" | ||
| logging.error(error_msg) | ||
| return {"error": error_msg, "approval_error": True} |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Fix import and code quality issues in approval integration
The approval integration logic is sound, but there are several code quality issues to address:
Apply this diff to fix the issues:
- # Check if approval is required for this tool
- from ..approval import is_approval_required, console_approval_callback, get_risk_level, mark_approved, ApprovalDecision
+ # Check if approval is required for this tool
+ from ..approval import is_approval_required, console_approval_callback, get_risk_level, mark_approved
if is_approval_required(function_name):
risk_level = get_risk_level(function_name)
- logging.info(f"Tool {function_name} requires approval (risk level: {risk_level})")
-
+ logging.info("Tool %s requires approval (risk level: %s)", function_name, risk_level)
+
# Use global approval callback or default console callback
callback = approval_callback or console_approval_callback
-
+
try:
decision = callback(function_name, arguments, risk_level)
if not decision.approved:
error_msg = f"Tool execution denied: {decision.reason}"
logging.warning(error_msg)
return {"error": error_msg, "approval_denied": True}
-
+
# Mark as approved in context to prevent double approval in decorator
mark_approved(function_name)
-
+
# Use modified arguments if provided
if decision.modified_args:
arguments = decision.modified_args
- logging.info(f"Using modified arguments: {arguments}")
-
+ logging.info("Using modified arguments: %s", arguments)
+
except Exception as e:
error_msg = f"Error during approval process: {str(e)}"
logging.error(error_msg)
return {"error": error_msg, "approval_error": True}
-Issues addressed:
- Removed unused
ApprovalDecisionimport (Ruff F401) - Fixed lazy logging formatting (Pylint W1203)
- Removed trailing whitespace
- Line length stays within reasonable bounds with the formatting changes
Note: The general exception catching is appropriate here since this is error handling at the boundary between the approval system and tool execution.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| # Check if approval is required for this tool | |
| from ..approval import is_approval_required, console_approval_callback, get_risk_level, mark_approved, ApprovalDecision | |
| if is_approval_required(function_name): | |
| risk_level = get_risk_level(function_name) | |
| logging.info(f"Tool {function_name} requires approval (risk level: {risk_level})") | |
| # Use global approval callback or default console callback | |
| callback = approval_callback or console_approval_callback | |
| try: | |
| decision = callback(function_name, arguments, risk_level) | |
| if not decision.approved: | |
| error_msg = f"Tool execution denied: {decision.reason}" | |
| logging.warning(error_msg) | |
| return {"error": error_msg, "approval_denied": True} | |
| # Mark as approved in context to prevent double approval in decorator | |
| mark_approved(function_name) | |
| # Use modified arguments if provided | |
| if decision.modified_args: | |
| arguments = decision.modified_args | |
| logging.info(f"Using modified arguments: {arguments}") | |
| except Exception as e: | |
| error_msg = f"Error during approval process: {str(e)}" | |
| logging.error(error_msg) | |
| return {"error": error_msg, "approval_error": True} | |
| # Check if approval is required for this tool | |
| from ..approval import is_approval_required, console_approval_callback, get_risk_level, mark_approved | |
| if is_approval_required(function_name): | |
| risk_level = get_risk_level(function_name) | |
| logging.info("Tool %s requires approval (risk level: %s)", function_name, risk_level) | |
| # Use global approval callback or default console callback | |
| callback = approval_callback or console_approval_callback | |
| try: | |
| decision = callback(function_name, arguments, risk_level) | |
| if not decision.approved: | |
| error_msg = f"Tool execution denied: {decision.reason}" | |
| logging.warning(error_msg) | |
| return {"error": error_msg, "approval_denied": True} | |
| # Mark as approved in context to prevent double approval in decorator | |
| mark_approved(function_name) | |
| # Use modified arguments if provided | |
| if decision.modified_args: | |
| arguments = decision.modified_args | |
| logging.info("Using modified arguments: %s", arguments) | |
| except Exception as e: | |
| error_msg = f"Error during approval process: {str(e)}" | |
| logging.error(error_msg) | |
| return {"error": error_msg, "approval_error": True} |
🧰 Tools
🪛 Ruff (0.11.9)
575-575: ..approval.ApprovalDecision imported but unused
Remove unused import: ..approval.ApprovalDecision
(F401)
🪛 Pylint (3.3.7)
[convention] 575-575: Line too long (127/100)
(C0301)
[convention] 579-579: Trailing whitespace
(C0303)
[convention] 582-582: Trailing whitespace
(C0303)
[convention] 589-589: Trailing whitespace
(C0303)
[convention] 592-592: Trailing whitespace
(C0303)
[convention] 597-597: Trailing whitespace
(C0303)
[convention] 575-575: Import outside toplevel (approval.is_approval_required, approval.console_approval_callback, approval.get_risk_level, approval.mark_approved, approval.ApprovalDecision)
(C0415)
[warning] 578-578: Use lazy % formatting in logging functions
(W1203)
[warning] 598-598: Catching too general exception Exception
(W0718)
[warning] 596-596: Use lazy % formatting in logging functions
(W1203)
[warning] 575-575: Unused ApprovalDecision imported from approval
(W0611)
🤖 Prompt for AI Agents
In src/praisonai-agents/praisonaiagents/agent/agent.py around lines 574 to 601,
remove the unused import ApprovalDecision to fix the unused import warning.
Change all logging calls that use f-strings to use lazy formatting by passing
the message and arguments separately to logging methods to improve performance
and comply with linting rules. Also, remove any trailing whitespace and ensure
line lengths remain reasonable by adjusting formatting as needed.
|
|
||
| import sys | ||
| import os | ||
| import asyncio |
There was a problem hiding this comment.
Remove unused import.
asyncio is imported but never used in this file.
-import asyncio📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| import asyncio |
🧰 Tools
🪛 Ruff (0.11.9)
11-11: asyncio imported but unused
Remove unused import: asyncio
(F401)
🪛 Pylint (3.3.7)
[warning] 11-11: Unused import asyncio
(W0611)
🤖 Prompt for AI Agents
In src/praisonai/tests/unit/test_approval_interactive.py at line 11, the import
statement for asyncio is unused. Remove the line importing asyncio to clean up
the code and avoid unnecessary imports.
| except KeyboardInterrupt: | ||
| print("\n❌ Process cancelled by user") | ||
| except Exception as e: | ||
| print(f"\n❌ Process failed: {e}") |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Improve exception handling specificity.
The broad Exception catch should be more specific to provide better error handling and debugging information.
except KeyboardInterrupt:
print("\n❌ Process cancelled by user")
- except Exception as e:
- print(f"\n❌ Process failed: {e}")
+ except Exception as e:
+ print(f"\n❌ Process failed: {e}")
+ logging.exception("Process execution failed")Consider catching specific exceptions like ImportError, AttributeError, etc. based on expected failure modes.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| except KeyboardInterrupt: | |
| print("\n❌ Process cancelled by user") | |
| except Exception as e: | |
| print(f"\n❌ Process failed: {e}") | |
| except KeyboardInterrupt: | |
| print("\n❌ Process cancelled by user") | |
| except Exception as e: | |
| print(f"\n❌ Process failed: {e}") | |
| logging.exception("Process execution failed") |
🧰 Tools
🪛 Pylint (3.3.7)
[warning] 130-130: Catching too general exception Exception
(W0718)
🤖 Prompt for AI Agents
In examples/python/general/human_approval_example.py around lines 128 to 131,
the current code catches a broad Exception which reduces error handling
specificity. Replace the broad Exception catch with more specific exceptions
such as ImportError, AttributeError, or others relevant to the expected failure
modes in this context. This will improve debugging and make error handling
clearer and more precise.
…12-20250601_032826 feat: Add human-in-the-loop approval system for dangerous tool operations
Implements human approval framework for dangerous operations like shell commands, code execution, and file operations to enhance security and user control.
Key features:
Resolves: #12
Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes
Tests
Documentation