Skip to content

refactor: streamline test functions in test_scheduler.py#586

Merged
MervinPraison merged 11 commits intomainfrom
develop
Jun 3, 2025
Merged

refactor: streamline test functions in test_scheduler.py#586
MervinPraison merged 11 commits intomainfrom
develop

Conversation

@MervinPraison
Copy link
Copy Markdown
Owner

@MervinPraison MervinPraison commented Jun 3, 2025

User description

  • Removed unnecessary try-except blocks in test functions for cleaner code.
  • Optimised the structure of test cases for better readability and maintainability.
  • Ensured consistent import statements and improved error handling in test execution.
  • Maintained functionality while adhering to the principle of minimal code change.

PR Type

Tests, Enhancement


Description

  • Refactored test functions to remove unnecessary try-except blocks.

  • Improved readability and maintainability of test cases.

  • Enhanced error handling in test runner by catching exceptions in main().

  • Ensured consistent import statements and streamlined test logic.


Changes walkthrough 📝

Relevant files
Tests
test_scheduler.py
Refactor and streamline test functions and error handling

src/praisonai/tests/unit/test_scheduler.py

  • Removed redundant try-except blocks from all test functions.
  • Simplified test logic for schedule parser, scheduler creation, config
    parsing, and CLI parsing.
  • Updated main() to handle exceptions per test and report failures.
  • Improved code readability and consistency throughout the test file.
  • +78/-101

    Need help?
  • Type /help how to ... in the comments thread for any questions about Qodo Merge usage.
  • Check out the documentation for more information.
  • Summary by CodeRabbit

    • Refactor
      • Streamlined test suites by centralizing exception handling and shifting from return-value-based to exception-based test result reporting.
      • Improved test result summaries and output formatting for better clarity.
      • Updated module path handling to use absolute paths in test scripts.
      • Simplified and clarified decorator enforcement tests, focusing on expected exception behavior.
      • Enhanced test isolation by mocking external dependencies and standardizing assertion usage.
    • New Features
      • Introduced a memory management module supporting various memory types including short-term, long-term, entity, and user memory, with graph memory support.
    • Chores
      • Updated GitHub Actions workflows to install additional dependencies for knowledge-related features.

    - Removed unnecessary try-except blocks in test functions for cleaner code.
    - Optimised the structure of test cases for better readability and maintainability.
    - Ensured consistent import statements and improved error handling in test execution.
    - Maintained functionality while adhering to the principle of minimal code change.
    @coderabbitai
    Copy link
    Copy Markdown
    Contributor

    coderabbitai Bot commented Jun 3, 2025

    Warning

    Rate limit exceeded

    @MervinPraison has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 6 minutes and 33 seconds before requesting another review.

    ⌛ How to resolve this issue?

    After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

    We recommend that you space out your commits to avoid hitting the rate limit.

    🚦 How do rate limits work?

    CodeRabbit enforces hourly rate limits for each developer per organization.

    Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

    Please see our FAQ for further information.

    📥 Commits

    Reviewing files that changed from the base of the PR and between c4be74f and 7741b4d.

    📒 Files selected for processing (2)
    • .github/workflows/python-package.yml (1 hunks)
    • .github/workflows/unittest.yml (1 hunks)

    Walkthrough

    The test suites for approval, scheduler, and decorator enforcement in the codebase were refactored to streamline error handling and reporting. Exception-based control flow replaces boolean return values in test functions, with centralized result aggregation in the main runners. Absolute path usage was standardized for module imports. Tests were enhanced with mocking, improved result validation, and simplified cleanup. A new memory module was introduced with support for multiple memory types and graph memory integration.

    Changes

    File(s) Change Summary
    src/praisonai/tests/unit/test_scheduler.py Removed try-except blocks from test functions; centralized error handling in main runner loop; no logic changes.
    src/praisonai/tests/unit/test_approval_agent_integration.py Improved path insertion to absolute; replaced boolean returns with assertions; enhanced result checks; added mocking; improved cleanup and dependency handling.
    src/praisonai/tests/unit/test_approval_basic.py Refactored to use assertion-based error handling; centralized result reporting; improved path handling; changed main() to return overall success boolean; enhanced async test handling.
    src/praisonai/tests/unit/test_decorator_enforcement.py Refactored test to use assertion and exception-based control; removed unnecessary imports; improved path logic; simplified approval callback and test execution.
    src/praisonai/tests/unit/test_approval_interactive.py Changed result checks from dict keys to substring checks; replaced boolean returns with assertions; improved path insertion; simplified file cleanup error handling.
    src/praisonai/tests/unit/test_decorator_simple.py Changed module path insertion to use absolute path instead of relative; replaced return-based success/failure with assertions; simplified main execution block.
    src/praisonai/tests/unit/test_graph_memory.py Added pytest and unittest.mock imports; changed module path insertion to absolute; added mocking for external dependencies; replaced return-based test success with assertions; updated test signatures with decorators.
    src/praisonai/tests/unit/test_ollama_fix.py Changed sys.path insertion to use absolute path instead of relative path.
    src/praisonai-agents/praisonaiagents/memory/init.py Added new memory module with support for short-term, long-term, entity, user, and quality-based memory; exposed Memory class as public API.
    .github/workflows/test-*.yml Added installation of praisonaiagents[knowledge] extra dependency in all test workflows.

    Sequence Diagram(s)

    sequenceDiagram
        participant TestRunner
        participant TestFunction
    
        TestRunner->>TestFunction: Call test function
        alt Test passes
            TestFunction-->>TestRunner: Completes without exception
            TestRunner->>TestRunner: Mark as passed
        else Test fails
            TestFunction--xTestRunner: Raises exception
            TestRunner->>TestRunner: Mark as failed, print error
        end
        TestRunner->>TestRunner: Aggregate and print summary
    
    Loading

    Possibly related PRs

    Poem

    In the warren where tests once hopped with care,
    Now exceptions leap freely through the air.
    No more returns of True or False,
    Just centralized counts for every waltz.
    With paths resolved and imports neat,
    This rabbit finds the changes sweet!
    🐇✨


    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.

    ❤️ Share
    🪧 Tips

    Chat

    There are 3 ways to chat with CodeRabbit:

    • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
      • I pushed a fix in commit <commit_id>, please review it.
      • Explain this complex logic.
      • Open a follow-up GitHub issue for this discussion.
    • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
      • @coderabbitai explain this code block.
      • @coderabbitai modularize this function.
    • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
      • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
      • @coderabbitai read src/utils.ts and explain its main purpose.
      • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
      • @coderabbitai help me debug CodeRabbit configuration file.

    Support

    Need 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)

    • @coderabbitai pause to pause the reviews on a PR.
    • @coderabbitai resume to resume the paused reviews.
    • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
    • @coderabbitai full review to do a full review from scratch and review all the files again.
    • @coderabbitai summary to regenerate the summary of the PR.
    • @coderabbitai generate docstrings to generate docstrings for this PR.
    • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
    • @coderabbitai resolve resolve all the CodeRabbit review comments.
    • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
    • @coderabbitai help to get help.

    Other keywords and placeholders

    • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
    • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
    • Add @coderabbitai anywhere in the PR title to generate the title automatically.

    CodeRabbit Configuration File (.coderabbit.yaml)

    • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
    • Please see the configuration documentation for more information.
    • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

    Documentation and Community

    • Visit our Documentation for detailed information on how to use CodeRabbit.
    • Join our Discord Community to get help, request features, and share feedback.
    • Follow us on X/Twitter for updates and announcements.

    @netlify
    Copy link
    Copy Markdown

    netlify Bot commented Jun 3, 2025

    Deploy Preview for praisonai canceled.

    Name Link
    🔨 Latest commit 7741b4d
    🔍 Latest deploy log https://app.netlify.com/projects/praisonai/deploys/683f136bdd342d0008430df5

    @qodo-code-review
    Copy link
    Copy Markdown

    PR Reviewer Guide 🔍

    Here are some key observations to aid the review process:

    ⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
    🧪 PR contains tests
    🔒 No security concerns identified
    ⚡ Recommended focus areas for review

    Error Handling

    The refactored code moves exception handling from individual test functions to the main() function. This improves code readability but might make it harder to identify which specific assertion or operation failed within a test.

    try:
        test()
        passed += 1
    except Exception as e:
        print(f"❌ Test failed: {e}")

    Copy link
    Copy Markdown
    Contributor

    @gemini-code-assist gemini-code-assist Bot left a comment

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    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! Gemini here, providing a summary of this pull request to help everyone get up to speed quickly.

    This PR, titled "refactor: streamline test functions in test_scheduler.py", aims to clean up and improve the structure of the unit tests within the test_scheduler.py file. The primary change involves removing redundant try...except blocks from individual test functions. Instead of each test handling its own exceptions and returning a boolean status, the responsibility for catching exceptions and reporting test failures is moved to the main test execution loop in the main() function. This refactoring makes the individual test functions simpler and more focused on the test logic itself, improving readability and maintainability.

    Highlights

    • Centralized Error Handling: Modified the main() function to wrap test execution in a try...except block, centralizing the logic for catching exceptions and reporting test failures.
    • Code Cleanup: Removed unnecessary return True/False statements from test functions, as the success/failure is now determined by whether an exception is raised during execution.

    Changelog

    • src/praisonai/tests/unit/test_scheduler.py
      • Removed try...except Exception blocks from test_schedule_parser (lines 17-41 -> 17-36).
      • Removed return True/False statements from test_schedule_parser.
      • Removed try...except Exception blocks from test_scheduler_creation (lines 45-66 -> 39-55).
      • Removed return True/False statements from test_scheduler_creation.
      • Removed try...except Exception blocks from test_config_file_parsing (lines 70-106 -> 58-89).
      • Removed return True/False statements from test_config_file_parsing.
      • Removed try...except Exception blocks from test_cli_argument_parsing (lines 110-125 -> 91-102).
      • Removed return True/False statements from test_cli_argument_parsing.
      • Modified the main() function loop to use a try...except Exception block around test execution (lines 144-147 -> 120-124).
    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.


    Tests run clean and fast,
    No try-excepts hold them back,
    Errors caught by main.

    Footnotes

    1. 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.

    @qodo-code-review
    Copy link
    Copy Markdown

    qodo-code-review Bot commented Jun 3, 2025

    PR Code Suggestions ✨

    Explore these optional code suggestions:

    CategorySuggestion                                                                                                                                    Impact
    Possible issue
    Fix incorrect path insertion

    The path insertion appears incorrect. The code is already in
    'src/praisonai/tests/unit', so adding 'src/praisonai' to the path creates a
    nested path that likely won't work. Use a relative path that points to the
    actual root directory.

    src/praisonai/tests/unit/test_scheduler.py [12-13]

     # Add the src directory to the path so we can import modules
    -sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src/praisonai'))
    +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../')))

    [To ensure code accuracy, apply this suggestion manually]

    Suggestion importance[1-10]: 8

    __

    Why: The current path insertion creates an incorrect nested path that would prevent proper imports. This fixes a critical import issue that could cause all tests to fail.

    Medium
    General
    Add exit code handling

    The main() function doesn't return an exit code, which is crucial for test
    runners to determine success or failure. Add a return statement that returns a
    non-zero exit code when tests fail.

    src/praisonai/tests/unit/test_scheduler.py [103-105]

     def main():
         """Run all tests."""
         print("Running PraisonAI Scheduler Tests")
    +    return_code = 0  # Success by default
    • Apply / Chat
    Suggestion importance[1-10]: 5

    __

    Why: Valid suggestion for proper exit code handling, but the improved_code is incomplete and doesn't show the full implementation needed to track and return test failure status.

    Low
    Improve exception handling specificity

    The exception handling is too broad. Catching all exceptions may mask important
    test failures like AssertionError. Consider using a more specific exception
    handler or re-raising certain exceptions to ensure test failures are properly
    reported.

    src/praisonai/tests/unit/test_scheduler.py [121-124]

             test()
             passed += 1
    +    except AssertionError as e:
    +        print(f"❌ Test assertion failed: {e}")
         except Exception as e:
    -        print(f"❌ Test failed: {e}")
    +        print(f"❌ Test error: {e}")
    • Apply / Chat
    Suggestion importance[1-10]: 4

    __

    Why: Minor improvement that provides more specific error reporting by distinguishing between AssertionError and other exceptions, though the current broad exception handling is functional.

    Low
    • Update

    @qodo-code-review
    Copy link
    Copy Markdown

    qodo-code-review Bot commented Jun 3, 2025

    CI Feedback 🧐

    (Feedback updated until commit 8921c08)

    A test triggered by this PR failed. Here is an AI-generated analysis of the failure:

    Action: build (3.10)

    Failed stage: Test with pytest [❌]

    Failed test name: test_agent_with_auto_approval

    Failure summary:

    The action failed because multiple tests couldn't import the approval module from the
    praisonaiagents package. The error "ModuleNotFoundError: No module named 'praisonaiagents.approval'"
    appears consistently across multiple test failures. This suggests that either:

    1. The approval module is missing from the codebase
    2. The module exists but wasn't properly
    installed or included in the package

    Additionally, there were failures related to the Memory class which couldn't be imported from
    praisonaiagents.memory, and a knowledge configuration test failed due to missing dependencies that
    should be installed with pip install "praisonaiagents[knowledge]".

    Relevant error logs:
    1:  ##[group]Operating System
    2:  Ubuntu
    ...
    
    1806:  tests/integration/crewai/test_crewai_basic.py::TestCrewAIIntegration::test_crewai_crew_workflow PASSED [ 11%]
    1807:  tests/integration/crewai/test_crewai_basic.py::TestCrewAIIntegration::test_crewai_config_validation PASSED [ 11%]
    1808:  tests/integration/crewai/test_crewai_basic.py::TestCrewAIIntegration::test_crewai_agent_collaboration PASSED [ 12%]
    1809:  tests/integration/test_base_url_api_base_fix.py::TestBaseUrlApiBaseMapping::test_llm_class_maps_base_url_to_api_base PASSED [ 13%]
    1810:  tests/integration/test_base_url_api_base_fix.py::TestBaseUrlApiBaseMapping::test_agent_with_llm_dict_base_url_parameter PASSED [ 14%]
    1811:  tests/integration/test_base_url_api_base_fix.py::TestBaseUrlApiBaseMapping::test_image_agent_base_url_consistency PASSED [ 15%]
    1812:  tests/integration/test_base_url_api_base_fix.py::TestBaseUrlApiBaseMapping::test_koboldcpp_specific_scenario PASSED [ 15%]
    1813:  tests/integration/test_base_url_api_base_fix.py::TestBaseUrlApiBaseMapping::test_litellm_documentation_example_compatibility PASSED [ 16%]
    1814:  tests/integration/test_base_url_api_base_fix.py::TestBaseUrlApiBaseMapping::test_backward_compatibility_with_api_base PASSED [ 17%]
    1815:  tests/integration/test_base_url_api_base_fix.py::TestBaseUrlApiBaseMapping::test_ollama_environment_variable_compatibility PASSED [ 18%]
    1816:  tests/integration/test_mcp_integration.py::TestMCPIntegration::test_mcp_server_connection PASSED [ 19%]
    1817:  tests/integration/test_mcp_integration.py::TestMCPIntegration::test_mcp_tool_execution PASSED [ 19%]
    1818:  tests/integration/test_mcp_integration.py::TestMCPIntegration::test_mcp_tool_wrapper PASSED [ 20%]
    1819:  tests/integration/test_mcp_integration.py::TestMCPIntegration::test_agent_with_mcp_tools PASSED [ 21%]
    1820:  tests/integration/test_mcp_integration.py::TestMCPIntegration::test_mcp_server_parameters PASSED [ 22%]
    1821:  tests/integration/test_mcp_integration.py::TestMCPIntegration::test_mcp_error_handling PASSED [ 23%]
    1822:  tests/integration/test_mcp_integration.py::TestMCPIntegration::test_mcp_multiple_servers PASSED [ 23%]
    ...
    
    1831:  tests/integration/test_rag_integration.py::TestRAGIntegration::test_knowledge_retrieval_simulation PASSED [ 30%]
    1832:  tests/integration/test_rag_integration.py::TestRAGIntegration::test_rag_agent_with_different_providers PASSED [ 31%]
    1833:  tests/integration/test_rag_integration.py::TestRAGIntegration::test_ollama_rag_integration PASSED [ 32%]
    1834:  tests/integration/test_rag_integration.py::TestRAGIntegration::test_rag_context_injection PASSED [ 33%]
    1835:  tests/integration/test_rag_integration.py::TestRAGIntegration::test_multi_document_rag PASSED [ 34%]
    1836:  tests/integration/test_rag_integration.py::TestRAGMemoryIntegration::test_rag_with_memory_persistence PASSED [ 34%]
    1837:  tests/integration/test_rag_integration.py::TestRAGMemoryIntegration::test_rag_knowledge_update PASSED [ 35%]
    1838:  tests/test_agents_playbook.py::TestPraisonAIFramework::test_main_with_autogen_framework PASSED [ 36%]
    1839:  tests/test_agents_playbook.py::TestPraisonAIFramework::test_main_with_built_in_tool PASSED [ 37%]
    1840:  tests/test_agents_playbook.py::TestPraisonAIFramework::test_main_with_custom_framework PASSED [ 38%]
    1841:  tests/test_agents_playbook.py::TestPraisonAIFramework::test_main_with_internet_search_tool PASSED [ 38%]
    1842:  tests/unit/agent/test_mini_agents_fix.py::test_context_processing PASSED [ 39%]
    1843:  tests/unit/agent/test_mini_agents_sequential.py::test_mini_agents_sequential_data_passing PASSED [ 40%]
    1844:  tests/unit/agent/test_type_casting.py::TestAgentTypeCasting::test_cast_arguments_already_correct_type PASSED [ 41%]
    1845:  tests/unit/agent/test_type_casting.py::TestAgentTypeCasting::test_cast_arguments_boolean_conversion PASSED [ 42%]
    1846:  tests/unit/agent/test_type_casting.py::TestAgentTypeCasting::test_cast_arguments_conversion_failure_graceful PASSED [ 42%]
    1847:  tests/unit/agent/test_type_casting.py::TestAgentTypeCasting::test_cast_arguments_float_conversion PASSED [ 43%]
    1848:  tests/unit/agent/test_type_casting.py::TestAgentTypeCasting::test_cast_arguments_integer_conversion PASSED [ 44%]
    1849:  tests/unit/agent/test_type_casting.py::TestAgentTypeCasting::test_cast_arguments_mixed_types PASSED [ 45%]
    1850:  tests/unit/agent/test_type_casting.py::TestAgentTypeCasting::test_cast_arguments_no_annotations PASSED [ 46%]
    1851:  tests/unit/agent/test_type_casting.py::TestAgentTypeCasting::test_cast_arguments_with_none_values PASSED [ 46%]
    1852:  tests/unit/test_approval_agent_integration.py::test_agent_tool_execution_with_approval SKIPPED [ 47%]
    1853:  tests/unit/test_approval_agent_integration.py::test_agent_with_auto_approval FAILED [ 48%]
    1854:  tests/unit/test_approval_agent_integration.py::test_agent_with_auto_denial FAILED [ 49%]
    1855:  tests/unit/test_approval_agent_integration.py::test_agent_python_code_execution FAILED [ 50%]
    1856:  tests/unit/test_approval_agent_integration.py::test_agent_file_operations FAILED [ 50%]
    1857:  tests/unit/test_approval_basic.py::test_imports FAILED                   [ 51%]
    1858:  tests/unit/test_approval_basic.py::test_approval_configuration FAILED    [ 52%]
    1859:  tests/unit/test_approval_basic.py::test_approval_decorator FAILED        [ 53%]
    1860:  tests/unit/test_approval_basic.py::test_tool_integration PASSED          [ 53%]
    1861:  tests/unit/test_approval_basic.py::test_approval_callback FAILED         [ 54%]
    1862:  tests/unit/test_approval_basic.py::test_agent_integration FAILED         [ 55%]
    1863:  tests/unit/test_approval_interactive.py::test_shell_command_approval SKIPPED [ 56%]
    1864:  tests/unit/test_approval_interactive.py::test_python_code_approval SKIPPED [ 57%]
    1865:  tests/unit/test_approval_interactive.py::test_file_operation_approval SKIPPED [ 57%]
    1866:  tests/unit/test_approval_interactive.py::test_auto_approval_callback FAILED [ 58%]
    1867:  tests/unit/test_approval_interactive.py::test_auto_denial_callback FAILED [ 59%]
    1868:  tests/unit/test_async_agents.py::TestAsyncAgents::test_async_tool_creation PASSED [ 60%]
    1869:  tests/unit/test_async_agents.py::TestAsyncAgents::test_async_task_execution PASSED [ 61%]
    1870:  tests/unit/test_async_agents.py::TestAsyncAgents::test_async_callback PASSED [ 61%]
    1871:  tests/unit/test_async_agents.py::TestAsyncAgents::test_async_agents_start PASSED [ 62%]
    1872:  tests/unit/test_async_agents.py::TestAsyncAgents::test_mixed_sync_async_tasks PASSED [ 63%]
    1873:  tests/unit/test_async_agents.py::TestAsyncAgents::test_workflow_async_execution PASSED [ 64%]
    1874:  tests/unit/test_async_agents.py::TestAsyncTools::test_async_search_tool PASSED [ 65%]
    1875:  tests/unit/test_async_agents.py::TestAsyncTools::test_async_tool_with_agent PASSED [ 65%]
    1876:  tests/unit/test_async_agents.py::TestAsyncTools::test_async_tool_error_handling PASSED [ 66%]
    1877:  tests/unit/test_async_agents.py::TestAsyncMemory::test_async_memory_operations PASSED [ 67%]
    1878:  tests/unit/test_context_management.py::test_context_management PASSED    [ 68%]
    1879:  tests/unit/test_core_agents.py::TestAgent::test_agent_creation PASSED    [ 69%]
    1880:  tests/unit/test_core_agents.py::TestAgent::test_agent_with_llm_dict PASSED [ 69%]
    1881:  tests/unit/test_core_agents.py::TestAgent::test_agent_with_tools PASSED  [ 70%]
    1882:  tests/unit/test_core_agents.py::TestAgent::test_agent_execution PASSED   [ 71%]
    1883:  tests/unit/test_core_agents.py::TestTask::test_task_creation PASSED      [ 72%]
    1884:  tests/unit/test_core_agents.py::TestTask::test_task_with_callback PASSED [ 73%]
    1885:  tests/unit/test_core_agents.py::TestTask::test_async_task_creation PASSED [ 73%]
    1886:  tests/unit/test_core_agents.py::TestPraisonAIAgents::test_agents_creation PASSED [ 74%]
    1887:  tests/unit/test_core_agents.py::TestPraisonAIAgents::test_sequential_execution PASSED [ 75%]
    1888:  tests/unit/test_core_agents.py::TestPraisonAIAgents::test_multiple_agents PASSED [ 76%]
    1889:  tests/unit/test_core_agents.py::TestLLMIntegration::test_llm_creation PASSED [ 76%]
    1890:  tests/unit/test_core_agents.py::TestLLMIntegration::test_llm_chat PASSED [ 77%]
    1891:  tests/unit/test_core_agents.py::TestLLMIntegration::test_llm_with_base_url PASSED [ 78%]
    1892:  tests/unit/test_database_config.py::test_database_config PASSED          [ 79%]
    1893:  tests/unit/test_decorator_enforcement.py::test_decorator_enforcement FAILED [ 80%]
    1894:  tests/unit/test_decorator_simple.py::test_improved_decorator FAILED      [ 80%]
    1895:  tests/unit/test_graph_memory.py::test_memory_import FAILED               [ 81%]
    1896:  tests/unit/test_graph_memory.py::test_knowledge_import PASSED            [ 82%]
    1897:  tests/unit/test_graph_memory.py::test_memory_config FAILED               [ 83%]
    1898:  tests/unit/test_graph_memory.py::test_knowledge_config FAILED            [ 84%]
    1899:  tests/unit/test_ollama_fix.py::test_ollama_provider_detection PASSED     [ 84%]
    1900:  tests/unit/test_ollama_fix.py::test_tool_call_parsing PASSED             [ 85%]
    1901:  tests/unit/test_ollama_fix.py::test_agent_tool_parameter_logic PASSED    [ 86%]
    1902:  tests/unit/test_scheduler.py::test_schedule_parser PASSED                [ 87%]
    1903:  tests/unit/test_scheduler.py::test_scheduler_creation PASSED             [ 88%]
    1904:  tests/unit/test_scheduler.py::test_config_file_parsing PASSED            [ 88%]
    1905:  tests/unit/test_scheduler.py::test_cli_argument_parsing PASSED           [ 89%]
    1906:  tests/unit/test_tools_and_ui.py::TestToolIntegration::test_custom_tool_creation PASSED [ 90%]
    1907:  tests/unit/test_tools_and_ui.py::TestToolIntegration::test_agent_with_multiple_tools PASSED [ 91%]
    1908:  tests/unit/test_tools_and_ui.py::TestToolIntegration::test_async_tools PASSED [ 92%]
    1909:  tests/unit/test_tools_and_ui.py::TestToolIntegration::test_tool_error_handling PASSED [ 92%]
    1910:  tests/unit/test_tools_and_ui.py::TestToolIntegration::test_duckduckgo_search_tool PASSED [ 93%]
    1911:  tests/unit/test_tools_and_ui.py::TestUIIntegration::test_gradio_app_config PASSED [ 94%]
    1912:  tests/unit/test_tools_and_ui.py::TestUIIntegration::test_streamlit_app_config PASSED [ 95%]
    1913:  tests/unit/test_tools_and_ui.py::TestUIIntegration::test_chainlit_app_config PASSED [ 96%]
    1914:  tests/unit/test_tools_and_ui.py::TestUIIntegration::test_ui_agent_wrapper PASSED [ 96%]
    1915:  tests/unit/test_tools_and_ui.py::TestUIIntegration::test_api_endpoint_simulation PASSED [ 97%]
    1916:  tests/unit/test_tools_and_ui.py::TestMultiModalTools::test_image_analysis_tool PASSED [ 98%]
    1917:  tests/unit/test_tools_and_ui.py::TestMultiModalTools::test_audio_processing_tool PASSED [ 99%]
    1918:  tests/unit/test_tools_and_ui.py::TestMultiModalTools::test_document_processing_tool PASSED [100%]
    1919:  =================================== FAILURES ===================================
    1920:  ________________________ test_agent_with_auto_approval _________________________
    1921:  /opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/unittest/mock.py:1248: in _dot_lookup
    1922:  return getattr(thing, comp)
    1923:  E   AttributeError: module 'praisonaiagents' has no attribute 'approval'
    1924:  During handling of the above exception, another exception occurred:
    ...
    
    1926:  with self.decoration_helper(patched,
    1927:  /opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/contextlib.py:135: in __enter__
    1928:  return next(self.gen)
    1929:  /opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/unittest/mock.py:1358: in decoration_helper
    1930:  arg = exit_stack.enter_context(patching)
    1931:  /opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/contextlib.py:492: in enter_context
    1932:  result = _cm_type.__enter__(cm)
    1933:  /opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/unittest/mock.py:1431: in __enter__
    1934:  self.target = self.getter()
    1935:  /opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/unittest/mock.py:1618: in <lambda>
    1936:  getter = lambda: _importer(target)
    1937:  /opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/unittest/mock.py:1261: in _importer
    1938:  thing = _dot_lookup(thing, comp, import_path)
    1939:  /opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/unittest/mock.py:1250: in _dot_lookup
    1940:  __import__(import_path)
    1941:  E   ModuleNotFoundError: No module named 'praisonaiagents.approval'
    1942:  _________________________ test_agent_with_auto_denial __________________________
    1943:  tests/unit/test_approval_agent_integration.py:132: in test_agent_with_auto_denial
    1944:  from praisonaiagents.approval import set_approval_callback, ApprovalDecision
    1945:  E   ModuleNotFoundError: No module named 'praisonaiagents.approval'
    1946:  During handling of the above exception, another exception occurred:
    1947:  tests/unit/test_approval_agent_integration.py:161: in test_agent_with_auto_denial
    1948:  assert False, f"Auto-denial test failed: {e}"
    1949:  E   AssertionError: Auto-denial test failed: No module named 'praisonaiagents.approval'
    1950:  E   assert False
    1951:  ----------------------------- Captured stdout call -----------------------------
    1952:  🚫 Testing Agent with Auto-Denial
    1953:  ========================================
    1954:  ❌ Auto-denial test failed: No module named 'praisonaiagents.approval'
    1955:  _______________________ test_agent_python_code_execution _______________________
    1956:  /opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/unittest/mock.py:1248: in _dot_lookup
    1957:  return getattr(thing, comp)
    1958:  E   AttributeError: module 'praisonaiagents' has no attribute 'approval'
    1959:  During handling of the above exception, another exception occurred:
    ...
    
    1961:  with self.decoration_helper(patched,
    1962:  /opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/contextlib.py:135: in __enter__
    1963:  return next(self.gen)
    1964:  /opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/unittest/mock.py:1358: in decoration_helper
    1965:  arg = exit_stack.enter_context(patching)
    1966:  /opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/contextlib.py:492: in enter_context
    1967:  result = _cm_type.__enter__(cm)
    1968:  /opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/unittest/mock.py:1431: in __enter__
    1969:  self.target = self.getter()
    1970:  /opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/unittest/mock.py:1618: in <lambda>
    1971:  getter = lambda: _importer(target)
    1972:  /opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/unittest/mock.py:1261: in _importer
    1973:  thing = _dot_lookup(thing, comp, import_path)
    1974:  /opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/unittest/mock.py:1250: in _dot_lookup
    1975:  __import__(import_path)
    1976:  E   ModuleNotFoundError: No module named 'praisonaiagents.approval'
    1977:  __________________________ test_agent_file_operations __________________________
    1978:  /opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/unittest/mock.py:1248: in _dot_lookup
    1979:  return getattr(thing, comp)
    1980:  E   AttributeError: module 'praisonaiagents' has no attribute 'approval'
    1981:  During handling of the above exception, another exception occurred:
    ...
    
    1983:  with self.decoration_helper(patched,
    1984:  /opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/contextlib.py:135: in __enter__
    1985:  return next(self.gen)
    1986:  /opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/unittest/mock.py:1358: in decoration_helper
    1987:  arg = exit_stack.enter_context(patching)
    1988:  /opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/contextlib.py:492: in enter_context
    1989:  result = _cm_type.__enter__(cm)
    1990:  /opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/unittest/mock.py:1431: in __enter__
    1991:  self.target = self.getter()
    1992:  /opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/unittest/mock.py:1618: in <lambda>
    1993:  getter = lambda: _importer(target)
    1994:  /opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/unittest/mock.py:1261: in _importer
    1995:  thing = _dot_lookup(thing, comp, import_path)
    1996:  /opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/unittest/mock.py:1250: in _dot_lookup
    1997:  __import__(import_path)
    1998:  E   ModuleNotFoundError: No module named 'praisonaiagents.approval'
    1999:  _________________________________ test_imports _________________________________
    2000:  tests/unit/test_approval_basic.py:18: in test_imports
    2001:  from praisonaiagents.approval import (
    2002:  E   ModuleNotFoundError: No module named 'praisonaiagents.approval'
    2003:  During handling of the above exception, another exception occurred:
    2004:  tests/unit/test_approval_basic.py:33: in test_imports
    2005:  assert False, f"Import failed: {e}"
    2006:  E   AssertionError: Import failed: No module named 'praisonaiagents.approval'
    2007:  E   assert False
    2008:  ----------------------------- Captured stdout call -----------------------------
    2009:  ❌ Import failed: No module named 'praisonaiagents.approval'
    2010:  _________________________ test_approval_configuration __________________________
    2011:  tests/unit/test_approval_basic.py:37: in test_approval_configuration
    2012:  from praisonaiagents.approval import (
    2013:  E   ModuleNotFoundError: No module named 'praisonaiagents.approval'
    2014:  ___________________________ test_approval_decorator ____________________________
    2015:  tests/unit/test_approval_basic.py:69: in test_approval_decorator
    2016:  from praisonaiagents.approval import require_approval, is_approval_required, get_risk_level, set_approval_callback, ApprovalDecision
    2017:  E   ModuleNotFoundError: No module named 'praisonaiagents.approval'
    2018:  ____________________________ test_approval_callback ____________________________
    2019:  tests/unit/test_approval_basic.py:149: in test_approval_callback
    2020:  from praisonaiagents.approval import request_approval, ApprovalDecision
    2021:  E   ModuleNotFoundError: No module named 'praisonaiagents.approval'
    2022:  ----------------------------- Captured stdout call -----------------------------
    2023:  📞 Testing approval callback system...
    2024:  ____________________________ test_agent_integration ____________________________
    2025:  tests/unit/test_approval_basic.py:204: in test_agent_integration
    2026:  from praisonaiagents.main import approval_callback
    2027:  E   ImportError: cannot import name 'approval_callback' from 'praisonaiagents.main' (/opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/site-packages/praisonaiagents/main.py)
    2028:  During handling of the above exception, another exception occurred:
    2029:  tests/unit/test_approval_basic.py:209: in test_agent_integration
    2030:  assert False, f"Agent integration test failed: {e}"
    2031:  E   AssertionError: Agent integration test failed: cannot import name 'approval_callback' from 'praisonaiagents.main' (/opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/site-packages/praisonaiagents/main.py)
    2032:  E   assert False
    2033:  ----------------------------- Captured stdout call -----------------------------
    2034:  🤖 Testing agent integration...
    2035:  ✅ Agent created with dangerous tools
    2036:  ⚠️ Agent integration test failed: cannot import name 'approval_callback' from 'praisonaiagents.main' (/opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/site-packages/praisonaiagents/main.py)
    2037:  _________________________ test_auto_approval_callback __________________________
    2038:  tests/unit/test_approval_interactive.py:154: in test_auto_approval_callback
    2039:  from praisonaiagents.approval import set_approval_callback, ApprovalDecision
    2040:  E   ModuleNotFoundError: No module named 'praisonaiagents.approval'
    2041:  During handling of the above exception, another exception occurred:
    2042:  tests/unit/test_approval_interactive.py:176: in test_auto_approval_callback
    2043:  assert False, f"Auto-approval test failed: {e}"
    2044:  E   AssertionError: Auto-approval test failed: No module named 'praisonaiagents.approval'
    2045:  E   assert False
    2046:  ----------------------------- Captured stdout call -----------------------------
    2047:  🤖 Testing Auto-Approval Callback
    2048:  ========================================
    2049:  ❌ Auto-approval test failed: No module named 'praisonaiagents.approval'
    2050:  __________________________ test_auto_denial_callback ___________________________
    2051:  tests/unit/test_approval_interactive.py:185: in test_auto_denial_callback
    2052:  from praisonaiagents.approval import set_approval_callback, ApprovalDecision
    2053:  E   ModuleNotFoundError: No module named 'praisonaiagents.approval'
    2054:  During handling of the above exception, another exception occurred:
    2055:  tests/unit/test_approval_interactive.py:207: in test_auto_denial_callback
    2056:  assert False, f"Auto-denial test failed: {e}"
    2057:  E   AssertionError: Auto-denial test failed: No module named 'praisonaiagents.approval'
    2058:  E   assert False
    2059:  ----------------------------- Captured stdout call -----------------------------
    2060:  🚫 Testing Auto-Denial Callback
    2061:  ========================================
    2062:  ❌ Auto-denial test failed: No module named 'praisonaiagents.approval'
    2063:  __________________________ test_decorator_enforcement __________________________
    2064:  tests/unit/test_decorator_enforcement.py:18: in test_decorator_enforcement
    2065:  from praisonaiagents.approval import require_approval, set_approval_callback, ApprovalDecision
    2066:  E   ModuleNotFoundError: No module named 'praisonaiagents.approval'
    2067:  During handling of the above exception, another exception occurred:
    2068:  tests/unit/test_decorator_enforcement.py:45: in test_decorator_enforcement
    2069:  assert False, f"Test failed: {e}"
    2070:  E   AssertionError: Test failed: No module named 'praisonaiagents.approval'
    2071:  E   assert False
    2072:  ----------------------------- Captured stdout call -----------------------------
    2073:  🧪 Testing Decorator Enforcement
    2074:  ===================================
    2075:  ❌ Test failed: No module named 'praisonaiagents.approval'
    2076:  ___________________________ test_improved_decorator ____________________________
    2077:  tests/unit/test_decorator_simple.py:18: in test_improved_decorator
    2078:  from praisonaiagents.approval import (
    2079:  E   ModuleNotFoundError: No module named 'praisonaiagents.approval'
    2080:  During handling of the above exception, another exception occurred:
    2081:  tests/unit/test_decorator_simple.py:92: in test_improved_decorator
    2082:  assert False, f"Test failed: {e}"
    2083:  E   AssertionError: Test failed: No module named 'praisonaiagents.approval'
    2084:  E   assert False
    2085:  ----------------------------- Captured stdout call -----------------------------
    2086:  🧪 Testing Improved Decorator with Context Management
    2087:  =======================================================
    2088:  ❌ Test failed: No module named 'praisonaiagents.approval'
    2089:  ----------------------------- Captured stderr call -----------------------------
    2090:  Traceback (most recent call last):
    2091:  File "/home/runner/work/PraisonAI/PraisonAI/src/praisonai/tests/unit/test_decorator_simple.py", line 18, in test_improved_decorator
    2092:  from praisonaiagents.approval import (
    2093:  ModuleNotFoundError: No module named 'praisonaiagents.approval'
    2094:  ______________________________ test_memory_import ______________________________
    2095:  tests/unit/test_graph_memory.py:17: in test_memory_import
    2096:  from praisonaiagents.memory import Memory
    2097:  E   ImportError: cannot import name 'Memory' from 'praisonaiagents.memory' (unknown location)
    2098:  During handling of the above exception, another exception occurred:
    2099:  tests/unit/test_graph_memory.py:21: in test_memory_import
    2100:  assert False, f"Failed to import Memory: {e}"
    2101:  E   AssertionError: Failed to import Memory: cannot import name 'Memory' from 'praisonaiagents.memory' (unknown location)
    2102:  E   assert False
    2103:  ----------------------------- Captured stdout call -----------------------------
    2104:  ❌ Failed to import Memory: cannot import name 'Memory' from 'praisonaiagents.memory' (unknown location)
    2105:  ______________________________ test_memory_config ______________________________
    2106:  tests/unit/test_graph_memory.py:36: in test_memory_config
    2107:  from praisonaiagents.memory import Memory
    2108:  E   ImportError: cannot import name 'Memory' from 'praisonaiagents.memory' (unknown location)
    2109:  During handling of the above exception, another exception occurred:
    2110:  tests/unit/test_graph_memory.py:77: in test_memory_config
    2111:  assert False, f"Memory configuration test failed: {e}"
    2112:  E   AssertionError: Memory configuration test failed: cannot import name 'Memory' from 'praisonaiagents.memory' (unknown location)
    2113:  E   assert False
    2114:  ----------------------------- Captured stdout call -----------------------------
    2115:  ❌ Memory configuration test failed: cannot import name 'Memory' from 'praisonaiagents.memory' (unknown location)
    2116:  ____________________________ test_knowledge_config _____________________________
    2117:  /opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/site-packages/praisonaiagents/knowledge/knowledge.py:73: in _deps
    2118:  from markitdown import MarkItDown
    2119:  E   ModuleNotFoundError: No module named 'markitdown'
    2120:  During handling of the above exception, another exception occurred:
    2121:  tests/unit/test_graph_memory.py:143: in test_knowledge_config
    2122:  final_config = knowledge_graph.config
    2123:  /opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/functools.py:981: in __get__
    2124:  val = self.func(instance)
    2125:  /opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/site-packages/praisonaiagents/knowledge/knowledge.py:98: in config
    2126:  "client": self._deps['chromadb'].PersistentClient(path=persist_dir),
    2127:  /opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/functools.py:981: in __get__
    2128:  val = self.func(instance)
    2129:  /opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/site-packages/praisonaiagents/knowledge/knowledge.py:80: in _deps
    2130:  raise ImportError(
    2131:  E   ImportError: Required packages not installed. Please install using: pip install "praisonaiagents[knowledge]"
    2132:  During handling of the above exception, another exception occurred:
    2133:  tests/unit/test_graph_memory.py:152: in test_knowledge_config
    2134:  assert False, f"Knowledge configuration test failed: {e}"
    2135:  E   AssertionError: Knowledge configuration test failed: Required packages not installed. Please install using: pip install "praisonaiagents[knowledge]"
    2136:  E   assert False
    2137:  ----------------------------- Captured stdout call -----------------------------
    2138:  ✅ Basic knowledge configuration works
    2139:  ✅ Graph knowledge configuration created
    2140:  ❌ Knowledge configuration test failed: Required packages not installed. Please install using: pip install "praisonaiagents[knowledge]"
    2141:  =============================== warnings summary ===============================
    2142:  ../../../../../../../opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/site-packages/pydantic/_internal/_config.py:295
    2143:  ../../../../../../../opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/site-packages/pydantic/_internal/_config.py:295
    2144:  /opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/site-packages/pydantic/_internal/_config.py:295: PydanticDeprecatedSince20: Support for class-based `config` is deprecated, use ConfigDict instead. Deprecated in Pydantic V2.0 to be removed in V3.0. See Pydantic V2 Migration Guide at https://errors.pydantic.dev/2.10/migration/
    2145:  warnings.warn(DEPRECATION_MESSAGE, DeprecationWarning)
    2146:  ../../../../../../../opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/site-packages/autogen/agentchat/contrib/swarm_agent.py:650
    2147:  /opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/site-packages/autogen/agentchat/contrib/swarm_agent.py:650: PydanticDeprecatedSince20: The `update_forward_refs` method is deprecated; use `model_rebuild` instead. Deprecated in Pydantic V2.0 to be removed in V3.0. See Pydantic V2 Migration Guide at https://errors.pydantic.dev/2.10/migration/
    2148:  SwarmResult.update_forward_refs()
    2149:  ../../../../../../../opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/site-packages/websockets/legacy/__init__.py:6
    2150:  /opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/site-packages/websockets/legacy/__init__.py:6: DeprecationWarning: websockets.legacy is deprecated; see https://websockets.readthedocs.io/en/stable/howto/upgrade.html for upgrade instructions
    2151:  warnings.warn(  # deprecated in 14.0 - 2024-11-09
    2152:  -- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
    2153:  =========================== short test summary info ============================
    2154:  FAILED tests/unit/test_approval_agent_integration.py::test_agent_with_auto_approval - ModuleNotFoundError: No module named 'praisonaiagents.approval'
    2155:  FAILED tests/unit/test_approval_agent_integration.py::test_agent_with_auto_denial - AssertionError: Auto-denial test failed: No module named 'praisonaiagents.approval'
    2156:  assert False
    2157:  FAILED tests/unit/test_approval_agent_integration.py::test_agent_python_code_execution - ModuleNotFoundError: No module named 'praisonaiagents.approval'
    2158:  FAILED tests/unit/test_approval_agent_integration.py::test_agent_file_operations - ModuleNotFoundError: No module named 'praisonaiagents.approval'
    2159:  FAILED tests/unit/test_approval_basic.py::test_imports - AssertionError: Import failed: No module named 'praisonaiagents.approval'
    2160:  assert False
    2161:  FAILED tests/unit/test_approval_basic.py::test_approval_configuration - ModuleNotFoundError: No module named 'praisonaiagents.approval'
    2162:  FAILED tests/unit/test_approval_basic.py::test_approval_decorator - ModuleNotFoundError: No module named 'praisonaiagents.approval'
    2163:  FAILED tests/unit/test_approval_basic.py::test_approval_callback - ModuleNotFoundError: No module named 'praisonaiagents.approval'
    2164:  FAILED tests/unit/test_approval_basic.py::test_agent_integration - AssertionError: Agent integration test failed: cannot import name 'approval_callback' from 'praisonaiagents.main' (/opt/hostedtoolcache/Python/3.10.17/x64/lib/python3.10/site-packages/praisonaiagents/main.py)
    2165:  assert False
    2166:  FAILED tests/unit/test_approval_interactive.py::test_auto_approval_callback - AssertionError: Auto-approval test failed: No module named 'praisonaiagents.approval'
    2167:  assert False
    2168:  FAILED tests/unit/test_approval_interactive.py::test_auto_denial_callback - AssertionError: Auto-denial test failed: No module named 'praisonaiagents.approval'
    2169:  assert False
    2170:  FAILED tests/unit/test_decorator_enforcement.py::test_decorator_enforcement - AssertionError: Test failed: No module named 'praisonaiagents.approval'
    2171:  assert False
    2172:  FAILED tests/unit/test_decorator_simple.py::test_improved_decorator - AssertionError: Test failed: No module named 'praisonaiagents.approval'
    2173:  assert False
    2174:  FAILED tests/unit/test_graph_memory.py::test_memory_import - AssertionError: Failed to import Memory: cannot import name 'Memory' from 'praisonaiagents.memory' (unknown location)
    2175:  assert False
    2176:  FAILED tests/unit/test_graph_memory.py::test_memory_config - AssertionError: Memory configuration test failed: cannot import name 'Memory' from 'praisonaiagents.memory' (unknown location)
    2177:  assert False
    2178:  FAILED tests/unit/test_graph_memory.py::test_knowledge_config - AssertionError: Knowledge configuration test failed: Required packages not installed. Please install using: pip install "praisonaiagents[knowledge]"
    2179:  assert False
    2180:  ====== 16 failed, 104 passed, 6 skipped, 4 warnings in 184.73s (0:03:04) =======
    2181:  ##[error]Process completed with exit code 1.
    2182:  Post job cleanup.
    

    Copy link
    Copy Markdown
    Contributor

    @gemini-code-assist gemini-code-assist Bot left a comment

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Code Review

    This pull request effectively refactors the test functions in test_scheduler.py by removing individual try-except blocks and centralizing error handling in the main test runner function. This is a good simplification and generally improves the clarity and maintainability of the test suite. The changes align well with the goal of making the tests cleaner.

    I've identified a couple of areas for further improvement, one related to resource management and another concerning import statement conventions.

    Summary of Findings

    • Resource Management: In test_config_file_parsing, a temporary file is created but might not be cleaned up if an assertion fails before the os.unlink() call. This could lead to an accumulation of temporary files. (Severity: high)
    • Import Statement Placement: Imports are consistently placed within individual test functions. While functional, this deviates from the common PEP 8 guideline of placing imports at the module level, which can affect the ease of identifying all module dependencies. (Severity: medium)

    Merge Readiness

    The pull request introduces valuable refactorings to the test suite, making it cleaner and centralizing error handling effectively. However, before merging, I recommend addressing the potential resource leak in test_config_file_parsing (a high-severity issue) to ensure robustness. The point about import placement is more of a stylistic consideration for discussion but adhering to PEP 8 could enhance long-term maintainability.

    As a reviewer, I am not authorized to approve pull requests. Please ensure these points are considered and that the code undergoes further review and approval as per your team's process before merging.

    Comment on lines +70 to +88
    with tempfile.NamedTemporaryFile(mode='w', suffix='.yaml', delete=False) as f:
    yaml.dump(config_data, f)
    config_file = f.name

    print("Testing config file parsing...")

    # Test loading the config
    with open(config_file, 'r') as f:
    loaded_config = yaml.safe_load(f)

    assert loaded_config['deployment']['schedule'] == 'daily'
    assert loaded_config['deployment']['provider'] == 'gcp'
    assert loaded_config['deployment']['max_retries'] == 5
    print(" ✓ Config file parsed correctly")

    # Clean up
    os.unlink(config_file)

    print("Config file parsing tests passed!")
    Copy link
    Copy Markdown
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    high

    The temporary file config_file created with tempfile.NamedTemporaryFile(delete=False) might not be cleaned up if an assertion fails (e.g., on lines 80-82). An assertion failure would cause the test function to exit, and os.unlink(config_file) on line 86 would be skipped, potentially leaving temporary files on the system.

    To ensure the temporary file is always cleaned up, would it be more robust to use a try...finally block? This would guarantee that os.unlink() is called even if assertions or other operations within the try block raise an exception.

        config_file_path = None  # Ensure it's defined for the finally block
        try:
            with tempfile.NamedTemporaryFile(mode='w', suffix='.yaml', delete=False) as tmp_f:
                yaml.dump(config_data, tmp_f)
                config_file_path = tmp_f.name
            
            print("Testing config file parsing...")
            
            # Test loading the config
            with open(config_file_path, 'r') as f_read:
                loaded_config = yaml.safe_load(f_read)
            
            assert loaded_config['deployment']['schedule'] == 'daily'
            assert loaded_config['deployment']['provider'] == 'gcp'
            assert loaded_config['deployment']['max_retries'] == 5
            print("  ✓ Config file parsed correctly")
            
        finally:
            # Clean up
            if config_file_path and os.path.exists(config_file_path):
                os.unlink(config_file_path)
        
        print("Config file parsing tests passed!")

    except Exception as e:
    print(f"ScheduleParser test failed: {e}")
    return False
    from praisonai.scheduler import ScheduleParser
    Copy link
    Copy Markdown
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    medium

    The PR description mentions 'Ensured consistent import statements,' and I observe that imports (like this one for ScheduleParser) are now consistently placed inside each test function. While this approach works, PEP 8, the standard style guide for Python code, generally recommends placing all imports at the top of the file, just after module comments and docstrings.1

    Module-level imports make it easier to see all of a module's dependencies at a glance. Was there a specific reason for choosing function-level imports in this test file (e.g., to manage slow-loading modules or to avoid circular dependencies)? If not, could we consider moving these imports to the module level to align more closely with common Python style conventions and potentially improve overall readability of dependencies?

    Style Guide References

    Footnotes

    1. PEP 8 advises that imports should usually be on separate lines and placed at the top of the file. Grouping standards are also defined: standard library, then related third-party, then local application/library specific imports.

    Copy link
    Copy Markdown
    Contributor

    @coderabbitai coderabbitai Bot left a comment

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Actionable comments posted: 0

    🧹 Nitpick comments (6)
    src/praisonai/tests/unit/test_scheduler.py (6)

    15-36: Good refactoring, but address formatting issues.

    The streamlined test function without try-except blocks improves readability and follows the centralized error handling approach. However, there are several trailing whitespace issues that should be cleaned up.

    Apply this diff to remove trailing whitespace:

    -from praisonai.scheduler import ScheduleParser
    -    
    +from praisonai.scheduler import ScheduleParser
    +
    -    ]
    -    
    +    ]
    +
    -        print(f"  ✓ '{expr}' -> {result} seconds")
    -    
    +        print(f"  ✓ '{expr}' -> {result} seconds")
    +
    🧰 Tools
    🪛 Pylint (3.3.7)

    [convention] 18-18: Trailing whitespace

    (C0303)


    [convention] 28-28: Trailing whitespace

    (C0303)


    [convention] 34-34: Trailing whitespace

    (C0303)


    [convention] 17-17: Import outside toplevel (praisonai.scheduler.ScheduleParser)

    (C0415)


    37-55: Effective refactoring with formatting cleanup needed.

    The test function is well-structured and the removal of internal exception handling is appropriate. The test logic correctly validates scheduler creation for different providers.

    Fix the trailing whitespace issues:

    -from praisonai.scheduler import create_scheduler, DeploymentScheduler
    -    
    +from praisonai.scheduler import create_scheduler, DeploymentScheduler
    +
    -    print("Testing scheduler creation...")
    -    
    +    print("Testing scheduler creation...")
    +
    -        print("  ✓ Default scheduler created")
    -    
    +        print("  ✓ Default scheduler created")
    +
    -        print(f"  ✓ {provider} scheduler created")
    -    
    +        print(f"  ✓ {provider} scheduler created")
    +
    🧰 Tools
    🪛 Pylint (3.3.7)

    [convention] 40-40: Trailing whitespace

    (C0303)


    [convention] 42-42: Trailing whitespace

    (C0303)


    [convention] 47-47: Trailing whitespace

    (C0303)


    [convention] 53-53: Trailing whitespace

    (C0303)


    [convention] 39-39: Import outside toplevel (praisonai.scheduler.create_scheduler, praisonai.scheduler.DeploymentScheduler)

    (C0415)


    56-89: Well-refactored function with minor improvements needed.

    The test logic is comprehensive and the streamlined approach without internal exception handling is good. However, there are formatting and best practice issues to address.

    Fix trailing whitespace and specify encoding for file operations:

    -    }
    -    
    +    }
    +
    -        config_file = f.name
    -    
    +        config_file = f.name
    +
    -    print("Testing config file parsing...")
    -    
    +    print("Testing config file parsing...")
    +
    -    # Test loading the config
    -    with open(config_file, 'r') as f:
    +    # Test loading the config
    +    with open(config_file, 'r', encoding='utf-8') as f:
    -        print("  ✓ Config file parsed correctly")
    -    
    +        print("  ✓ Config file parsed correctly")
    +
    -    os.unlink(config_file)
    -    
    +    os.unlink(config_file)
    +
    🧰 Tools
    🪛 Pylint (3.3.7)

    [convention] 69-69: Trailing whitespace

    (C0303)


    [convention] 73-73: Trailing whitespace

    (C0303)


    [convention] 75-75: Trailing whitespace

    (C0303)


    [convention] 79-79: Trailing whitespace

    (C0303)


    [convention] 84-84: Trailing whitespace

    (C0303)


    [convention] 87-87: Trailing whitespace

    (C0303)


    [warning] 77-77: Using open without explicitly specifying an encoding

    (W1514)


    90-102: Refactoring complete, but consider expanding test coverage.

    The streamlined function is good, but the test coverage is quite minimal - it only tests basic CLI instantiation.

    Fix trailing whitespace and consider expanding the test:

    -from praisonai.cli import PraisonAI
    -    
    +from praisonai.cli import PraisonAI
    +
    -    print("Testing CLI argument parsing...")
    -    
    +    print("Testing CLI argument parsing...")
    +
    -    print("  ✓ PraisonAI CLI instance created")
    -    
    +    print("  ✓ PraisonAI CLI instance created")
    +

    Consider adding more comprehensive CLI argument testing:

    def test_cli_argument_parsing():
        """Test CLI argument parsing for scheduling options."""
        from praisonai.cli import PraisonAI
        
        print("Testing CLI argument parsing...")
        
        # Test basic CLI instantiation
        praison = PraisonAI()
        assert praison is not None
        print("  ✓ PraisonAI CLI instance created")
        
        # TODO: Add tests for actual CLI argument parsing
        # e.g., test different command line arguments, scheduling options, etc.
        
        print("CLI argument parsing tests passed!")
    🧰 Tools
    🪛 Pylint (3.3.7)

    [convention] 93-93: Trailing whitespace

    (C0303)


    [convention] 95-95: Trailing whitespace

    (C0303)


    [convention] 100-100: Trailing whitespace

    (C0303)


    [convention] 92-92: Import outside toplevel (praisonai.cli.PraisonAI)

    (C0415)


    118-125: Excellent centralized error handling approach with room for improvement.

    The centralized exception handling is a significant improvement over individual try-catch blocks in each test function. However, the current implementation could be enhanced for better debugging.

    Consider making the exception handling more specific and informative:

            try:
                test()
                passed += 1
    -        except Exception as e:
    -            print(f"❌ Test failed: {e}")
    +        except AssertionError as e:
    +            print(f"❌ {test.__name__} assertion failed: {e}")
    +        except ImportError as e:
    +            print(f"❌ {test.__name__} import failed: {e}")
    +        except Exception as e:
    +            print(f"❌ {test.__name__} failed with unexpected error: {type(e).__name__}: {e}")

    This provides more specific error information while maintaining the centralized approach.

    🧰 Tools
    🪛 Pylint (3.3.7)

    [convention] 125-125: Trailing whitespace

    (C0303)


    [warning] 123-123: Catching too general exception Exception

    (W0718)


    17-17: Consider consolidating imports for better code organization.

    The imports inside test functions provide isolation but go against Python conventions. For better maintainability, consider moving these imports to the top level.

    Move the imports to the top of the file:

    +from praisonai.scheduler import ScheduleParser, create_scheduler, DeploymentScheduler
    +from praisonai.cli import PraisonAI
    +
     def test_schedule_parser():
         """Test the schedule parser functionality."""
    -    from praisonai.scheduler import ScheduleParser
         
     def test_scheduler_creation():
         """Test scheduler creation and basic functionality."""
    -    from praisonai.scheduler import create_scheduler, DeploymentScheduler
         
     def test_cli_argument_parsing():
         """Test CLI argument parsing for scheduling options."""
    -    from praisonai.cli import PraisonAI

    However, if test isolation is a priority, the current approach is acceptable.

    Also applies to: 39-39, 92-92

    🧰 Tools
    🪛 Pylint (3.3.7)

    [convention] 17-17: Import outside toplevel (praisonai.scheduler.ScheduleParser)

    (C0415)

    📜 Review details

    Configuration used: CodeRabbit UI
    Review profile: CHILL
    Plan: Pro

    📥 Commits

    Reviewing files that changed from the base of the PR and between 27ed2e8 and 296a45b.

    📒 Files selected for processing (1)
    • src/praisonai/tests/unit/test_scheduler.py (2 hunks)
    🧰 Additional context used
    🪛 Pylint (3.3.7)
    src/praisonai/tests/unit/test_scheduler.py

    [convention] 18-18: Trailing whitespace

    (C0303)


    [convention] 28-28: Trailing whitespace

    (C0303)


    [convention] 34-34: Trailing whitespace

    (C0303)


    [convention] 40-40: Trailing whitespace

    (C0303)


    [convention] 42-42: Trailing whitespace

    (C0303)


    [convention] 47-47: Trailing whitespace

    (C0303)


    [convention] 53-53: Trailing whitespace

    (C0303)


    [convention] 69-69: Trailing whitespace

    (C0303)


    [convention] 73-73: Trailing whitespace

    (C0303)


    [convention] 75-75: Trailing whitespace

    (C0303)


    [convention] 79-79: Trailing whitespace

    (C0303)


    [convention] 84-84: Trailing whitespace

    (C0303)


    [convention] 87-87: Trailing whitespace

    (C0303)


    [convention] 93-93: Trailing whitespace

    (C0303)


    [convention] 95-95: Trailing whitespace

    (C0303)


    [convention] 100-100: Trailing whitespace

    (C0303)


    [convention] 17-17: Import outside toplevel (praisonai.scheduler.ScheduleParser)

    (C0415)


    [convention] 39-39: Import outside toplevel (praisonai.scheduler.create_scheduler, praisonai.scheduler.DeploymentScheduler)

    (C0415)


    [warning] 77-77: Using open without explicitly specifying an encoding

    (W1514)


    [convention] 92-92: Import outside toplevel (praisonai.cli.PraisonAI)

    (C0415)


    [warning] 123-123: Catching too general exception Exception

    (W0718)

    - Simplified test function structure for improved clarity and maintainability.
    - Removed redundant error handling to streamline code execution.
    - Ensured adherence to minimal code change principles while maintaining functionality.
    Copy link
    Copy Markdown
    Contributor

    @coderabbitai coderabbitai Bot left a comment

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Actionable comments posted: 23

    🔭 Outside diff range comments (1)
    src/praisonai/tests/unit/test_graph_memory.py (1)

    134-169: 🛠️ Refactor suggestion

    Consider migrating to unittest framework for better integration.

    While the current test runner works, consider using the standard unittest framework for better integration with test discovery and reporting tools, especially given the PR objective of streamlining test functions.

    Here's how you could refactor to use unittest:

    import unittest
    import sys
    import os
    
    class TestGraphMemory(unittest.TestCase):
        
        @classmethod
        def setUpClass(cls):
            """Set up the Python path for imports"""
            project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..', '..'))
            sys.path.insert(0, project_root)
        
        def test_memory_import(self):
            """Test that Memory class can be imported and initialized"""
            try:
                from praisonaiagents.memory import Memory
                self.assertIsNotNone(Memory)
            except ImportError as e:
                self.skipTest(f"Memory import failed: {e}")
        
        def test_knowledge_import(self):
            """Test that Knowledge class can be imported"""
            try:
                from praisonaiagents.knowledge import Knowledge
                self.assertIsNotNone(Knowledge)
            except ImportError as e:
                self.skipTest(f"Knowledge import failed: {e}")
        
        # ... other test methods
    
    if __name__ == "__main__":
        unittest.main()

    This approach would align better with the PR's goal of streamlining test functions and provide better integration with CI/CD pipelines.

    🧰 Tools
    🪛 Pylint (3.3.7)

    [convention] 137-137: Trailing whitespace

    (C0303)


    [convention] 140-140: Trailing whitespace

    (C0303)


    [convention] 144-144: Trailing whitespace

    (C0303)


    [convention] 147-147: Trailing whitespace

    (C0303)


    [convention] 155-155: Trailing whitespace

    (C0303)


    [convention] 157-157: Trailing whitespace

    (C0303)


    [convention] 162-162: Trailing whitespace

    (C0303)


    [convention] 134-134: Missing function or method docstring

    (C0116)


    [warning] 153-153: Catching too general exception Exception

    (W0718)

    🧹 Nitpick comments (16)
    src/praisonai/tests/unit/test_graph_memory.py (6)

    12-21: Improve import testing approach and handle unused imports.

    The current approach works but could be more robust. Consider using importlib.util.find_spec as suggested by static analysis, and the import inside the function is flagged as unused.

     def test_memory_import():
         """Test that Memory class can be imported and initialized"""
         try:
    -        from praisonaiagents.memory import Memory
    +        import importlib.util
    +        spec = importlib.util.find_spec('praisonaiagents.memory')
    +        if spec is None:
    +            raise ImportError("praisonaiagents.memory module not found")
    +        
    +        from praisonaiagents.memory import Memory
    +        # Actually use the imported class to avoid unused import warning
    +        assert Memory is not None
             print("✅ Memory class imported successfully")
             return True
         except ImportError as e:
             print(f"❌ Failed to import Memory: {e}")
             return False
    🧰 Tools
    🪛 Ruff (0.11.9)

    15-15: praisonaiagents.memory.Memory imported but unused; consider using importlib.util.find_spec to test for availability

    (F401)

    🪛 Pylint (3.3.7)

    [convention] 15-15: Import outside toplevel (praisonaiagents.memory.Memory)

    (C0415)


    [warning] 15-15: Unused Memory imported from praisonaiagents.memory

    (W0611)


    22-31: Apply consistent import testing approach.

    Same improvement as the Memory import test.

     def test_knowledge_import():
         """Test that Knowledge class can be imported"""
         try:
    +        import importlib.util
    +        spec = importlib.util.find_spec('praisonaiagents.knowledge')
    +        if spec is None:
    +            raise ImportError("praisonaiagents.knowledge module not found")
    +        
             from praisonaiagents.knowledge import Knowledge
    +        # Actually use the imported class to avoid unused import warning
    +        assert Knowledge is not None
             print("✅ Knowledge class imported successfully")
             return True
         except ImportError as e:
             print(f"❌ Failed to import Knowledge: {e}")
             return False
    🧰 Tools
    🪛 Ruff (0.11.9)

    25-25: praisonaiagents.knowledge.Knowledge imported but unused; consider using importlib.util.find_spec to test for availability

    (F401)

    🪛 Pylint (3.3.7)

    [convention] 25-25: Import outside toplevel (praisonaiagents.knowledge.Knowledge)

    (C0415)


    [warning] 25-25: Unused Knowledge imported from praisonaiagents.knowledge

    (W0611)


    48-49: Address unused variable assignment.

    The memory variable is assigned but never used, which static analysis correctly flags.

    -        memory = Memory(config=basic_config, verbose=1)
    +        Memory(config=basic_config, verbose=1)
             print("✅ Basic memory configuration works")

    Alternatively, if you want to validate the instance:

             memory = Memory(config=basic_config, verbose=1)
    +        assert memory is not None
             print("✅ Basic memory configuration works")
    🧰 Tools
    🪛 Ruff (0.11.9)

    48-48: Local variable memory is assigned to but never used

    Remove assignment to unused variable memory

    (F841)

    🪛 Pylint (3.3.7)

    [warning] 48-48: Unused variable 'memory'

    (W0612)


    66-73: Make exception handling more specific.

    The broad Exception catch could mask specific issues. Consider being more specific about expected exceptions.

             try:
                 memory_graph = Memory(config=graph_config, verbose=1)
                 print("✅ Graph memory configuration initialized")
                 print(f"   Graph enabled: {getattr(memory_graph, 'graph_enabled', False)}")
    -        except Exception as e:
    +        except (ImportError, ConnectionError, AttributeError) as e:
                 print(f"⚠️  Graph memory not available (expected): {e}")
                 print("   This is normal if graph dependencies are not installed")
    🧰 Tools
    🪛 Pylint (3.3.7)

    [convention] 73-73: Trailing whitespace

    (C0303)


    [warning] 70-70: Catching too general exception Exception

    (W0718)


    96-98: Address unused variable assignment.

    Similar to the memory test, the knowledge variable is assigned but never used.

    -        knowledge = Knowledge(config=basic_config, verbose=0)
    +        Knowledge(config=basic_config, verbose=0)
             print("✅ Basic knowledge configuration works")
    🧰 Tools
    🪛 Ruff (0.11.9)

    96-96: Local variable knowledge is assigned to but never used

    Remove assignment to unused variable knowledge

    (F841)

    🪛 Pylint (3.3.7)

    [convention] 98-98: Trailing whitespace

    (C0303)


    [warning] 96-96: Unused variable 'knowledge'

    (W0612)


    1-169: Address formatting issues and improve code consistency.

    The file has multiple trailing whitespace issues flagged by static analysis. Consider running a formatter to clean these up.

    Run the following command to fix formatting issues:

    #!/bin/bash
    # Remove trailing whitespace and ensure consistent formatting
    sed -i 's/[[:space:]]*$//' src/praisonai/tests/unit/test_graph_memory.py

    Additionally, consider adding type hints and improving docstrings for better code documentation:

    def test_memory_import() -> bool:
        """
        Test that Memory class can be imported and initialized.
        
        Returns:
            bool: True if import successful, False otherwise
        """
    🧰 Tools
    🪛 Ruff (0.11.9)

    15-15: praisonaiagents.memory.Memory imported but unused; consider using importlib.util.find_spec to test for availability

    (F401)


    25-25: praisonaiagents.knowledge.Knowledge imported but unused; consider using importlib.util.find_spec to test for availability

    (F401)


    48-48: Local variable memory is assigned to but never used

    Remove assignment to unused variable memory

    (F841)


    96-96: Local variable knowledge is assigned to but never used

    Remove assignment to unused variable knowledge

    (F841)

    🪛 Pylint (3.3.7)

    [convention] 36-36: Trailing whitespace

    (C0303)


    [convention] 47-47: Trailing whitespace

    (C0303)


    [convention] 50-50: Trailing whitespace

    (C0303)


    [convention] 65-65: Trailing whitespace

    (C0303)


    [convention] 73-73: Trailing whitespace

    (C0303)


    [convention] 75-75: Trailing whitespace

    (C0303)


    [convention] 84-84: Trailing whitespace

    (C0303)


    [convention] 95-95: Trailing whitespace

    (C0303)


    [convention] 98-98: Trailing whitespace

    (C0303)


    [convention] 117-117: Trailing whitespace

    (C0303)


    [convention] 120-120: Trailing whitespace

    (C0303)


    [convention] 127-127: Trailing whitespace

    (C0303)


    [convention] 129-129: Trailing whitespace

    (C0303)


    [convention] 137-137: Trailing whitespace

    (C0303)


    [convention] 140-140: Trailing whitespace

    (C0303)


    [convention] 144-144: Trailing whitespace

    (C0303)


    [convention] 147-147: Trailing whitespace

    (C0303)


    [convention] 155-155: Trailing whitespace

    (C0303)


    [convention] 157-157: Trailing whitespace

    (C0303)


    [convention] 162-162: Trailing whitespace

    (C0303)


    [convention] 15-15: Import outside toplevel (praisonaiagents.memory.Memory)

    (C0415)


    [warning] 15-15: Unused Memory imported from praisonaiagents.memory

    (W0611)


    [convention] 25-25: Import outside toplevel (praisonaiagents.knowledge.Knowledge)

    (C0415)


    [warning] 25-25: Unused Knowledge imported from praisonaiagents.knowledge

    (W0611)


    [warning] 76-76: Catching too general exception Exception

    (W0718)


    [error] 35-35: Unable to import 'praisonaiagents.memory'

    (E0401)


    [convention] 35-35: Import outside toplevel (praisonaiagents.memory.Memory)

    (C0415)


    [warning] 70-70: Catching too general exception Exception

    (W0718)


    [warning] 48-48: Unused variable 'memory'

    (W0612)


    [warning] 130-130: Catching too general exception Exception

    (W0718)


    [error] 83-83: Unable to import 'praisonaiagents.knowledge'

    (E0401)


    [convention] 83-83: Import outside toplevel (praisonaiagents.knowledge.Knowledge)

    (C0415)


    [warning] 96-96: Unused variable 'knowledge'

    (W0612)


    [convention] 134-134: Missing function or method docstring

    (C0116)


    [warning] 153-153: Catching too general exception Exception

    (W0718)

    🪛 GitHub Actions: Core Tests

    [error] 1-1: test_memory_import failed: Failed to import Memory: cannot import name 'Memory' from 'praisonaiagents.memory' (unknown location).


    [error] 1-1: test_knowledge_import failed: Expected None, but test returned True. Assertion error likely due to improper use of return instead of assert.


    [error] 1-1: test_memory_config failed: Memory configuration test failed: cannot import name 'Memory' from 'praisonaiagents.memory' (unknown location).


    [error] 1-1: test_knowledge_config failed: Knowledge configuration test failed: Required packages not installed. Please install using: pip install "praisonaiagents[knowledge]".

    src/praisonai/tests/unit/test_decorator_enforcement.py (2)

    35-35: Remove unused variable

    The result variable is assigned but never used, as correctly identified by static analysis.

    -            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 result is assigned to but never used

    Remove assignment to unused variable result

    (F841)

    🪛 Pylint (3.3.7)

    [warning] 35-35: Unused variable 'result'

    (W0612)


    35-35: Remove unused variable assignment.

    The result variable is assigned but never used, as flagged by static analysis.

    -            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 result is assigned to but never used

    Remove assignment to unused variable result

    (F841)

    🪛 Pylint (3.3.7)

    [warning] 35-35: Unused variable 'result'

    (W0612)

    src/praisonai/tests/unit/test_decorator_simple.py (1)

    36-36: Remove unused function parameters

    The callback functions have unused parameters that trigger static analysis warnings.

    -        def auto_deny(function_name, arguments, risk_level):
    +        def auto_deny(function_name, _arguments, _risk_level):
                 return ApprovalDecision(approved=False, reason='Test denial')
    
    -        def auto_approve(function_name, arguments, risk_level):
    +        def auto_approve(function_name, _arguments, _risk_level):
                 return ApprovalDecision(approved=True, reason='Test approval')

    Also applies to: 63-63

    🧰 Tools
    🪛 Pylint (3.3.7)

    [warning] 36-36: Unused argument 'function_name'

    (W0613)


    [warning] 36-36: Unused argument 'arguments'

    (W0613)


    [warning] 36-36: Unused argument 'risk_level'

    (W0613)

    src/praisonai/tests/unit/test_approval_basic.py (1)

    100-100: Remove unused tool instance variables

    Tool instances are created but never used, as identified by static analysis.

    -        shell_tools = ShellTools()
    +        ShellTools()  # Just verify instantiation works
             
             # Check if execute_command requires approval
             from praisonaiagents.approval import is_approval_required
    
    -        python_tools = PythonTools()
    +        PythonTools()  # Just verify instantiation works
    
    -        file_tools = FileTools()
    +        FileTools()  # Just verify instantiation works

    Also applies to: 117-117, 129-129

    🧰 Tools
    🪛 Ruff (0.11.9)

    100-100: Local variable shell_tools is assigned to but never used

    Remove assignment to unused variable shell_tools

    (F841)

    🪛 Pylint (3.3.7)

    [warning] 100-100: Unused variable 'shell_tools'

    (W0612)

    src/praisonai/tests/unit/test_approval_agent_integration.py (4)

    11-11: Remove unused asyncio import

    The asyncio module is imported but never used in this file.

    -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)


    34-34: Fix unused callback function parameters

    Multiple callback functions have unused parameters that should be prefixed with underscore to indicate they're intentionally unused.

    -            def auto_approve_callback(function_name, arguments, risk_level):
    +            def auto_approve_callback(function_name, _arguments, _risk_level):
                     return ApprovalDecision(approved=True, reason="Auto-approved for CI")
    
    -        def auto_approve_callback(function_name, arguments, risk_level):
    +        def auto_approve_callback(function_name, _arguments, _risk_level):
    
    -        def auto_deny_callback(function_name, arguments, risk_level):
    +        def auto_deny_callback(function_name, _arguments, _risk_level):
    
    -        def auto_approve_callback(function_name, arguments, risk_level):
    +        def auto_approve_callback(function_name, _arguments, _risk_level):
    
    -        def auto_approve_callback(function_name, arguments, risk_level):
    +        def auto_approve_callback(function_name, _arguments, _risk_level):

    Also applies to: 77-77, 117-117, 159-159, 205-205

    🧰 Tools
    🪛 Pylint (3.3.7)

    [warning] 34-34: Unused argument 'function_name'

    (W0613)


    [warning] 34-34: Unused argument 'arguments'

    (W0613)


    [warning] 34-34: Unused argument 'risk_level'

    (W0613)


    11-11: Remove unused asyncio import.

    Static analysis correctly identifies that asyncio is imported but never used.

     import sys
     import os
    -import asyncio
     import pytest
    🧰 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)


    247-316: Consider restructuring main function for pytest compatibility.

    The interactive main function is useful for manual testing but doesn't integrate well with pytest's test discovery and execution model.

    Consider splitting this into separate test functions that can be run independently by pytest:

    def test_auto_approval():
        """Pytest-compatible version of auto-approval test."""
        # Extract the core logic from test_agent_with_auto_approval()
        pass
    
    def test_auto_denial():
        """Pytest-compatible version of auto-denial test."""
        # Extract the core logic from test_agent_with_auto_denial()
        pass
    
    @pytest.mark.skipif(os.getenv("ASK_USER") != "1", reason="requires user interaction")
    def test_interactive_approval():
        """Interactive test that requires user input."""
        # Extract the core logic from test_agent_tool_execution_with_approval()
        pass

    This allows pytest to discover and run these tests individually while maintaining the interactive main function for manual testing.

    🧰 Tools
    🪛 Pylint (3.3.7)

    [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)


    [warning] 314-314: Catching too general exception Exception

    (W0718)


    [refactor] 247-247: Too many statements (57/50)

    (R0915)

    src/praisonai/tests/unit/test_approval_interactive.py (2)

    11-11: Remove unused import.

    The asyncio module is imported but never used in the file.

    -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)


    287-287: Add missing final newline.

    The file is missing a final newline as required by Python style guidelines.

     if __name__ == "__main__":
    -    main() 
    +    main()
    
    🧰 Tools
    🪛 Pylint (3.3.7)

    [convention] 287-287: Final newline missing

    (C0304)

    📜 Review details

    Configuration used: CodeRabbit UI
    Review profile: CHILL
    Plan: Pro

    📥 Commits

    Reviewing files that changed from the base of the PR and between 296a45b and 9b6b9b2.

    📒 Files selected for processing (6)
    • 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)
    • src/praisonai/tests/unit/test_graph_memory.py (1 hunks)
    🧰 Additional context used
    🧬 Code Graph Analysis (2)
    src/praisonai/tests/unit/test_decorator_enforcement.py (2)
    src/praisonai-agents/praisonaiagents/tools/shell_tools.py (1)
    • ShellTools (17-228)
    src/praisonai/tests/unit/test_decorator_simple.py (1)
    • auto_deny (36-37)
    src/praisonai/tests/unit/test_decorator_simple.py (1)
    src/praisonai/tests/unit/test_decorator_enforcement.py (1)
    • auto_deny (23-25)
    🪛 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_graph_memory.py

    15-15: praisonaiagents.memory.Memory imported but unused; consider using importlib.util.find_spec to test for availability

    (F401)


    25-25: praisonaiagents.knowledge.Knowledge imported but unused; consider using importlib.util.find_spec to test for availability

    (F401)


    48-48: Local variable memory is assigned to but never used

    Remove assignment to unused variable memory

    (F841)


    96-96: Local variable knowledge is assigned to but never used

    Remove assignment to unused variable knowledge

    (F841)

    src/praisonai/tests/unit/test_approval_agent_integration.py

    11-11: asyncio imported but unused

    Remove unused import: asyncio

    (F401)

    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_interactive.py

    11-11: asyncio imported but unused

    Remove unused import: asyncio

    (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_graph_memory.py

    [convention] 36-36: Trailing whitespace

    (C0303)


    [convention] 47-47: Trailing whitespace

    (C0303)


    [convention] 50-50: Trailing whitespace

    (C0303)


    [convention] 65-65: Trailing whitespace

    (C0303)


    [convention] 73-73: Trailing whitespace

    (C0303)


    [convention] 75-75: Trailing whitespace

    (C0303)


    [convention] 84-84: Trailing whitespace

    (C0303)


    [convention] 95-95: Trailing whitespace

    (C0303)


    [convention] 98-98: Trailing whitespace

    (C0303)


    [convention] 117-117: Trailing whitespace

    (C0303)


    [convention] 120-120: Trailing whitespace

    (C0303)


    [convention] 127-127: Trailing whitespace

    (C0303)


    [convention] 129-129: Trailing whitespace

    (C0303)


    [convention] 137-137: Trailing whitespace

    (C0303)


    [convention] 140-140: Trailing whitespace

    (C0303)


    [convention] 144-144: Trailing whitespace

    (C0303)


    [convention] 147-147: Trailing whitespace

    (C0303)


    [convention] 155-155: Trailing whitespace

    (C0303)


    [convention] 157-157: Trailing whitespace

    (C0303)


    [convention] 162-162: Trailing whitespace

    (C0303)


    [convention] 15-15: Import outside toplevel (praisonaiagents.memory.Memory)

    (C0415)


    [warning] 15-15: Unused Memory imported from praisonaiagents.memory

    (W0611)


    [convention] 25-25: Import outside toplevel (praisonaiagents.knowledge.Knowledge)

    (C0415)


    [warning] 25-25: Unused Knowledge imported from praisonaiagents.knowledge

    (W0611)


    [warning] 76-76: Catching too general exception Exception

    (W0718)


    [error] 35-35: Unable to import 'praisonaiagents.memory'

    (E0401)


    [convention] 35-35: Import outside toplevel (praisonaiagents.memory.Memory)

    (C0415)


    [warning] 70-70: Catching too general exception Exception

    (W0718)


    [warning] 48-48: Unused variable 'memory'

    (W0612)


    [warning] 130-130: Catching too general exception Exception

    (W0718)


    [error] 83-83: Unable to import 'praisonaiagents.knowledge'

    (E0401)


    [convention] 83-83: Import outside toplevel (praisonaiagents.knowledge.Knowledge)

    (C0415)


    [warning] 96-96: Unused variable 'knowledge'

    (W0612)


    [convention] 134-134: Missing function or method docstring

    (C0116)


    [warning] 153-153: Catching too general exception Exception

    (W0718)

    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)

    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_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_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)

    🪛 GitHub Actions: Core Tests
    src/praisonai/tests/unit/test_decorator_enforcement.py

    [error] 1-1: test_decorator_enforcement failed: Expected None, but test returned False. Command executed when it should have been denied.

    src/praisonai/tests/unit/test_graph_memory.py

    [error] 1-1: test_memory_import failed: Failed to import Memory: cannot import name 'Memory' from 'praisonaiagents.memory' (unknown location).


    [error] 1-1: test_knowledge_import failed: Expected None, but test returned True. Assertion error likely due to improper use of return instead of assert.


    [error] 1-1: test_memory_config failed: Memory configuration test failed: cannot import name 'Memory' from 'praisonaiagents.memory' (unknown location).


    [error] 1-1: test_knowledge_config failed: Knowledge configuration test failed: Required packages not installed. Please install using: pip install "praisonaiagents[knowledge]".

    src/praisonai/tests/unit/test_decorator_simple.py

    [error] 1-1: test_improved_decorator failed: Expected None, but test returned True. Assertion error likely due to improper use of return instead of assert.

    src/praisonai/tests/unit/test_approval_agent_integration.py

    [error] 1-1: test_agent_with_auto_approval failed: Expected None, but test returned True. Approval error due to pytest reading from stdin while output is captured. Consider using '-s'.


    [error] 1-1: test_agent_with_auto_denial failed: Expected None, but test returned True. Approval error due to pytest reading from stdin while output is captured. Consider using '-s'.


    [error] 1-1: test_agent_python_code_execution failed: Required packages not available. Please install: black, pylint, autopep8.


    [error] 1-1: test_agent_file_operations failed: Expected None, but test returned True. Approval error due to pytest reading from stdin while output is captured. Consider using '-s'.

    src/praisonai/tests/unit/test_approval_basic.py

    [error] 1-1: test_imports failed: Expected None, but test returned True. Assertion error likely due to improper use of return instead of assert.


    [error] 1-1: test_approval_configuration failed: Expected None, but test returned True. Assertion error likely due to improper use of return instead of assert.


    [error] 1-1: test_approval_decorator failed: Expected None, but test returned True. Assertion error likely due to improper use of return instead of assert.


    [error] 1-1: test_tool_integration failed: Python tools test failed due to missing packages black, pylint, autopep8. Run: pip install black pylint autopep8.


    [error] 1-1: test_agent_integration failed: Expected None, but test returned True. Assertion error likely due to improper use of return instead of assert.

    src/praisonai/tests/unit/test_approval_interactive.py

    [error] 1-1: test_auto_approval_callback failed: Expected None, but test returned True. Assertion error likely due to improper use of return instead of assert.


    [error] 1-1: test_auto_denial_callback failed: Expected None, but test returned True. Command executed when it should have been denied.

    🪛 GitHub Actions: Quick Validation Tests
    src/praisonai/tests/unit/test_approval_agent_integration.py

    [error] 1-1: Test failure in test_agent_with_auto_approval: Expected None, but test returned True. Did you mean to use assert instead of return? Additionally, tool execution was denied due to approval error caused by pytest reading from stdin while output is captured. Consider using -s option.

    ⏰ Context from checks skipped due to timeout of 90000ms (2)
    • GitHub Check: build (3.10)
    • GitHub Check: build (3.11)
    🔇 Additional comments (1)
    src/praisonai/tests/unit/test_decorator_enforcement.py (1)

    1-55: ⚠️ Potential issue

    [Critical] Test is failing and conflicts with PR objectives

    There are several critical issues with this test file:

    1. Inconsistent with PR objectives: The PR summary mentions "streamline test functions in test_scheduler.py" but this is an entirely new test file for approval system functionality.

    2. Test is actually failing: The pipeline shows "Command executed when it should have been denied" - indicating the decorator enforcement is not working as expected.

    3. Incorrect test structure: This is written as an executable script returning boolean values instead of using proper test assertions that pytest expects.

    Apply this diff to fix the test structure:

    -def test_decorator_enforcement():
    +def test_decorator_enforcement():
         """Test that the decorator actually enforces approval."""
    -    print("🧪 Testing Decorator Enforcement")
    -    print("=" * 35)
         
         try:
             from praisonaiagents.tools.shell_tools import ShellTools
             from praisonaiagents.approval import set_approval_callback, ApprovalDecision
             
             # Set auto-denial to test enforcement
             def auto_deny(function_name, arguments, risk_level):
    -            print(f"🚫 Denying {function_name} (risk: {risk_level})")
                 return ApprovalDecision(approved=False, reason='Test denial')
             
             set_approval_callback(auto_deny)
             
             shell_tools = ShellTools()
             
    -        print("Attempting to execute command directly (should be blocked)...")
    -        
    -        try:
    +        # This should now be blocked by the decorator
    +        with pytest.raises(PermissionError):
    -            # This should now be blocked by the decorator
    -            result = shell_tools.execute_command('echo "This should be denied"')
    -            print('❌ Command executed when it should have been denied!')
    -            return False
    -        except PermissionError as e:
    -            print(f'✅ Decorator enforcement working: {e}')
    -            return True
    -        except Exception as e:
    -            print(f'❌ Unexpected error: {e}')
    -            return False
    +            shell_tools.execute_command('echo "This should be denied"')
                 
         except Exception as e:
    -        print(f"❌ Test setup failed: {e}")
    -        return False
    +        pytest.fail(f"Test setup failed: {e}")
    
    -if __name__ == "__main__":
    -    success = test_decorator_enforcement()
    -    if success:
    -        print("\n🎉 Decorator enforcement is working correctly!")
    -    else:
    -        print("\n❌ Decorator enforcement test failed!")
    -    sys.exit(0 if success else 1)

    Likely an incorrect or invalid review comment.

    🧰 Tools
    🪛 Ruff (0.11.9)

    35-35: Local variable result is assigned to but never used

    Remove 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)


    [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)

    🪛 GitHub Actions: Core Tests

    [error] 1-1: test_decorator_enforcement failed: Expected None, but test returned False. Command executed when it should have been denied.

    Comment on lines +9 to +10
    # Add the source directory to Python path
    sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src', 'praisonai-agents'))
    Copy link
    Copy Markdown
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    ⚠️ Potential issue

    Fix the incorrect path construction causing import failures.

    The path setup is incorrect and causing the import failures seen in the pipeline. The test file is located at src/praisonai/tests/unit/test_graph_memory.py, but the path construction assumes a different directory structure.

    -# Add the source directory to Python path
    -sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src', 'praisonai-agents'))
    +# Add the source directory to Python path
    +sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', '..', '..'))

    Alternatively, consider using a more robust approach:

    -# Add the source directory to Python path
    -sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src', 'praisonai-agents'))
    +# Add the project root to Python path
    +project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..', '..'))
    +sys.path.insert(0, project_root)
    📝 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.

    Suggested change
    # Add the source directory to Python path
    sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src', 'praisonai-agents'))
    # Add the source directory to Python path
    sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', '..', '..'))
    🤖 Prompt for AI Agents
    In src/praisonai/tests/unit/test_graph_memory.py around lines 9 to 10, the
    sys.path insertion uses an incorrect relative path that causes import failures.
    Fix this by correctly constructing the path relative to the test file location,
    ensuring it points to the actual source directory containing praisonai-agents.
    Alternatively, use an absolute path or a more robust method like pathlib to
    dynamically resolve the source directory path to avoid import errors.
    

    Comment thread src/praisonai/tests/unit/test_decorator_enforcement.py Outdated
    Comment on lines +1 to +102
    #!/usr/bin/env python3
    """
    Simple test to verify the improved require_approval decorator.
    """

    import sys
    import os

    # Add the praisonai-agents module to path
    sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src', 'praisonai-agents'))

    def test_improved_decorator():
    """Test the improved decorator with context management."""
    print("🧪 Testing Improved Decorator with Context Management")
    print("=" * 55)

    try:
    from praisonaiagents.approval import (
    require_approval, set_approval_callback, ApprovalDecision,
    mark_approved, is_already_approved, clear_approval_context
    )

    # Clear any previous context
    clear_approval_context()

    # Create a test function
    @require_approval(risk_level="critical")
    def test_function(message="test"):
    return f"Function executed: {message}"

    print("✅ Test function decorated successfully")

    # Test 1: Direct call without approval (should fail)
    print("\n1. Testing direct call without approval (should fail)...")

    def auto_deny(function_name, arguments, risk_level):
    return ApprovalDecision(approved=False, reason='Test denial')

    set_approval_callback(auto_deny)

    try:
    result = test_function("direct call")
    print(f"❌ Function executed when it should have been denied: {result}")
    except PermissionError as e:
    print(f"✅ Correctly denied: {e}")

    # Test 2: Mark as approved and call (should succeed)
    print("\n2. Testing with approval context (should succeed)...")

    mark_approved("test_function")

    try:
    result = test_function("approved context")
    print(f"✅ Function executed with approved context: {result}")
    except Exception as e:
    print(f"❌ Function failed in approved context: {e}")

    # Test 3: Clear context and test auto-approval
    print("\n3. Testing auto-approval callback...")

    clear_approval_context()

    def auto_approve(function_name, arguments, risk_level):
    return ApprovalDecision(approved=True, reason='Test approval')

    set_approval_callback(auto_approve)

    try:
    result = test_function("auto approved")
    print(f"✅ Function executed with auto-approval: {result}")
    except Exception as e:
    print(f"❌ Function failed with auto-approval: {e}")

    # Test 4: Verify context is working
    print("\n4. Testing context persistence...")

    if is_already_approved("test_function"):
    print("✅ Context correctly shows function as approved")
    else:
    print("❌ Context not working correctly")

    return True

    except Exception as e:
    print(f"❌ Test failed: {e}")
    import traceback
    traceback.print_exc()
    return False

    if __name__ == "__main__":
    success = test_improved_decorator()
    if success:
    print("\n🎉 Improved decorator approach is working correctly!")
    print("\nKey improvements:")
    print("- ✅ Context management prevents double approval")
    print("- ✅ Proper async handling")
    print("- ✅ Decorator actually enforces approval")
    print("- ✅ Agent integration marks tools as approved")
    else:
    print("\n❌ Improved decorator test failed!")

    sys.exit(0 if success else 1) No newline at end of file
    Copy link
    Copy Markdown
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    ⚠️ Potential issue

    Convert from script to proper pytest test

    This file has the same fundamental issues as the other test files - it's written as an executable script rather than a proper pytest test.

    Convert the structure to use proper assertions:

     def test_improved_decorator():
         """Test the improved decorator with context management."""
    -    print("🧪 Testing Improved Decorator with Context Management")
    -    print("=" * 55)
         
         try:
             from praisonaiagents.approval import (
                 require_approval, set_approval_callback, ApprovalDecision,
                 mark_approved, is_already_approved, clear_approval_context
             )
             
             # Clear any previous context
             clear_approval_context()
             
             # Create a test function
             @require_approval(risk_level="critical")
             def test_function(message="test"):
                 return f"Function executed: {message}"
             
    -        print("✅ Test function decorated successfully")
             
             # Test 1: Direct call without approval (should fail)
    -        print("\n1. Testing direct call without approval (should fail)...")
             
             def auto_deny(function_name, arguments, risk_level):
                 return ApprovalDecision(approved=False, reason='Test denial')
             
             set_approval_callback(auto_deny)
             
    -        try:
    -            result = test_function("direct call")
    -            print(f"❌ Function executed when it should have been denied: {result}")
    -        except PermissionError as e:
    -            print(f"✅ Correctly denied: {e}")
    +        with pytest.raises(PermissionError):
    +            test_function("direct call")

    Apply similar changes throughout the file to use proper assertions instead of print statements and return values.

    Committable suggestion skipped: line range outside the PR's diff.

    🧰 Tools
    🪛 Pylint (3.3.7)

    [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)

    🪛 GitHub Actions: Core Tests

    [error] 1-1: test_improved_decorator failed: Expected None, but test returned True. Assertion error likely due to improper use of return instead of assert.

    🤖 Prompt for AI Agents
    In src/praisonai/tests/unit/test_decorator_simple.py lines 1 to 102, the test is
    currently written as a standalone script using print statements and returning
    boolean values instead of using pytest conventions. Refactor the test function
    to remove print statements and replace them with appropriate pytest assert
    statements to verify expected behavior. Remove the main guard and sys.exit
    calls, and ensure the test function raises exceptions on failure rather than
    catching them and printing errors. This will convert the script into a proper
    pytest test that integrates cleanly with pytest's test discovery and reporting.
    

    Comment on lines +214 to +265
    def main():
    """Run all approval system tests."""
    print("🧪 PraisonAI Human Approval System Test Suite")
    print("=" * 50)

    test_results = []

    # Run synchronous tests
    test_results.append(("Imports", test_imports()))
    test_results.append(("Configuration", test_approval_configuration()))
    test_results.append(("Decorator", test_approval_decorator()))
    test_results.append(("Tool Integration", test_tool_integration()))
    test_results.append(("Agent Integration", test_agent_integration()))

    # Run async tests
    try:
    async_result = asyncio.run(test_approval_callback())
    test_results.append(("Approval Callback", async_result))
    except Exception as e:
    print(f"❌ Async test failed: {e}")
    test_results.append(("Approval Callback", False))

    # Print summary
    print("\n" + "=" * 50)
    print("📊 TEST SUMMARY")
    print("=" * 50)

    passed = 0
    failed = 0

    for test_name, result in test_results:
    status = "✅ PASSED" if result else "❌ FAILED"
    print(f"{test_name:<20} {status}")
    if result:
    passed += 1
    else:
    failed += 1

    print(f"\nTotal: {passed + failed} tests")
    print(f"Passed: {passed}")
    print(f"Failed: {failed}")

    if failed == 0:
    print("\n🎉 All tests passed! Human approval system is working correctly.")
    return True
    else:
    print(f"\n❌ {failed} test(s) failed. Please check the implementation.")
    return False

    if __name__ == "__main__":
    success = main()
    sys.exit(0 if success else 1) No newline at end of file
    Copy link
    Copy Markdown
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    ⚠️ Potential issue

    Convert test runner to proper pytest structure

    The main() function implements a custom test runner that returns boolean values, conflicting with pytest expectations and causing pipeline failures.

    Remove the custom test runner and let pytest handle test execution:

    -def main():
    -    """Run all approval system tests."""
    -    print("🧪 PraisonAI Human Approval System Test Suite")
    -    print("=" * 50)
    -    
    -    test_results = []
    -    
    -    # Run synchronous tests
    -    test_results.append(("Imports", test_imports()))
    -    test_results.append(("Configuration", test_approval_configuration()))
    -    test_results.append(("Decorator", test_approval_decorator()))
    -    test_results.append(("Tool Integration", test_tool_integration()))
    -    test_results.append(("Agent Integration", test_agent_integration()))
    -    
    -    # Run async tests
    -    try:
    -        async_result = asyncio.run(test_approval_callback())
    -        test_results.append(("Approval Callback", async_result))
    -    except Exception as e:
    -        print(f"❌ Async test failed: {e}")
    -        test_results.append(("Approval Callback", False))
    -    
    -    # Print summary
    -    print("\n" + "=" * 50)
    -    print("📊 TEST SUMMARY")
    -    print("=" * 50)
    -    
    -    passed = 0
    -    failed = 0
    -    
    -    for test_name, result in test_results:
    -        status = "✅ PASSED" if result else "❌ FAILED"
    -        print(f"{test_name:<20} {status}")
    -        if result:
    -            passed += 1
    -        else:
    -            failed += 1
    -    
    -    print(f"\nTotal: {passed + failed} tests")
    -    print(f"Passed: {passed}")
    -    print(f"Failed: {failed}")
    -    
    -    if failed == 0:
    -        print("\n🎉 All tests passed! Human approval system is working correctly.")
    -        return True
    -    else:
    -        print(f"\n❌ {failed} test(s) failed. Please check the implementation.")
    -        return False
    -
    -if __name__ == "__main__":
    -    success = main()
    -    sys.exit(0 if success else 1)
    +# Remove main() - let pytest handle test 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.

    Suggested change
    def main():
    """Run all approval system tests."""
    print("🧪 PraisonAI Human Approval System Test Suite")
    print("=" * 50)
    test_results = []
    # Run synchronous tests
    test_results.append(("Imports", test_imports()))
    test_results.append(("Configuration", test_approval_configuration()))
    test_results.append(("Decorator", test_approval_decorator()))
    test_results.append(("Tool Integration", test_tool_integration()))
    test_results.append(("Agent Integration", test_agent_integration()))
    # Run async tests
    try:
    async_result = asyncio.run(test_approval_callback())
    test_results.append(("Approval Callback", async_result))
    except Exception as e:
    print(f"❌ Async test failed: {e}")
    test_results.append(("Approval Callback", False))
    # Print summary
    print("\n" + "=" * 50)
    print("📊 TEST SUMMARY")
    print("=" * 50)
    passed = 0
    failed = 0
    for test_name, result in test_results:
    status = "✅ PASSED" if result else "❌ FAILED"
    print(f"{test_name:<20} {status}")
    if result:
    passed += 1
    else:
    failed += 1
    print(f"\nTotal: {passed + failed} tests")
    print(f"Passed: {passed}")
    print(f"Failed: {failed}")
    if failed == 0:
    print("\n🎉 All tests passed! Human approval system is working correctly.")
    return True
    else:
    print(f"\n{failed} test(s) failed. Please check the implementation.")
    return False
    if __name__ == "__main__":
    success = main()
    sys.exit(0 if success else 1)
    # Remove main() - let pytest handle test execution
    🧰 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)


    [convention] 265-265: Final newline missing

    (C0304)


    [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)

    🤖 Prompt for AI Agents
    In src/praisonai/tests/unit/test_approval_basic.py from lines 214 to 265, the
    main() function implements a custom test runner that returns boolean values,
    which conflicts with pytest's expected test structure and causes pipeline
    failures. Remove the entire main() function and the if __name__ == "__main__"
    block, and instead rely on pytest's default test discovery and execution by
    ensuring all test functions are properly named and structured for pytest to run
    them automatically.
    

    Comment on lines +15 to +34
    def test_imports():
    """Test that all the new approval imports work correctly."""
    try:
    from praisonaiagents.approval import (
    require_approval,
    ApprovalDecision,
    console_approval_callback,
    request_approval,
    add_approval_requirement,
    remove_approval_requirement,
    is_approval_required,
    get_risk_level,
    APPROVAL_REQUIRED_TOOLS,
    TOOL_RISK_LEVELS
    )
    print("✅ All approval imports successful")
    return True
    except ImportError as e:
    print(f"❌ Import failed: {e}")
    return False
    Copy link
    Copy Markdown
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    🛠️ Refactor suggestion

    Improve import testing strategy

    The import test function imports modules but doesn't actually use them, leading to static analysis warnings. Consider testing imports more meaningfully.

     def test_imports():
         """Test that all the new approval imports work correctly."""
    -    try:
    -        from praisonaiagents.approval import (
    -            require_approval,
    -            ApprovalDecision,
    -            console_approval_callback,
    -            request_approval,
    -            add_approval_requirement,
    -            remove_approval_requirement,
    -            is_approval_required,
    -            get_risk_level,
    -            APPROVAL_REQUIRED_TOOLS,
    -            TOOL_RISK_LEVELS
    -        )
    -        print("✅ All approval imports successful")
    -        return True
    -    except ImportError as e:
    -        print(f"❌ Import failed: {e}")
    -        return False
    +    # Test each import individually with actual usage
    +    from praisonaiagents.approval import require_approval
    +    assert callable(require_approval)
    +    
    +    from praisonaiagents.approval import ApprovalDecision
    +    decision = ApprovalDecision(approved=True, reason="test")
    +    assert decision.approved is True
    +    
    +    from praisonaiagents.approval import add_approval_requirement, is_approval_required
    +    add_approval_requirement("test_import", "low")
    +    assert is_approval_required("test_import")
    📝 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.

    Suggested change
    def test_imports():
    """Test that all the new approval imports work correctly."""
    try:
    from praisonaiagents.approval import (
    require_approval,
    ApprovalDecision,
    console_approval_callback,
    request_approval,
    add_approval_requirement,
    remove_approval_requirement,
    is_approval_required,
    get_risk_level,
    APPROVAL_REQUIRED_TOOLS,
    TOOL_RISK_LEVELS
    )
    print("✅ All approval imports successful")
    return True
    except ImportError as e:
    print(f"❌ Import failed: {e}")
    return False
    def test_imports():
    """Test that all the new approval imports work correctly."""
    # Test each import individually with actual usage
    from praisonaiagents.approval import require_approval
    assert callable(require_approval)
    from praisonaiagents.approval import ApprovalDecision
    decision = ApprovalDecision(approved=True, reason="test")
    assert decision.approved is True
    from praisonaiagents.approval import add_approval_requirement, is_approval_required
    add_approval_requirement("test_import", "low")
    assert is_approval_required("test_import")
    🧰 Tools
    🪛 Ruff (0.11.9)

    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)

    🪛 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)

    🤖 Prompt for AI Agents
    In src/praisonai/tests/unit/test_approval_basic.py between lines 15 and 34, the
    test_imports function imports approval modules but does not use them, causing
    static analysis warnings. To fix this, modify the test to not only import but
    also perform simple operations or assertions with the imported items, such as
    checking their types or calling a minimal function, to ensure they are used
    meaningfully and avoid unused import warnings.
    

    🛠️ Refactor suggestion

    Fix import test logic and address unused imports.

    The test_imports function imports modules only to test if they can be imported, but doesn't use them afterwards. This is causing static analysis warnings.

     def test_imports():
         """Test that all the new approval imports work correctly."""
         try:
    -        from praisonaiagents.approval import (
    -            require_approval,
    -            ApprovalDecision,
    -            console_approval_callback,
    -            request_approval,
    -            add_approval_requirement,
    -            remove_approval_requirement,
    -            is_approval_required,
    -            get_risk_level,
    -            APPROVAL_REQUIRED_TOOLS,
    -            TOOL_RISK_LEVELS
    -        )
    +        import importlib.util
    +        
    +        # Test individual imports
    +        modules_to_test = [
    +            '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'
    +        ]
    +        
    +        for module_name in modules_to_test:
    +            module_path = module_name.replace('.', '/') + '.py'
    +            spec = importlib.util.find_spec(module_name.split('.')[0])
    +            assert spec is not None, f"Module {module_name.split('.')[0]} not found"
    +        
             print("✅ All approval imports successful")
    -        return True
         except ImportError as e:
             print(f"❌ Import failed: {e}")
    -        return False
    +        pytest.fail(f"Import failed: {e}")

    Committable suggestion skipped: line range outside the PR's diff.

    🧰 Tools
    🪛 Ruff (0.11.9)

    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)

    🪛 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)

    🤖 Prompt for AI Agents
    In src/praisonai/tests/unit/test_approval_basic.py around lines 15 to 34, the
    test_imports function imports multiple approval-related symbols but does not use
    them, causing static analysis warnings for unused imports. To fix this, modify
    the test to actually reference or use the imported symbols in a minimal way,
    such as asserting their types or existence, so that the imports are recognized
    as used and the warnings are resolved.
    

    Comment on lines +90 to +102
    if __name__ == "__main__":
    success = test_improved_decorator()
    if success:
    print("\n🎉 Improved decorator approach is working correctly!")
    print("\nKey improvements:")
    print("- ✅ Context management prevents double approval")
    print("- ✅ Proper async handling")
    print("- ✅ Decorator actually enforces approval")
    print("- ✅ Agent integration marks tools as approved")
    else:
    print("\n❌ Improved decorator test failed!")

    sys.exit(0 if success else 1) No newline at end of file
    Copy link
    Copy Markdown
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    🛠️ Refactor suggestion

    Fix main execution block structure.

    Similar to the previous file, the main execution should be restructured to work properly with pytest.

     if __name__ == "__main__":
    -    success = test_improved_decorator()
    -    if success:
    -        print("\n🎉 Improved decorator approach is working correctly!")
    -        print("\nKey improvements:")
    -        print("- ✅ Context management prevents double approval")
    -        print("- ✅ Proper async handling")
    -        print("- ✅ Decorator actually enforces approval")
    -        print("- ✅ Agent integration marks tools as approved")
    -    else:
    -        print("\n❌ Improved decorator test failed!")
    -    
    -    sys.exit(0 if success else 1)
    +    try:
    +        test_improved_decorator()
    +        print("\n🎉 Improved decorator approach is working correctly!")
    +        print("\nKey improvements:")
    +        print("- ✅ Context management prevents double approval")
    +        print("- ✅ Proper async handling")
    +        print("- ✅ Decorator actually enforces approval")
    +        print("- ✅ Agent integration marks tools as approved")
    +    except Exception as e:
    +        print(f"\n❌ Improved decorator test failed: {e}")
    +        sys.exit(1)
    📝 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.

    Suggested change
    if __name__ == "__main__":
    success = test_improved_decorator()
    if success:
    print("\n🎉 Improved decorator approach is working correctly!")
    print("\nKey improvements:")
    print("- ✅ Context management prevents double approval")
    print("- ✅ Proper async handling")
    print("- ✅ Decorator actually enforces approval")
    print("- ✅ Agent integration marks tools as approved")
    else:
    print("\n❌ Improved decorator test failed!")
    sys.exit(0 if success else 1)
    if __name__ == "__main__":
    try:
    test_improved_decorator()
    print("\n🎉 Improved decorator approach is working correctly!")
    print("\nKey improvements:")
    print("- ✅ Context management prevents double approval")
    print("- ✅ Proper async handling")
    print("- ✅ Decorator actually enforces approval")
    print("- ✅ Agent integration marks tools as approved")
    except Exception as e:
    print(f"\n❌ Improved decorator test failed: {e}")
    sys.exit(1)
    🧰 Tools
    🪛 Pylint (3.3.7)

    [convention] 101-101: Trailing whitespace

    (C0303)


    [convention] 102-102: Final newline missing

    (C0304)


    [convention] 91-91: Constant name "success" doesn't conform to UPPER_CASE naming style

    (C0103)

    🤖 Prompt for AI Agents
    In src/praisonai/tests/unit/test_decorator_simple.py around lines 90 to 102, the
    main execution block uses a manual test invocation and sys.exit, which is not
    compatible with pytest. Remove the if __name__ == "__main__" block entirely and
    rely on pytest's test discovery to run the test_improved_decorator function
    automatically. This will ensure proper integration with pytest and avoid manual
    exit calls.
    

    Comment on lines +214 to +261
    def main():
    """Run all approval system tests."""
    print("🧪 PraisonAI Human Approval System Test Suite")
    print("=" * 50)

    test_results = []

    # Run synchronous tests
    test_results.append(("Imports", test_imports()))
    test_results.append(("Configuration", test_approval_configuration()))
    test_results.append(("Decorator", test_approval_decorator()))
    test_results.append(("Tool Integration", test_tool_integration()))
    test_results.append(("Agent Integration", test_agent_integration()))

    # Run async tests
    try:
    async_result = asyncio.run(test_approval_callback())
    test_results.append(("Approval Callback", async_result))
    except Exception as e:
    print(f"❌ Async test failed: {e}")
    test_results.append(("Approval Callback", False))

    # Print summary
    print("\n" + "=" * 50)
    print("📊 TEST SUMMARY")
    print("=" * 50)

    passed = 0
    failed = 0

    for test_name, result in test_results:
    status = "✅ PASSED" if result else "❌ FAILED"
    print(f"{test_name:<20} {status}")
    if result:
    passed += 1
    else:
    failed += 1

    print(f"\nTotal: {passed + failed} tests")
    print(f"Passed: {passed}")
    print(f"Failed: {failed}")

    if failed == 0:
    print("\n🎉 All tests passed! Human approval system is working correctly.")
    return True
    else:
    print(f"\n❌ {failed} test(s) failed. Please check the implementation.")
    return False
    Copy link
    Copy Markdown
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    🛠️ Refactor suggestion

    Convert test runner to use proper assertions.

    The main function uses a custom test runner that returns boolean values, which doesn't integrate well with pytest.

     def main():
         """Run all approval system tests."""
         print("🧪 PraisonAI Human Approval System Test Suite")
         print("=" * 50)
         
    -    test_results = []
    -    
    -    # Run synchronous tests
    -    test_results.append(("Imports", test_imports()))
    -    test_results.append(("Configuration", test_approval_configuration()))
    -    test_results.append(("Decorator", test_approval_decorator()))
    -    test_results.append(("Tool Integration", test_tool_integration()))
    -    test_results.append(("Agent Integration", test_agent_integration()))
    -    
    -    # Run async tests
    -    try:
    -        async_result = asyncio.run(test_approval_callback())
    -        test_results.append(("Approval Callback", async_result))
    -    except Exception as e:
    -        print(f"❌ Async test failed: {e}")
    -        test_results.append(("Approval Callback", False))
    +    # Run synchronous tests
    +    test_imports()
    +    print("✅ Imports test passed")
    +    
    +    test_approval_configuration()
    +    print("✅ Configuration test passed")
    +    
    +    test_approval_decorator()
    +    print("✅ Decorator test passed")
    +    
    +    test_tool_integration()
    +    print("✅ Tool Integration test passed")
    +    
    +    test_agent_integration()
    +    print("✅ Agent Integration test passed")
    +    
    +    # Run async tests
    +    asyncio.run(test_approval_callback())
    +    print("✅ Approval Callback test passed")
         
    -    # Print summary
    -    print("\n" + "=" * 50)
    -    print("📊 TEST SUMMARY")
    -    print("=" * 50)
    -    
    -    passed = 0
    -    failed = 0
    -    
    -    for test_name, result in test_results:
    -        status = "✅ PASSED" if result else "❌ FAILED"
    -        print(f"{test_name:<20} {status}")
    -        if result:
    -            passed += 1
    -        else:
    -            failed += 1
    -    
    -    print(f"\nTotal: {passed + failed} tests")
    -    print(f"Passed: {passed}")
    -    print(f"Failed: {failed}")
    -    
    -    if failed == 0:
    -        print("\n🎉 All tests passed! Human approval system is working correctly.")
    -        return True
    -    else:
    -        print(f"\n❌ {failed} test(s) failed. Please check the implementation.")
    -        return False
    +    print("\n🎉 All tests passed! Human approval system is working correctly.")
    📝 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.

    Suggested change
    def main():
    """Run all approval system tests."""
    print("🧪 PraisonAI Human Approval System Test Suite")
    print("=" * 50)
    test_results = []
    # Run synchronous tests
    test_results.append(("Imports", test_imports()))
    test_results.append(("Configuration", test_approval_configuration()))
    test_results.append(("Decorator", test_approval_decorator()))
    test_results.append(("Tool Integration", test_tool_integration()))
    test_results.append(("Agent Integration", test_agent_integration()))
    # Run async tests
    try:
    async_result = asyncio.run(test_approval_callback())
    test_results.append(("Approval Callback", async_result))
    except Exception as e:
    print(f"❌ Async test failed: {e}")
    test_results.append(("Approval Callback", False))
    # Print summary
    print("\n" + "=" * 50)
    print("📊 TEST SUMMARY")
    print("=" * 50)
    passed = 0
    failed = 0
    for test_name, result in test_results:
    status = "✅ PASSED" if result else "❌ FAILED"
    print(f"{test_name:<20} {status}")
    if result:
    passed += 1
    else:
    failed += 1
    print(f"\nTotal: {passed + failed} tests")
    print(f"Passed: {passed}")
    print(f"Failed: {failed}")
    if failed == 0:
    print("\n🎉 All tests passed! Human approval system is working correctly.")
    return True
    else:
    print(f"\n{failed} test(s) failed. Please check the implementation.")
    return False
    def main():
    """Run all approval system tests."""
    print("🧪 PraisonAI Human Approval System Test Suite")
    print("=" * 50)
    # Run synchronous tests
    test_imports()
    print("✅ Imports test passed")
    test_approval_configuration()
    print("✅ Configuration test passed")
    test_approval_decorator()
    print("✅ Decorator test passed")
    test_tool_integration()
    print("✅ Tool Integration test passed")
    test_agent_integration()
    print("✅ Agent Integration test passed")
    # Run async tests
    asyncio.run(test_approval_callback())
    print("✅ Approval Callback test passed")
    print("\n🎉 All tests passed! Human approval system is working correctly.")
    🧰 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)

    🤖 Prompt for AI Agents
    In src/praisonai/tests/unit/test_approval_basic.py lines 214 to 261, the main
    test runner uses print statements and boolean returns instead of proper
    assertions, which is incompatible with pytest. Refactor the tests to remove the
    main function and instead convert each test into individual pytest test
    functions using assert statements to verify outcomes. This will allow pytest to
    handle test execution and reporting natively.
    

    Comment on lines +114 to +124
    # Test python tools
    try:
    from praisonaiagents.tools.python_tools import PythonTools
    python_tools = PythonTools()

    # Check if execute_code requires approval
    assert is_approval_required("execute_code"), "execute_code should require approval"
    print("✅ PythonTools.execute_code requires approval")

    except Exception as e:
    print(f"⚠️ Python tools test failed: {e}")
    Copy link
    Copy Markdown
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    💡 Verification agent

    🧩 Analysis chain

    Address missing Python tool dependencies.

    The pipeline failure indicates missing packages (black, pylint, autopep8) required for Python tools testing.

    The Python tools test is failing due to missing packages. This suggests the test environment needs additional dependencies.

    Consider adding these packages to the test requirements or making the Python tools test conditional:

         # Test python tools
         try:
    +        import subprocess
    +        # Check if required packages are available
    +        required_packages = ['black', 'pylint', 'autopep8']
    +        missing_packages = []
    +        for package in required_packages:
    +            try:
    +                __import__(package)
    +            except ImportError:
    +                missing_packages.append(package)
    +        
    +        if missing_packages:
    +            print(f"⚠️ Python tools test skipped: missing packages {missing_packages}")
    +            return True
    +            
             from praisonaiagents.tools.python_tools import PythonTools

    🏁 Script executed:

    #!/bin/bash
    # Check if the required packages are listed in requirements or setup files
    fd -e txt -e py | xargs rg -l "black|pylint|autopep8" | head -5
    
    # Check current Python packages in the environment
    pip list | grep -E "(black|pylint|autopep8)"

    Length of output: 472


    🏁 Script executed:

    #!/bin/bash
    # Inspect import usage and early code in PythonTools to confirm dependency requirements
    rg -n "import .*black" src/praisonai-agents/praisonaiagents/tools/python_tools.py
    rg -n "import .*autopep8" src/praisonai-agents/praisonaiagents/tools/python_tools.py
    rg -n "import .*pylint" src/praisonai-agents/praisonaiagents/tools/python_tools.py
    
    # Display the top of the file to see how these imports are used
    sed -n '1,200p' src/praisonai-agents/praisonaiagents/tools/python_tools.py

    Length of output: 7444


    Add missing Python tool dependencies or skip tests when unavailable

    The PythonTools class enforces that black, pylint and autopep8 are installed via its _check_dependencies(). Our CI environment currently only includes pylint, causing the unit test in test_approval_basic.py to fail when attempting to instantiate PythonTools.

    Please address this by either:

    • Adding black and autopep8 (and ensuring pylint) to your dev/test dependencies (e.g. requirements-dev.txt, test_requirements.txt, or CI setup), or
    • Modifying the test to skip when these packages are missing using pytest.importorskip.

    Locations to update:

    • src/praisonai/tests/unit/test_approval_basic.py (around lines 114–124)
    • Your project’s dev/test requirements file(s)

    Suggested test change using pytest skips:

    -from praisonaiagents.tools.python_tools import PythonTools
    -# Test python tools
    -try:
    -    python_tools = PythonTools()
    -    assert is_approval_required("execute_code"), "execute_code should require approval"
    -    print("✅ PythonTools.execute_code requires approval")
    -except Exception as e:
    -    print(f"⚠️ Python tools test failed: {e}")
    +import pytest
    +
    +def test_python_tools_execute_code_requires_approval():
    +    # Skip if any Python tool dependency is not installed
    +    pytest.importorskip("black")
    +    pytest.importorskip("autopep8")
    +    pytest.importorskip("pylint")
    +
    +    from praisonaiagents.tools.python_tools import PythonTools
    +    python_tools = PythonTools()
    +    assert is_approval_required("execute_code"), "execute_code should require approval"
    +    print("✅ PythonTools.execute_code requires approval")

    Or ensure your test requirements include:

    black
    pylint
    autopep8
    
    🧰 Tools
    🪛 Ruff (0.11.9)

    117-117: Local variable python_tools is assigned to but never used

    Remove assignment to unused variable python_tools

    (F841)

    🪛 Pylint (3.3.7)

    [convention] 118-118: Trailing whitespace

    (C0303)


    [convention] 122-122: Trailing whitespace

    (C0303)


    [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] 117-117: Unused variable 'python_tools'

    (W0612)

    🤖 Prompt for AI Agents
    In src/praisonai/tests/unit/test_approval_basic.py around lines 114 to 124, the
    PythonTools test fails due to missing dependencies black and autopep8 in the
    test environment. Fix this by either adding black, pylint, and autopep8 to your
    project's dev/test requirements files to ensure they are installed in CI and
    local testing, or modify the test to skip execution when these packages are not
    available by using pytest.importorskip for each dependency before importing
    PythonTools.
    

    Comment on lines +17 to +18
    # Run interactively only when ASK_USER=1 is set
    @pytest.mark.skipif(os.getenv("ASK_USER") != "1", reason="interactive approval requires user input")
    Copy link
    Copy Markdown
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    🛠️ Refactor suggestion

    Fix pytest skip condition and add pytest configuration.

    The test is being skipped correctly for interactive approval, but the pipeline failures suggest pytest's capture mechanism is interfering with the approval system.

    Add pytest configuration to handle stdin/stdout capture issues:

    +import pytest
    +
     # Run interactively only when ASK_USER=1 is set
    -@pytest.mark.skipif(os.getenv("ASK_USER") != "1", reason="interactive approval requires user input")
    +@pytest.mark.skipif(os.getenv("ASK_USER") != "1", reason="interactive approval requires user input")
    +@pytest.mark.capture('no')  # Disable capture for interactive tests
     def test_agent_tool_execution_with_approval():

    Also consider adding a pytest.ini or pyproject.toml configuration:

    [tool.pytest.ini_options]
    addopts = "-s --tb=short"
    🤖 Prompt for AI Agents
    In src/praisonai/tests/unit/test_approval_agent_integration.py around lines 17
    to 18, the pytest skip condition is correct but pytest's default output capture
    interferes with interactive approval tests. To fix this, add pytest
    configuration to disable output capturing by including the "-s" option and
    shorten tracebacks with "--tb=short". This can be done by creating or updating a
    pytest.ini or pyproject.toml file with the appropriate addopts setting to ensure
    stdin/stdout are properly handled during test runs.
    

    Comment thread src/praisonai/tests/unit/test_approval_agent_integration.py Outdated
    - Added a newline at the end of the file to comply with standard coding practices.
    - Maintained existing functionality while adhering to the principle of minimal code change.
    Copy link
    Copy Markdown
    Contributor

    @coderabbitai coderabbitai Bot left a comment

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Actionable comments posted: 2

    ♻️ Duplicate comments (1)
    src/praisonai/tests/unit/test_graph_memory.py (1)

    9-10: ⚠️ Potential issue

    Fix the incorrect path construction causing import failures.

    This is the same issue identified in the previous review. The path setup is still incorrect and causing the import failures seen in the pipeline.

    Apply the suggested fix from the previous review:

    -# Add the source directory to Python path
    -sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src', 'praisonai-agents'))
    +# Add the project root to Python path
    +project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..', '..'))
    +sys.path.insert(0, project_root)
    🧹 Nitpick comments (5)
    src/praisonai/tests/unit/test_graph_memory.py (5)

    48-48: Address unused variable warning appropriately.

    The static analysis flags memory as unused, but it's actually used to test successful initialization. Consider adding a simple assertion to demonstrate usage.

     memory = Memory(config=basic_config, verbose=1)
    +assert memory is not None, "Memory should be initialized successfully"
     print("✅ Basic memory configuration works")
    🧰 Tools
    🪛 Ruff (0.11.9)

    48-48: Local variable memory is assigned to but never used

    Remove assignment to unused variable memory

    (F841)

    🪛 Pylint (3.3.7)

    [warning] 48-48: Unused variable 'memory'

    (W0612)


    66-72: Use more specific exception handling.

    The broad exception catching makes it difficult to distinguish between expected failures (missing dependencies) and actual bugs.

     try:
         memory_graph = Memory(config=graph_config, verbose=1)
         print("✅ Graph memory configuration initialized")
         print(f"   Graph enabled: {getattr(memory_graph, 'graph_enabled', False)}")
    -except Exception as e:
    +except (ImportError, ModuleNotFoundError, ConnectionError) as e:
         print(f"⚠️  Graph memory not available (expected): {e}")
         print("   This is normal if graph dependencies are not installed")
    +except Exception as e:
    +    print(f"❌ Unexpected error in graph memory configuration: {e}")
    +    raise
    🧰 Tools
    🪛 Pylint (3.3.7)

    [warning] 70-70: Catching too general exception Exception

    (W0718)


    96-96: Address unused variable warning appropriately.

    Similar to the memory variable, add an assertion to demonstrate usage.

     knowledge = Knowledge(config=basic_config, verbose=0)
    +assert knowledge is not None, "Knowledge should be initialized successfully"
     print("✅ Basic knowledge configuration works")
    🧰 Tools
    🪛 Ruff (0.11.9)

    96-96: Local variable knowledge is assigned to but never used

    Remove assignment to unused variable knowledge

    (F841)

    🪛 Pylint (3.3.7)

    [warning] 96-96: Unused variable 'knowledge'

    (W0612)


    134-168: Add missing docstring and improve test orchestration.

    The main function lacks a docstring and could benefit from more robust error handling and reporting.

     def main():
    +    """Run all graph memory tests and report results."""
         print("🧪 Testing Graph Memory Implementation")
         print("=" * 50)
         
         tests = [
             ("Memory Import", test_memory_import),
             ("Knowledge Import", test_knowledge_import), 
             ("Memory Configuration", test_memory_config),
             ("Knowledge Configuration", test_knowledge_config)
         ]
         
         passed = 0
         total = len(tests)
    +    failed_tests = []
         
         for test_name, test_func in tests:
             print(f"\n🔬 Testing {test_name}...")
             try:
                 if test_func():
                     passed += 1
    +            else:
    +                failed_tests.append(test_name)
             except Exception as e:
                 print(f"❌ Test {test_name} crashed: {e}")
    +            failed_tests.append(test_name)
         
         print(f"\n📊 Test Results: {passed}/{total} tests passed")
         
         if passed == total:
             print("🎉 All tests passed! Graph memory implementation is working correctly.")
         else:
             print("⚠️  Some tests failed. This might be expected if dependencies are missing.")
    +        if failed_tests:
    +            print(f"   Failed tests: {', '.join(failed_tests)}")
    🧰 Tools
    🪛 Pylint (3.3.7)

    [convention] 137-137: Trailing whitespace

    (C0303)


    [convention] 140-140: Trailing whitespace

    (C0303)


    [convention] 144-144: Trailing whitespace

    (C0303)


    [convention] 147-147: Trailing whitespace

    (C0303)


    [convention] 155-155: Trailing whitespace

    (C0303)


    [convention] 157-157: Trailing whitespace

    (C0303)


    [convention] 162-162: Trailing whitespace

    (C0303)


    [convention] 168-168: Final newline missing

    (C0304)


    [convention] 134-134: Missing function or method docstring

    (C0116)


    [warning] 153-153: Catching too general exception Exception

    (W0718)


    1-168: Remove trailing whitespace throughout the file.

    Multiple lines have trailing whitespace that should be cleaned up for consistency.

    Please remove trailing whitespace from lines: 36, 47, 50, 65, 73, 75, 84, 95, 98, 117, 120, 127, 129, 137, 140, 144, 147, 155, 157, 162. Also add a final newline at the end of the file (line 168).

    🧰 Tools
    🪛 Ruff (0.11.9)

    15-15: praisonaiagents.memory.Memory imported but unused; consider using importlib.util.find_spec to test for availability

    (F401)


    25-25: praisonaiagents.knowledge.Knowledge imported but unused; consider using importlib.util.find_spec to test for availability

    (F401)


    48-48: Local variable memory is assigned to but never used

    Remove assignment to unused variable memory

    (F841)


    96-96: Local variable knowledge is assigned to but never used

    Remove assignment to unused variable knowledge

    (F841)

    🪛 Pylint (3.3.7)

    [convention] 36-36: Trailing whitespace

    (C0303)


    [convention] 47-47: Trailing whitespace

    (C0303)


    [convention] 50-50: Trailing whitespace

    (C0303)


    [convention] 65-65: Trailing whitespace

    (C0303)


    [convention] 73-73: Trailing whitespace

    (C0303)


    [convention] 75-75: Trailing whitespace

    (C0303)


    [convention] 84-84: Trailing whitespace

    (C0303)


    [convention] 95-95: Trailing whitespace

    (C0303)


    [convention] 98-98: Trailing whitespace

    (C0303)


    [convention] 117-117: Trailing whitespace

    (C0303)


    [convention] 120-120: Trailing whitespace

    (C0303)


    [convention] 127-127: Trailing whitespace

    (C0303)


    [convention] 129-129: Trailing whitespace

    (C0303)


    [convention] 137-137: Trailing whitespace

    (C0303)


    [convention] 140-140: Trailing whitespace

    (C0303)


    [convention] 144-144: Trailing whitespace

    (C0303)


    [convention] 147-147: Trailing whitespace

    (C0303)


    [convention] 155-155: Trailing whitespace

    (C0303)


    [convention] 157-157: Trailing whitespace

    (C0303)


    [convention] 162-162: Trailing whitespace

    (C0303)


    [convention] 168-168: Final newline missing

    (C0304)


    [convention] 15-15: Import outside toplevel (praisonaiagents.memory.Memory)

    (C0415)


    [warning] 15-15: Unused Memory imported from praisonaiagents.memory

    (W0611)


    [convention] 25-25: Import outside toplevel (praisonaiagents.knowledge.Knowledge)

    (C0415)


    [warning] 25-25: Unused Knowledge imported from praisonaiagents.knowledge

    (W0611)


    [warning] 76-76: Catching too general exception Exception

    (W0718)


    [error] 35-35: Unable to import 'praisonaiagents.memory'

    (E0401)


    [convention] 35-35: Import outside toplevel (praisonaiagents.memory.Memory)

    (C0415)


    [warning] 70-70: Catching too general exception Exception

    (W0718)


    [warning] 48-48: Unused variable 'memory'

    (W0612)


    [warning] 130-130: Catching too general exception Exception

    (W0718)


    [error] 83-83: Unable to import 'praisonaiagents.knowledge'

    (E0401)


    [convention] 83-83: Import outside toplevel (praisonaiagents.knowledge.Knowledge)

    (C0415)


    [warning] 96-96: Unused variable 'knowledge'

    (W0612)


    [convention] 134-134: Missing function or method docstring

    (C0116)


    [warning] 153-153: Catching too general exception Exception

    (W0718)

    🪛 GitHub Actions: Core Tests

    [error] 1-1: Test 'test_memory_import' failed: cannot import name 'Memory' from 'praisonaiagents.memory' (unknown location).


    [warning] 1-1: Test 'test_knowledge_import' passed but returned True instead of None. Did you mean to use assert instead of return?


    [error] 1-1: Test 'test_memory_config' failed: cannot import name 'Memory' from 'praisonaiagents.memory' (unknown location).


    [error] 1-1: Test 'test_knowledge_config' failed: Required packages not installed. Please install using: pip install "praisonaiagents[knowledge]".

    📜 Review details

    Configuration used: CodeRabbit UI
    Review profile: CHILL
    Plan: Pro

    📥 Commits

    Reviewing files that changed from the base of the PR and between 9b6b9b2 and 460d515.

    📒 Files selected for processing (1)
    • src/praisonai/tests/unit/test_graph_memory.py (1 hunks)
    🧰 Additional context used
    🧬 Code Graph Analysis (1)
    src/praisonai/tests/unit/test_graph_memory.py (1)
    src/praisonai-agents/praisonaiagents/knowledge/knowledge.py (2)
    • memory (143-156)
    • config (86-140)
    🪛 Ruff (0.11.9)
    src/praisonai/tests/unit/test_graph_memory.py

    15-15: praisonaiagents.memory.Memory imported but unused; consider using importlib.util.find_spec to test for availability

    (F401)


    25-25: praisonaiagents.knowledge.Knowledge imported but unused; consider using importlib.util.find_spec to test for availability

    (F401)


    48-48: Local variable memory is assigned to but never used

    Remove assignment to unused variable memory

    (F841)


    96-96: Local variable knowledge is assigned to but never used

    Remove assignment to unused variable knowledge

    (F841)

    🪛 Pylint (3.3.7)
    src/praisonai/tests/unit/test_graph_memory.py

    [convention] 36-36: Trailing whitespace

    (C0303)


    [convention] 47-47: Trailing whitespace

    (C0303)


    [convention] 50-50: Trailing whitespace

    (C0303)


    [convention] 65-65: Trailing whitespace

    (C0303)


    [convention] 73-73: Trailing whitespace

    (C0303)


    [convention] 75-75: Trailing whitespace

    (C0303)


    [convention] 84-84: Trailing whitespace

    (C0303)


    [convention] 95-95: Trailing whitespace

    (C0303)


    [convention] 98-98: Trailing whitespace

    (C0303)


    [convention] 117-117: Trailing whitespace

    (C0303)


    [convention] 120-120: Trailing whitespace

    (C0303)


    [convention] 127-127: Trailing whitespace

    (C0303)


    [convention] 129-129: Trailing whitespace

    (C0303)


    [convention] 137-137: Trailing whitespace

    (C0303)


    [convention] 140-140: Trailing whitespace

    (C0303)


    [convention] 144-144: Trailing whitespace

    (C0303)


    [convention] 147-147: Trailing whitespace

    (C0303)


    [convention] 155-155: Trailing whitespace

    (C0303)


    [convention] 157-157: Trailing whitespace

    (C0303)


    [convention] 162-162: Trailing whitespace

    (C0303)


    [convention] 168-168: Final newline missing

    (C0304)


    [convention] 15-15: Import outside toplevel (praisonaiagents.memory.Memory)

    (C0415)


    [warning] 15-15: Unused Memory imported from praisonaiagents.memory

    (W0611)


    [convention] 25-25: Import outside toplevel (praisonaiagents.knowledge.Knowledge)

    (C0415)


    [warning] 25-25: Unused Knowledge imported from praisonaiagents.knowledge

    (W0611)


    [warning] 76-76: Catching too general exception Exception

    (W0718)


    [error] 35-35: Unable to import 'praisonaiagents.memory'

    (E0401)


    [convention] 35-35: Import outside toplevel (praisonaiagents.memory.Memory)

    (C0415)


    [warning] 70-70: Catching too general exception Exception

    (W0718)


    [warning] 48-48: Unused variable 'memory'

    (W0612)


    [warning] 130-130: Catching too general exception Exception

    (W0718)


    [error] 83-83: Unable to import 'praisonaiagents.knowledge'

    (E0401)


    [convention] 83-83: Import outside toplevel (praisonaiagents.knowledge.Knowledge)

    (C0415)


    [warning] 96-96: Unused variable 'knowledge'

    (W0612)


    [convention] 134-134: Missing function or method docstring

    (C0116)


    [warning] 153-153: Catching too general exception Exception

    (W0718)

    🪛 GitHub Actions: Core Tests
    src/praisonai/tests/unit/test_graph_memory.py

    [error] 1-1: Test 'test_memory_import' failed: cannot import name 'Memory' from 'praisonaiagents.memory' (unknown location).


    [warning] 1-1: Test 'test_knowledge_import' passed but returned True instead of None. Did you mean to use assert instead of return?


    [error] 1-1: Test 'test_memory_config' failed: cannot import name 'Memory' from 'praisonaiagents.memory' (unknown location).


    [error] 1-1: Test 'test_knowledge_config' failed: Required packages not installed. Please install using: pip install "praisonaiagents[knowledge]".

    ⏰ Context from checks skipped due to timeout of 90000ms (2)
    • GitHub Check: build (3.10)
    • GitHub Check: build (3.11)

    Comment on lines +163 to +165
    print("\n💡 To fully test graph memory, install dependencies:")
    print(" pip install \"mem0ai[graph]\"")
    print(" docker run -p 7687:7687 memgraph/memgraph-mage:latest")
    Copy link
    Copy Markdown
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    💡 Verification agent

    🧩 Analysis chain

    Verify the package installation instructions.

    Ensure the installation command and Docker instructions are accurate for the current version.


    🏁 Script executed:

    #!/bin/bash
    # Description: Verify the correct installation command and Docker image for mem0ai and memgraph
    
    # Check if mem0ai package exists with graph extras
    curl -s https://pypi.org/pypi/mem0ai/json | jq '.info.description' | head -20
    
    # Check if the Docker image exists
    curl -s https://hub.docker.com/v2/repositories/memgraph/memgraph-mage/tags | jq '.results[0].name'

    Length of output: 6980


    To verify the mem0ai[graph] extra actually exists on PyPI:


    🏁 Script executed:

    #!/bin/bash
    # Check available extras for the mem0ai package
    curl -s https://pypi.org/pypi/mem0ai/json | jq '.info.provides_extras'

    Length of output: 75


    Update mem0ai installation command

    The PyPI metadata shows no “graph” extra for mem0ai, so the test’s install hint should be updated:

    • File: src/praisonai/tests/unit/test_graph_memory.py (lines 163–165)

    - print("   pip install \"mem0ai[graph]\"")
    + print("   pip install mem0ai")

    The Docker instruction (memgraph/memgraph-mage:latest) is correct.

    📝 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.

    Suggested change
    print("\n💡 To fully test graph memory, install dependencies:")
    print(" pip install \"mem0ai[graph]\"")
    print(" docker run -p 7687:7687 memgraph/memgraph-mage:latest")
    print("\n💡 To fully test graph memory, install dependencies:")
    print(" pip install mem0ai")
    print(" docker run -p 7687:7687 memgraph/memgraph-mage:latest")
    🤖 Prompt for AI Agents
    In src/praisonai/tests/unit/test_graph_memory.py around lines 163 to 165, the
    installation command references a non-existent "graph" extra for the mem0ai
    package. Update the pip install command to remove the "[graph]" extra, changing
    it to simply "pip install mem0ai". Keep the Docker instruction for memgraph
    unchanged as it is correct.
    

    Comment on lines +12 to +31
    def test_memory_import():
    """Test that Memory class can be imported and initialized"""
    try:
    from praisonaiagents.memory import Memory
    print("✅ Memory class imported successfully")
    return True
    except ImportError as e:
    print(f"❌ Failed to import Memory: {e}")
    return False

    def test_knowledge_import():
    """Test that Knowledge class can be imported"""
    try:
    from praisonaiagents.knowledge import Knowledge
    print("✅ Knowledge class imported successfully")
    return True
    except ImportError as e:
    print(f"❌ Failed to import Knowledge: {e}")
    return False

    Copy link
    Copy Markdown
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    🛠️ Refactor suggestion

    Consider using proper test assertions instead of print statements.

    The test functions use print statements and return boolean values instead of proper assertions. This pattern doesn't follow standard unit testing practices and makes it harder to integrate with test frameworks.

    Consider refactoring to use proper assertions:

     def test_memory_import():
         """Test that Memory class can be imported and initialized"""
    -    try:
    -        from praisonaiagents.memory import Memory
    -        print("✅ Memory class imported successfully")
    -        return True
    -    except ImportError as e:
    -        print(f"❌ Failed to import Memory: {e}")
    -        return False
    +    from praisonaiagents.memory import Memory
    +    assert Memory is not None, "Memory class should be importable"
    
     def test_knowledge_import():
         """Test that Knowledge class can be imported"""
    -    try:
    -        from praisonaiagents.knowledge import Knowledge
    -        print("✅ Knowledge class imported successfully")
    -        return True
    -    except ImportError as e:
    -        print(f"❌ Failed to import Knowledge: {e}")
    -        return False
    +    from praisonaiagents.knowledge import Knowledge
    +    assert Knowledge is not None, "Knowledge class should be importable"
    📝 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.

    Suggested change
    def test_memory_import():
    """Test that Memory class can be imported and initialized"""
    try:
    from praisonaiagents.memory import Memory
    print("✅ Memory class imported successfully")
    return True
    except ImportError as e:
    print(f"❌ Failed to import Memory: {e}")
    return False
    def test_knowledge_import():
    """Test that Knowledge class can be imported"""
    try:
    from praisonaiagents.knowledge import Knowledge
    print("✅ Knowledge class imported successfully")
    return True
    except ImportError as e:
    print(f"❌ Failed to import Knowledge: {e}")
    return False
    def test_memory_import():
    """Test that Memory class can be imported and initialized"""
    from praisonaiagents.memory import Memory
    assert Memory is not None, "Memory class should be importable"
    def test_knowledge_import():
    """Test that Knowledge class can be imported"""
    from praisonaiagents.knowledge import Knowledge
    assert Knowledge is not None, "Knowledge class should be importable"
    🧰 Tools
    🪛 Ruff (0.11.9)

    15-15: praisonaiagents.memory.Memory imported but unused; consider using importlib.util.find_spec to test for availability

    (F401)


    25-25: praisonaiagents.knowledge.Knowledge imported but unused; consider using importlib.util.find_spec to test for availability

    (F401)

    🪛 Pylint (3.3.7)

    [convention] 15-15: Import outside toplevel (praisonaiagents.memory.Memory)

    (C0415)


    [warning] 15-15: Unused Memory imported from praisonaiagents.memory

    (W0611)


    [convention] 25-25: Import outside toplevel (praisonaiagents.knowledge.Knowledge)

    (C0415)


    [warning] 25-25: Unused Knowledge imported from praisonaiagents.knowledge

    (W0611)

    🤖 Prompt for AI Agents
    In src/praisonai/tests/unit/test_graph_memory.py around lines 12 to 31, the test
    functions use print statements and return boolean values instead of proper
    assertions, which is not standard for unit tests. Refactor these test functions
    to remove print statements and return values, and instead use assert statements
    to verify that the imports succeed. This will make the tests compatible with
    standard test frameworks and improve test clarity.
    

    - Enhanced readability by formatting command execution in `test_agent_with_auto_approval`.
    - Updated import path handling in `test_approval_basic` for consistency.
    - Simplified error handling in various test functions to assert failures directly.
    - Ensured adherence to minimal code change principles while maintaining functionality.
    Copy link
    Copy Markdown
    Contributor

    @coderabbitai coderabbitai Bot left a comment

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Actionable comments posted: 2

    ♻️ Duplicate comments (4)
    src/praisonai/tests/unit/test_approval_basic.py (4)

    13-13: Fix line length.

    The path manipulation line exceeds the 100-character limit.

    This is the same issue as in the other test file and should be addressed consistently.

    🧰 Tools
    🪛 Pylint (3.3.7)

    [convention] 13-13: Line too long (114/100)

    (C0301)


    33-33: Replace assert False with proper exception raising.

    Same issue as in test_decorator_enforcement.py - assert False should be replaced with explicit raise AssertionError().

    Also applies to: 209-209

    🧰 Tools
    🪛 Ruff (0.11.9)

    33-33: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    119-127: Address missing Python tool dependencies.

    The PythonTools test will fail due to missing dependencies (black, autopep8) as noted in previous reviews. Consider using pytest.importorskip or adding these to test requirements.

    🧰 Tools
    🪛 Ruff (0.11.9)

    120-120: Local variable python_tools is assigned to but never used

    Remove assignment to unused variable python_tools

    (F841)

    🪛 Pylint (3.3.7)

    [convention] 121-121: Trailing whitespace

    (C0303)


    [convention] 125-125: Trailing whitespace

    (C0303)


    [warning] 126-126: Catching too general exception Exception

    (W0718)


    [error] 119-119: Unable to import 'praisonaiagents.tools.python_tools'

    (E0401)


    [convention] 119-119: Import outside toplevel (praisonaiagents.tools.python_tools.PythonTools)

    (C0415)


    [warning] 120-120: Unused variable 'python_tools'

    (W0612)


    15-34: Improve import testing to address unused import warnings.

    The import test loads modules but doesn't use them, causing static analysis warnings. Consider using the imported items in simple assertions to make the test more meaningful.

    🧰 Tools
    🪛 Ruff (0.11.9)

    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)


    33-33: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)

    🪛 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)

    🧹 Nitpick comments (5)
    src/praisonai/tests/unit/test_decorator_enforcement.py (4)

    10-10: Fix line length and consider path readability.

    The path manipulation line exceeds the 100-character limit and is quite complex.

    -sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..', 'praisonai-agents')))
    +# Navigate to praisonai-agents directory
    +agents_path = os.path.abspath(os.path.join(
    +    os.path.dirname(__file__), '..', '..', '..', 'praisonai-agents'
    +))
    +sys.path.insert(0, agents_path)
    🧰 Tools
    🪛 Pylint (3.3.7)

    [convention] 10-10: Line too long (114/100)

    (C0301)


    21-21: Address unused function parameters.

    The callback function has unused parameters that should be prefixed with underscore to indicate they're intentionally unused.

    -        def auto_deny_callback(function_name, arguments, risk_level):
    +        def auto_deny_callback(_function_name, _arguments, _risk_level):
    🧰 Tools
    🪛 Pylint (3.3.7)

    [warning] 21-21: Unused argument 'function_name'

    (W0613)


    [warning] 21-21: Unused argument 'arguments'

    (W0613)


    [warning] 21-21: Unused argument 'risk_level'

    (W0613)


    34-34: Remove unused variable assignment.

    The result variable is assigned but never used, and the static analysis correctly identifies this.

    -            result = test_function("dangerous command")
    +            test_function("dangerous command")
    🧰 Tools
    🪛 Ruff (0.11.9)

    34-34: Local variable result is assigned to but never used

    Remove assignment to unused variable result

    (F841)

    🪛 Pylint (3.3.7)

    [warning] 34-34: Unused variable 'result'

    (W0612)


    49-49: Add missing final newline.

    The file is missing a final newline, which is a common convention in Python files.

    -    print("🎉 Decorator enforcement test completed!")
    +    print("🎉 Decorator enforcement test completed!")
    +
    🧰 Tools
    🪛 Pylint (3.3.7)

    [convention] 49-49: Final newline missing

    (C0304)

    src/praisonai/tests/unit/test_approval_basic.py (1)

    74-74: Address unused parameter in callback function.

    The arguments parameter is unused and should be prefixed with underscore.

    -    def auto_approve_callback(function_name, arguments, risk_level):
    +    def auto_approve_callback(function_name, _arguments, risk_level):
    🧰 Tools
    🪛 Pylint (3.3.7)

    [warning] 74-74: Unused argument 'arguments'

    (W0613)

    📜 Review details

    Configuration used: CodeRabbit UI
    Review profile: CHILL
    Plan: Pro

    📥 Commits

    Reviewing files that changed from the base of the PR and between 460d515 and 1c6afda.

    📒 Files selected for processing (3)
    • src/praisonai/tests/unit/test_approval_agent_integration.py (1 hunks)
    • src/praisonai/tests/unit/test_approval_basic.py (6 hunks)
    • src/praisonai/tests/unit/test_decorator_enforcement.py (1 hunks)
    ✅ Files skipped from review due to trivial changes (1)
    • src/praisonai/tests/unit/test_approval_agent_integration.py
    🧰 Additional context used
    🪛 Ruff (0.11.9)
    src/praisonai/tests/unit/test_decorator_enforcement.py

    34-34: Local variable result is assigned to but never used

    Remove assignment to unused variable result

    (F841)


    36-36: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    41-41: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    45-45: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)

    src/praisonai/tests/unit/test_approval_basic.py

    33-33: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    209-209: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    222-222: Local variable e is assigned to but never used

    Remove assignment to unused variable e

    (F841)


    228-228: Local variable e is assigned to but never used

    Remove assignment to unused variable e

    (F841)


    234-234: Local variable e is assigned to but never used

    Remove assignment to unused variable e

    (F841)


    240-240: Local variable e is assigned to but never used

    Remove assignment to unused variable e

    (F841)


    246-246: Local variable e is assigned to but never used

    Remove assignment to unused variable e

    (F841)

    🪛 Pylint (3.3.7)
    src/praisonai/tests/unit/test_decorator_enforcement.py

    [convention] 10-10: Line too long (114/100)

    (C0301)


    [convention] 16-16: Trailing whitespace

    (C0303)


    [convention] 18-18: Line too long (102/100)

    (C0301)


    [convention] 19-19: Trailing whitespace

    (C0303)


    [convention] 23-23: Trailing whitespace

    (C0303)


    [convention] 25-25: Trailing whitespace

    (C0303)


    [convention] 30-30: Trailing whitespace

    (C0303)


    [convention] 32-32: Trailing whitespace

    (C0303)


    [convention] 42-42: Trailing whitespace

    (C0303)


    [convention] 49-49: Final newline missing

    (C0304)


    [warning] 43-43: Catching too general exception Exception

    (W0718)


    [error] 18-18: Unable to import 'praisonaiagents.approval'

    (E0401)


    [convention] 18-18: Import outside toplevel (praisonaiagents.approval.require_approval, praisonaiagents.approval.set_approval_callback, praisonaiagents.approval.ApprovalDecision)

    (C0415)


    [warning] 21-21: Unused argument 'function_name'

    (W0613)


    [warning] 21-21: Unused argument 'arguments'

    (W0613)


    [warning] 21-21: Unused argument 'risk_level'

    (W0613)


    [warning] 39-39: Catching too general exception Exception

    (W0718)


    [warning] 34-34: Unused variable 'result'

    (W0612)

    src/praisonai/tests/unit/test_approval_basic.py

    [convention] 13-13: Line too long (114/100)

    (C0301)


    [convention] 69-69: Line too long (136/100)

    (C0301)


    [convention] 70-70: Trailing whitespace

    (C0303)


    [convention] 72-72: Trailing whitespace

    (C0303)


    [convention] 77-77: Trailing whitespace

    (C0303)


    [convention] 79-79: Trailing whitespace

    (C0303)


    [error] 69-69: Unable to import 'praisonaiagents.approval'

    (E0401)


    [convention] 69-69: Import outside toplevel (praisonaiagents.approval.require_approval, praisonaiagents.approval.is_approval_required, praisonaiagents.approval.get_risk_level, praisonaiagents.approval.set_approval_callback, praisonaiagents.approval.ApprovalDecision)

    (C0415)


    [warning] 74-74: Unused argument 'arguments'

    (W0613)


    [convention] 224-224: Trailing whitespace

    (C0303)


    [convention] 230-230: Trailing whitespace

    (C0303)


    [convention] 236-236: Trailing whitespace

    (C0303)


    [convention] 242-242: Trailing whitespace

    (C0303)


    [convention] 248-248: Trailing whitespace

    (C0303)


    [warning] 222-222: Catching too general exception Exception

    (W0718)


    [warning] 228-228: Catching too general exception Exception

    (W0718)


    [warning] 234-234: Catching too general exception Exception

    (W0718)


    [warning] 240-240: Catching too general exception Exception

    (W0718)


    [warning] 246-246: Catching too general exception Exception

    (W0718)


    [warning] 222-223: Unused variable 'e'

    (W0612)

    ⏰ Context from checks skipped due to timeout of 90000ms (2)
    • GitHub Check: build (3.10)
    • GitHub Check: build (3.11)
    🔇 Additional comments (2)
    src/praisonai/tests/unit/test_decorator_enforcement.py (1)

    12-46: LGTM: Improved test structure with local decorated function.

    The refactoring to use a local decorated test function instead of importing ShellTools is a good approach. This makes the test more focused and self-contained for testing decorator enforcement specifically.

    🧰 Tools
    🪛 Ruff (0.11.9)

    34-34: Local variable result is assigned to but never used

    Remove assignment to unused variable result

    (F841)


    36-36: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    41-41: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    45-45: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)

    🪛 Pylint (3.3.7)

    [convention] 16-16: Trailing whitespace

    (C0303)


    [convention] 18-18: Line too long (102/100)

    (C0301)


    [convention] 19-19: Trailing whitespace

    (C0303)


    [convention] 23-23: Trailing whitespace

    (C0303)


    [convention] 25-25: Trailing whitespace

    (C0303)


    [convention] 30-30: Trailing whitespace

    (C0303)


    [convention] 32-32: Trailing whitespace

    (C0303)


    [convention] 42-42: Trailing whitespace

    (C0303)


    [warning] 43-43: Catching too general exception Exception

    (W0718)


    [error] 18-18: Unable to import 'praisonaiagents.approval'

    (E0401)


    [convention] 18-18: Import outside toplevel (praisonaiagents.approval.require_approval, praisonaiagents.approval.set_approval_callback, praisonaiagents.approval.ApprovalDecision)

    (C0415)


    [warning] 21-21: Unused argument 'function_name'

    (W0613)


    [warning] 21-21: Unused argument 'arguments'

    (W0613)


    [warning] 21-21: Unused argument 'risk_level'

    (W0613)


    [warning] 39-39: Catching too general exception Exception

    (W0718)


    [warning] 34-34: Unused variable 'result'

    (W0612)

    src/praisonai/tests/unit/test_approval_basic.py (1)

    69-79: Good improvement: Added auto-approval callback for testing.

    The addition of the auto-approval callback setup makes the decorator test more robust and ensures decorated functions can execute during testing.

    🧰 Tools
    🪛 Pylint (3.3.7)

    [convention] 69-69: Line too long (136/100)

    (C0301)


    [convention] 70-70: Trailing whitespace

    (C0303)


    [convention] 72-72: Trailing whitespace

    (C0303)


    [convention] 77-77: Trailing whitespace

    (C0303)


    [convention] 79-79: Trailing whitespace

    (C0303)


    [error] 69-69: Unable to import 'praisonaiagents.approval'

    (E0401)


    [convention] 69-69: Import outside toplevel (praisonaiagents.approval.require_approval, praisonaiagents.approval.is_approval_required, praisonaiagents.approval.get_risk_level, praisonaiagents.approval.set_approval_callback, praisonaiagents.approval.ApprovalDecision)

    (C0415)


    [warning] 74-74: Unused argument 'arguments'

    (W0613)

    return True
    result = test_function("dangerous command")
    print("❌ Command executed when it should have been denied!")
    assert False, "Command executed when it should have been denied!"
    Copy link
    Copy Markdown
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    🛠️ Refactor suggestion

    Replace assert False with proper exception raising.

    Using assert False is problematic because Python's optimization mode (python -O) removes these calls. Use explicit exception raising instead.

    -            assert False, "Command executed when it should have been denied!"
    +            raise AssertionError("Command executed when it should have been denied!")
    -            assert False, f"Unexpected error: {e}"
    +            raise AssertionError(f"Unexpected error: {e}")
    -        assert False, f"Test failed: {e}"
    +        raise AssertionError(f"Test failed: {e}")

    Also applies to: 41-41, 45-45

    🧰 Tools
    🪛 Ruff (0.11.9)

    36-36: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)

    🤖 Prompt for AI Agents
    In src/praisonai/tests/unit/test_decorator_enforcement.py at lines 36, 41, and
    45, replace the use of 'assert False' with explicit exception raising, such as
    raising a RuntimeError with the same message. This ensures the error is always
    raised regardless of Python optimization mode.
    

    Comment on lines +219 to +247
    try:
    test_imports()
    test_results.append(("Imports", True))
    except Exception as e:
    test_results.append(("Imports", False))

    try:
    test_approval_configuration()
    test_results.append(("Configuration", True))
    except Exception as e:
    test_results.append(("Configuration", False))

    try:
    test_approval_decorator()
    test_results.append(("Decorator", True))
    except Exception as e:
    test_results.append(("Decorator", False))

    try:
    test_tool_integration()
    test_results.append(("Tool Integration", True))
    except Exception as e:
    test_results.append(("Tool Integration", False))

    try:
    test_agent_integration()
    test_results.append(("Agent Integration", True))
    except Exception as e:
    test_results.append(("Agent Integration", False))
    Copy link
    Copy Markdown
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    🛠️ Refactor suggestion

    Improve exception handling in main test runner.

    The current approach catches exceptions but doesn't use the exception information, leading to unused variable warnings. Also, the main runner still doesn't fully embrace pytest patterns.

         try:
             test_imports()
             test_results.append(("Imports", True))
    -    except Exception as e:
    +    except Exception:
             test_results.append(("Imports", False))

    Apply similar changes to all other exception handlers. However, consider transitioning to proper pytest structure:

    -def main():
    -    """Run all approval system tests."""
    -    # ... current implementation
    +# Remove main() function and convert to individual pytest test functions
    +def test_imports_pytest():
    +    """Test that all the new approval imports work correctly."""
    +    # Move test_imports() content here
    +
    +def test_approval_configuration_pytest():
    +    """Test approval requirement configuration."""  
    +    # Move test_approval_configuration() content here
    +
    +# etc. for other tests

    Committable suggestion skipped: line range outside the PR's diff.

    🧰 Tools
    🪛 Ruff (0.11.9)

    222-222: Local variable e is assigned to but never used

    Remove assignment to unused variable e

    (F841)


    228-228: Local variable e is assigned to but never used

    Remove assignment to unused variable e

    (F841)


    234-234: Local variable e is assigned to but never used

    Remove assignment to unused variable e

    (F841)


    240-240: Local variable e is assigned to but never used

    Remove assignment to unused variable e

    (F841)


    246-246: Local variable e is assigned to but never used

    Remove assignment to unused variable e

    (F841)

    🪛 Pylint (3.3.7)

    [convention] 224-224: Trailing whitespace

    (C0303)


    [convention] 230-230: Trailing whitespace

    (C0303)


    [convention] 236-236: Trailing whitespace

    (C0303)


    [convention] 242-242: Trailing whitespace

    (C0303)


    [warning] 222-222: Catching too general exception Exception

    (W0718)


    [warning] 228-228: Catching too general exception Exception

    (W0718)


    [warning] 234-234: Catching too general exception Exception

    (W0718)


    [warning] 240-240: Catching too general exception Exception

    (W0718)


    [warning] 246-246: Catching too general exception Exception

    (W0718)


    [warning] 222-223: Unused variable 'e'

    (W0612)

    🤖 Prompt for AI Agents
    In src/praisonai/tests/unit/test_approval_basic.py lines 219 to 247, the
    exception handlers catch exceptions but do not use the exception variable,
    causing unused variable warnings. To fix this, remove the unused exception
    variable from all except clauses. Additionally, refactor the main test runner to
    use pytest's native assertion and test discovery features instead of manual
    try-except blocks, which will improve test clarity and integration with pytest.
    

    … files
    
    - Updated import paths in multiple test files for consistency and clarity.
    - Improved error handling in approval tests to assert failures directly.
    - Ensured minimal code changes while maintaining existing functionality and readability.
    Copy link
    Copy Markdown
    Contributor

    @coderabbitai coderabbitai Bot left a comment

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Actionable comments posted: 3

    ♻️ Duplicate comments (2)
    src/praisonai/tests/unit/test_approval_interactive.py (2)

    48-48: Replace assert False with raise AssertionError() for optimization compatibility.

    Same issue as in the first file - assert False statements are removed during Python optimization, which could mask test failures.

    Also applies to: 52-52, 91-91, 95-95, 141-141, 145-145, 172-172, 176-176, 203-203, 207-207

    🧰 Tools
    🪛 Ruff (0.11.9)

    48-48: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    244-315: Interactive main() function still conflicts with automated testing.

    The interactive CLI in the main() function continues to pose issues for automated testing environments, as noted in previous reviews. The pipeline failures confirm this is causing stdin capture conflicts with pytest.

    🧰 Tools
    🪛 Pylint (3.3.7)

    [convention] 249-249: Trailing whitespace

    (C0303)


    [convention] 256-256: Trailing whitespace

    (C0303)


    [convention] 266-266: Trailing whitespace

    (C0303)


    [convention] 274-274: Trailing whitespace

    (C0303)


    [convention] 281-281: Final newline missing

    (C0304)


    [warning] 277-277: Catching too general exception Exception

    (W0718)

    🧹 Nitpick comments (2)
    src/praisonai/tests/unit/test_decorator_simple.py (1)

    10-10: Refactor path insertion for clarity and maintainability
    The sys.path.insert call is quite long and brittle. You can simplify it with pathlib, break it into meaningful steps, or—better yet—move this logic into a central conftest.py so individual tests don’t need their own sys.path hacks.

    -from praisonai/tests/unit/test_decorator_simple.py:10
    -sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__),
    -                                               '..', '..', '..',
    -                                               'praisonai-agents')))
    +from pathlib import Path
    +
    +# Insert praisonai-agents root into PYTHONPATH
    +agents_dir = Path(__file__).resolve().parents[3] / 'praisonai-agents'
    +sys.path.insert(0, str(agents_dir))

    Consider configuring pytest’s pythonpath in pytest.ini or using a conftest.py fixture instead of per-file modifications.

    🧰 Tools
    🪛 Pylint (3.3.7)

    [convention] 10-10: Line too long (114/100)

    (C0301)

    🪛 GitHub Actions: Core Tests

    [error] Test failed: Expected None, but test returned True. Did you mean to use assert instead of return?

    src/praisonai/tests/unit/test_ollama_fix.py (1)

    9-9: 🏷️ Line too long (Pylint C0301)
    The insertion statement is 114 characters, exceeding the 100-character limit. Consider breaking it up or using a temporary variable for clarity. For example:

    # Compute absolute path for praisonai-agents
    agents_dir = os.path.abspath(
        os.path.join(
            os.path.dirname(__file__),
            "..", "..", "..",
            "praisonai-agents"
        )
    )
    sys.path.insert(0, agents_dir)

    Or, with pathlib:

    from pathlib import Path
    agents_dir = Path(__file__).resolve().parents[3] / "praisonai-agents"
    sys.path.insert(0, str(agents_dir))
    🧰 Tools
    🪛 Pylint (3.3.7)

    [convention] 9-9: Line too long (114/100)

    (C0301)

    📜 Review details

    Configuration used: CodeRabbit UI
    Review profile: CHILL
    Plan: Pro

    📥 Commits

    Reviewing files that changed from the base of the PR and between 1c6afda and fcd9866.

    📒 Files selected for processing (5)
    • src/praisonai/tests/unit/test_approval_agent_integration.py (7 hunks)
    • src/praisonai/tests/unit/test_approval_interactive.py (6 hunks)
    • src/praisonai/tests/unit/test_decorator_simple.py (1 hunks)
    • src/praisonai/tests/unit/test_graph_memory.py (1 hunks)
    • src/praisonai/tests/unit/test_ollama_fix.py (1 hunks)
    🧰 Additional context used
    🧬 Code Graph Analysis (1)
    src/praisonai/tests/unit/test_approval_interactive.py (1)
    src/praisonai-agents/praisonaiagents/tools/file_tools.py (1)
    • delete_file (186-202)
    🪛 Pylint (3.3.7)
    src/praisonai/tests/unit/test_approval_interactive.py

    [convention] 15-15: Line too long (114/100)

    (C0301)


    [convention] 49-49: Trailing whitespace

    (C0303)


    [warning] 50-50: Catching too general exception Exception

    (W0718)


    [convention] 92-92: Trailing whitespace

    (C0303)


    [warning] 93-93: Catching too general exception Exception

    (W0718)


    [convention] 129-129: Trailing whitespace

    (C0303)


    [convention] 133-133: Trailing whitespace

    (C0303)


    [convention] 134-134: Line too long (118/100)

    (C0301)


    [convention] 142-142: Trailing whitespace

    (C0303)


    [warning] 143-143: Catching too general exception Exception

    (W0718)


    [convention] 173-173: Trailing whitespace

    (C0303)


    [warning] 174-174: Catching too general exception Exception

    (W0718)


    [convention] 204-204: Trailing whitespace

    (C0303)


    [warning] 205-205: Catching too general exception Exception

    (W0718)

    src/praisonai/tests/unit/test_approval_agent_integration.py

    [convention] 15-15: Line too long (114/100)

    (C0301)


    [convention] 58-58: Trailing whitespace

    (C0303)


    [warning] 59-59: Catching too general exception Exception

    (W0718)


    [convention] 94-94: Trailing whitespace

    (C0303)


    [convention] 100-100: Trailing whitespace

    (C0303)


    [warning] 101-101: Catching too general exception Exception

    (W0718)


    [convention] 139-139: Trailing whitespace

    (C0303)


    [convention] 148-148: Trailing whitespace

    (C0303)


    [convention] 155-155: Trailing whitespace

    (C0303)


    [warning] 140-140: Catching too general exception Exception

    (W0718)


    [convention] 151-151: Import outside toplevel (black, pylint, autopep8)

    (C0415)


    [convention] 151-151: Multiple imports on one line (black, pylint, autopep8)

    (C0410)


    [warning] 151-151: Unused import black

    (W0611)


    [warning] 151-151: Unused import pylint

    (W0611)


    [warning] 151-151: Unused import autopep8

    (W0611)


    [convention] 178-178: Trailing whitespace

    (C0303)


    [convention] 181-181: Trailing whitespace

    (C0303)


    [convention] 187-187: Trailing whitespace

    (C0303)


    [warning] 188-188: Catching too general exception Exception

    (W0718)


    [convention] 225-225: Line too long (129/100)

    (C0301)


    [convention] 227-227: Trailing whitespace

    (C0303)


    [convention] 239-239: Trailing whitespace

    (C0303)


    [warning] 230-230: Redefining name 'os' from outer scope (line 10)

    (W0621)


    [warning] 240-240: Catching too general exception Exception

    (W0718)


    [warning] 234-234: Catching too general exception Exception

    (W0718)


    [warning] 230-230: Reimport 'os' (imported line 10)

    (W0404)


    [convention] 230-230: Import outside toplevel (os)

    (C0415)

    src/praisonai/tests/unit/test_decorator_simple.py

    [convention] 10-10: Line too long (114/100)

    (C0301)

    src/praisonai/tests/unit/test_graph_memory.py

    [convention] 10-10: Line too long (114/100)

    (C0301)

    src/praisonai/tests/unit/test_ollama_fix.py

    [convention] 9-9: Line too long (114/100)

    (C0301)

    🪛 Ruff (0.11.9)
    src/praisonai/tests/unit/test_approval_interactive.py

    48-48: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    52-52: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    91-91: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    95-95: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    141-141: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    145-145: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    172-172: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    176-176: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    203-203: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    207-207: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)

    src/praisonai/tests/unit/test_approval_agent_integration.py

    57-57: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    61-61: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    99-99: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    103-103: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    138-138: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    142-142: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    151-151: black imported but unused; consider using importlib.util.find_spec to test for availability

    (F401)


    151-151: pylint imported but unused; consider using importlib.util.find_spec to test for availability

    (F401)


    151-151: autopep8 imported but unused; consider using importlib.util.find_spec to test for availability

    (F401)


    186-186: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    190-190: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    238-238: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    242-242: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)

    🪛 GitHub Actions: Core Tests
    src/praisonai/tests/unit/test_approval_agent_integration.py

    [error] 99-103: Auto-approval test failed: Auto-approved command failed due to tool execution denied with approval error: pytest reading from stdin while output is captured. Consider using -s.


    [error] 238-242: File operations test failed: File creation failed due to tool execution denied with approval error: pytest reading from stdin while output is captured. Consider using -s.

    src/praisonai/tests/unit/test_decorator_simple.py

    [error] Test failed: Expected None, but test returned True. Did you mean to use assert instead of return?

    src/praisonai/tests/unit/test_graph_memory.py

    [error] Test failed: Expected None, but test returned False. Did you mean to use assert instead of return? Failed to import Memory: cannot import name 'Memory' from 'praisonaiagents.memory'.


    [error] Test failed: Expected None, but test returned True. Did you mean to use assert instead of return? Knowledge class imported successfully.


    [error] Test failed: Expected None, but test returned False. Did you mean to use assert instead of return? Memory configuration test failed: cannot import name 'Memory' from 'praisonaiagents.memory'.


    [error] Test failed: Expected None, but test returned False. Did you mean to use assert instead of return? Knowledge configuration test failed: Required packages not installed. Please install using: pip install "praisonaiagents[knowledge]".

    🪛 GitHub Actions: Quick Validation Tests
    src/praisonai/tests/unit/test_approval_agent_integration.py

    [error] 99-103: Test 'test_agent_with_auto_approval' failed due to tool execution denial: Approval error caused by pytest reading from stdin while output is captured. Suggestion: run pytest with '-s' option.

    ⏰ Context from checks skipped due to timeout of 90000ms (2)
    • GitHub Check: build (3.10)
    • GitHub Check: build (3.11)
    🔇 Additional comments (10)
    src/praisonai/tests/unit/test_ollama_fix.py (1)

    9-9: ✅ Prefer absolute paths for import resolution
    Switching from a relative to an absolute path via os.path.abspath ensures that the praisonai-agents directory is correctly located regardless of the current working directory when running tests. This change aligns with best practices for modifying sys.path.

    🧰 Tools
    🪛 Pylint (3.3.7)

    [convention] 9-9: Line too long (114/100)

    (C0301)

    src/praisonai/tests/unit/test_graph_memory.py (1)

    10-10:

    Details

    ✅ Verification successful

    Verify and refine the Python path insertion.

    The updated sys.path.insert targets praisonai-agents, but please ensure that the praisonai-agents directory exists at this relative location and contains the praisonaiagents package (e.g., praisonaiagents/memory.py). Incorrect paths here are the root cause of the ImportError: cannot import name 'Memory' failures in CI.

    Optionally, for readability and to satisfy the line-length limit, you could refactor this using pathlib and intermediate variables:

    -from praisonaiagents import os, sys
    -sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..', 'praisonai-agents')))
    +from pathlib import Path
    +project_root = Path(__file__).resolve().parents[3]
    +sys.path.insert(0, str(project_root / 'praisonai-agents'))

    To verify the actual structure, you can run:


    🏁 Script executed:

    #!/bin/bash
    # Verify presence of the Memory module in the target directory
    fd 'praisonaiagents/memory.py' praisonai-agents

    Length of output: 151


    🏁 Script executed:

    #!/bin/bash
    # Locate the module directory and Memory implementation
    echo "Searching for 'praisonaiagents' directories..."
    fd -t d praisonaiagents
    echo "Searching for 'praisonai-agents' directories..."
    fd -t d praisonai-agents
    echo "Searching for any memory.py in the repo..."
    fd -t f memory.py

    Length of output: 621


    Sys.path insertion verified

    • The directory src/praisonai-agents/ exists and contains the package praisonaiagents/memory/memory.py.
    • The relative path in
      sys.path.insert(0, os.path.abspath(os.path.join(
          os.path.dirname(__file__), '..', '..', '..', 'praisonai-agents'
      )))
      correctly points to src/praisonai-agents, so the ImportError isn’t caused by a missing directory.

    No changes required. You may optionally refactor to pathlib for readability as previously suggested.

    🧰 Tools
    🪛 Pylint (3.3.7)

    [convention] 10-10: Line too long (114/100)

    (C0301)

    🪛 GitHub Actions: Core Tests

    [error] Test failed: Expected None, but test returned False. Did you mean to use assert instead of return? Failed to import Memory: cannot import name 'Memory' from 'praisonaiagents.memory'.


    [error] Test failed: Expected None, but test returned True. Did you mean to use assert instead of return? Knowledge class imported successfully.


    [error] Test failed: Expected None, but test returned False. Did you mean to use assert instead of return? Memory configuration test failed: cannot import name 'Memory' from 'praisonaiagents.memory'.


    [error] Test failed: Expected None, but test returned False. Did you mean to use assert instead of return? Knowledge configuration test failed: Required packages not installed. Please install using: pip install "praisonaiagents[knowledge]".

    src/praisonai/tests/unit/test_approval_agent_integration.py (5)

    15-15: Path resolution improvement looks good.

    The change to use absolute path resolution is consistent with similar improvements across other test files and helps ensure reliable module discovery.

    🧰 Tools
    🪛 Pylint (3.3.7)

    [convention] 15-15: Line too long (114/100)

    (C0301)


    44-44: Improved result validation logic.

    The change from checking dictionary keys to using substring validation in string representation is more robust and flexible. The addition of assertions instead of returning boolean values properly integrates with pytest.

    Also applies to: 53-61


    90-93: Good formatting improvement for readability.

    The multi-line formatting for the execute_tool call improves code readability without changing functionality.


    228-235: File cleanup improvement is safer and more appropriate.

    The change from using agent deletion to direct os.remove with proper exception handling is a good improvement. This avoids potential test failures due to cleanup issues and is more appropriate for unit tests.

    🧰 Tools
    🪛 Pylint (3.3.7)

    [warning] 230-230: Redefining name 'os' from outer scope (line 10)

    (W0621)


    [warning] 234-234: Catching too general exception Exception

    (W0718)


    [warning] 230-230: Reimport 'os' (imported line 10)

    (W0404)


    [convention] 230-230: Import outside toplevel (os)

    (C0415)


    99-103:

    Details

    ❌ Incorrect review comment

    Pipeline failures indicate stdin capture issues with approval system.

    The test failures suggest that the approval system is trying to read from stdin even when auto-approval callbacks are set, causing conflicts with pytest's output capture.

    This appears to be a deeper issue with the approval system integration. Run this script to investigate how the approval callbacks are being invoked:

    Also applies to: 238-242


    🏁 Script executed:

    #!/bin/bash
    # Description: Search for approval callback usage and stdin interactions in the approval system
    
    # Look for approval callback implementations and stdin usage
    echo "=== Searching for approval callback patterns ==="
    rg -A 10 -B 5 "set_approval_callback|console_approval_callback" --type py
    
    echo -e "\n=== Searching for stdin usage in approval system ==="
    rg -A 5 -B 5 "input\(|stdin" --type py
    
    echo -e "\n=== Searching for approval decision logic ==="
    ast-grep --pattern 'def $_($$$) {
      $$$
      return ApprovalDecision($$$)
      $$$
    }'

    Length of output: 66491


    Ignore stdin capture issues—no input reads in auto-approval tests

    The auto-approval callbacks and the test snippet at lines 99–103 do not invoke input() or read from stdin, so pytest’s output capture isn’t at fault here. The failures stem from the test logic itself (for example, an unexpected return value from shell_tools.execute_command), not from the approval system blocking on stdin. Please verify the command execution results and adjust the assertions or mock behavior accordingly.

    Likely an incorrect or invalid review comment.

    🧰 Tools
    🪛 Ruff (0.11.9)

    99-99: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    103-103: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)

    🪛 Pylint (3.3.7)

    [convention] 100-100: Trailing whitespace

    (C0303)


    [warning] 101-101: Catching too general exception Exception

    (W0718)

    🪛 GitHub Actions: Core Tests

    [error] 99-103: Auto-approval test failed: Auto-approved command failed due to tool execution denied with approval error: pytest reading from stdin while output is captured. Consider using -s.

    🪛 GitHub Actions: Quick Validation Tests

    [error] 99-103: Test 'test_agent_with_auto_approval' failed due to tool execution denial: Approval error caused by pytest reading from stdin while output is captured. Suggestion: run pytest with '-s' option.

    src/praisonai/tests/unit/test_approval_interactive.py (3)

    15-15: Path resolution improvement consistent with other test files.

    This change aligns with the broader refactoring across the test suite for reliable module discovery.

    🧰 Tools
    🪛 Pylint (3.3.7)

    [convention] 15-15: Line too long (114/100)

    (C0301)


    44-48: Consistent result validation improvements across all test functions.

    The shift from dictionary key checks to substring validation provides more flexible and robust result checking across all approval test scenarios.

    Also applies to: 87-91, 127-128, 168-169, 199-199

    🧰 Tools
    🪛 Ruff (0.11.9)

    48-48: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    134-139: Smart handling of file deletion failures.

    The decision to not fail the test when file deletion fails is appropriate for cleanup operations, preventing test failures due to filesystem issues unrelated to the core approval functionality.

    🧰 Tools
    🪛 Pylint (3.3.7)

    [convention] 134-134: Line too long (118/100)

    (C0301)

    Comment on lines +149 to +155
    # Check if required packages are available - skip if not
    try:
    import black, pylint, autopep8
    except ImportError:
    print("⚠️ Skipping Python code test - missing optional packages (black, pylint, autopep8)")
    pytest.skip("Optional Python tools not available")

    Copy link
    Copy Markdown
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    🛠️ Refactor suggestion

    Smart dependency checking, but import handling needs refinement.

    The optional dependency checking is a good practice, but the import approach violates static analysis rules.

    Replace the current import approach with importlib.util.find_spec:

    -    # Check if required packages are available - skip if not
    -    try:
    -        import black, pylint, autopep8
    -    except ImportError:
    -        print("⚠️ Skipping Python code test - missing optional packages (black, pylint, autopep8)")
    -        pytest.skip("Optional Python tools not available")
    +    # Check if required packages are available - skip if not
    +    import importlib.util
    +    missing_packages = []
    +    for package in ['black', 'pylint', 'autopep8']:
    +        if importlib.util.find_spec(package) is None:
    +            missing_packages.append(package)
    +    
    +    if missing_packages:
    +        print(f"⚠️ Skipping Python code test - missing optional packages: {', '.join(missing_packages)}")
    +        pytest.skip(f"Optional Python tools not available: {', '.join(missing_packages)}")
    📝 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.

    Suggested change
    # Check if required packages are available - skip if not
    try:
    import black, pylint, autopep8
    except ImportError:
    print("⚠️ Skipping Python code test - missing optional packages (black, pylint, autopep8)")
    pytest.skip("Optional Python tools not available")
    # Check if required packages are available - skip if not
    import importlib.util
    missing_packages = []
    for package in ['black', 'pylint', 'autopep8']:
    if importlib.util.find_spec(package) is None:
    missing_packages.append(package)
    if missing_packages:
    print(f"⚠️ Skipping Python code test - missing optional packages: {', '.join(missing_packages)}")
    pytest.skip(f"Optional Python tools not available: {', '.join(missing_packages)}")
    🧰 Tools
    🪛 Ruff (0.11.9)

    151-151: black imported but unused; consider using importlib.util.find_spec to test for availability

    (F401)


    151-151: pylint imported but unused; consider using importlib.util.find_spec to test for availability

    (F401)


    151-151: autopep8 imported but unused; consider using importlib.util.find_spec to test for availability

    (F401)

    🪛 Pylint (3.3.7)

    [convention] 155-155: Trailing whitespace

    (C0303)


    [convention] 151-151: Import outside toplevel (black, pylint, autopep8)

    (C0415)


    [convention] 151-151: Multiple imports on one line (black, pylint, autopep8)

    (C0410)


    [warning] 151-151: Unused import black

    (W0611)


    [warning] 151-151: Unused import pylint

    (W0611)


    [warning] 151-151: Unused import autopep8

    (W0611)

    🤖 Prompt for AI Agents
    In src/praisonai/tests/unit/test_approval_agent_integration.py around lines 149
    to 155, the current import of optional packages black, pylint, and autopep8
    inside a try-except block violates static analysis rules. Replace this with
    importlib.util.find_spec to check for the presence of these packages without
    importing them. Use find_spec for each package and if any are missing, print the
    warning and call pytest.skip to skip the test.
    

    else:
    print(f"⚠️ Command failed for other reasons: {result}")
    print("❌ Command execution failed:", result)
    assert False, f"Command execution failed: {result}"
    Copy link
    Copy Markdown
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    ⚠️ Potential issue

    Replace assert False with raise AssertionError() for optimization compatibility.

    The static analysis correctly identifies that assert False statements are removed when Python runs with optimization (python -O), which could mask test failures in production.

    Apply this pattern throughout the file:

    -            assert False, f"Command execution failed: {result}"
    +            raise AssertionError(f"Command execution failed: {result}")

    Also applies to: 61-61, 99-99, 103-103, 138-138, 142-142, 186-186, 190-190, 238-238, 242-242

    🧰 Tools
    🪛 Ruff (0.11.9)

    57-57: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)

    🤖 Prompt for AI Agents
    In src/praisonai/tests/unit/test_approval_agent_integration.py at lines 57, 61,
    99, 103, 138, 142, 186, 190, 238, and 242, replace all instances of 'assert
    False, <message>' with 'raise AssertionError(<message>)' to ensure test failures
    are not ignored when Python runs with optimization flags. This change prevents
    the removal of these failure checks during optimized execution.
    

    Comment on lines +199 to +203
    if result and ("denied" in str(result).lower() or "approval" in str(result).lower()):
    print("✅ Command was correctly denied by approval system")
    elif result.get('success'):
    print("❌ Command executed when it should have been denied")
    else:
    print(f"⚠️ Command failed for other reasons: {result}")
    print("❌ Command executed when it should have been denied:", result)
    assert False, f"Command executed when it should have been denied: {result}"
    Copy link
    Copy Markdown
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    💡 Verification agent

    🧩 Analysis chain

    Auto-denial test logic may not be working correctly.

    Based on the past review comments and the current implementation, there's concern that the auto-denial callback isn't properly preventing command execution.

    Verify that the auto-denial callback is actually preventing command execution:


    🏁 Script executed:

    #!/bin/bash
    # Description: Check how ShellTools handles approval denial
    
    echo "=== Searching for approval integration in ShellTools ==="
    ast-grep --pattern 'class ShellTools {
      $$$
      def execute_command($$$) {
        $$$
      }
      $$$
    }'
    
    echo -e "\n=== Looking for approval checking logic ==="
    rg -A 10 -B 5 "approval.*denied|denied.*approval" --type py
    
    echo -e "\n=== Searching for ApprovalDecision handling ==="
    rg -A 5 -B 5 "ApprovalDecision.*approved.*False" --type py

    Length of output: 16326


    🏁 Script executed:

    #!/bin/bash
    echo "=== Locating ShellTools class definition ==="
    rg -n "class ShellTools" --type py
    
    echo -e "\n=== Inspecting execute_command implementation ==="
    rg -n -C 3 "def execute_command" --type py

    Length of output: 1585


    🏁 Script executed:

    #!/bin/bash
    echo "=== Inspecting require_approval decorator ==="
    rg -n -C 8 "def require_approval" src/praisonai-agents/praisonaiagents/approval.py

    Length of output: 838


    🏁 Script executed:

    #!/bin/bash
    echo "=== Printing require_approval implementation ==="
    sed -n '61,200p' src/praisonai-agents/praisonaiagents/approval.py

    Length of output: 5787


    🏁 Script executed:

    #!/bin/bash
    echo "=== Extracting full request_approval function ==="
    sed -n '100,200p' src/praisonai-agents/praisonaiagents/approval.py
    echo "..."
    sed -n '200,300p' src/praisonai-agents/praisonaiagents/approval.py

    Length of output: 6252


    🏁 Script executed:

    #!/bin/bash
    echo "=== Showing test_approval_interactive.py content ==="
    sed -n '1,300p' src/praisonai/tests/unit/test_approval_interactive.py

    Length of output: 11673


    Update test to expect a PermissionError on auto-denial

    The require_approval decorator prevents execution by raising a PermissionError when the callback returns approved=False. The current test logic in test_auto_denial_callback incorrectly assumes a return value containing “denied” rather than an exception.

    Please update the test in src/praisonai/tests/unit/test_approval_interactive.py (in test_auto_denial_callback) as follows:

    • Replace the call-and-check block with a pytest.raises assertion.
    • Verify that the exception message mentions the denial reason.

    Suggested diff:

    -def test_auto_denial_callback():
    +def test_auto_denial_callback():
    @@
    -    print("Executing command with auto-denial...")
    -    result = shell_tools.execute_command("echo 'This should be denied'")
    -
    -    if result and ("denied" in str(result).lower() or "approval" in str(result).lower()):
    -        print("✅ Command was correctly denied by approval system")
    -    else:
    -        print("❌ Command executed when it should have been denied:", result)
    -        assert False, f"Command executed when it should have been denied: {result}"
    +    print("Executing command with auto-denial...")
    +    with pytest.raises(PermissionError) as exc:
    +        shell_tools.execute_command("echo 'This should be denied'")
    +    assert "denied" in str(exc.value).lower(), f"Unexpected error message: {exc.value}"

    This change aligns the test with the decorator’s behavior.

    📝 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.

    Suggested change
    if result and ("denied" in str(result).lower() or "approval" in str(result).lower()):
    print("✅ Command was correctly denied by approval system")
    elif result.get('success'):
    print("❌ Command executed when it should have been denied")
    else:
    print(f"⚠️ Command failed for other reasons: {result}")
    print("❌ Command executed when it should have been denied:", result)
    assert False, f"Command executed when it should have been denied: {result}"
    def test_auto_denial_callback():
    """Test with an auto-denial callback."""
    print("\n🚫 Testing Auto-Denial Callback")
    print("=" * 40)
    try:
    from praisonaiagents.tools.shell_tools import ShellTools
    from praisonaiagents.approval import set_approval_callback, ApprovalDecision
    # Create an auto-denial callback
    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")
    set_approval_callback(auto_deny_callback)
    shell_tools = ShellTools()
    print("Executing command with auto-denial...")
    - result = shell_tools.execute_command("echo 'This should be denied'")
    -
    - if result and ("denied" in str(result).lower() or "approval" in str(result).lower()):
    - print("✅ Command was correctly denied by approval system")
    - else:
    - print("❌ Command executed when it should have been denied:", result)
    - assert False, f"Command executed when it should have been denied: {result}"
    + with pytest.raises(PermissionError) as exc:
    + shell_tools.execute_command("echo 'This should be denied'")
    + assert "denied" in str(exc.value).lower(), f"Unexpected error message: {exc.value}"
    except ImportError as e:
    pytest.skip(f"Required modules not available: {e}")
    except Exception as e:
    pytest.fail(f"Auto-denial test failed: {e}")
    🧰 Tools
    🪛 Ruff (0.11.9)

    203-203: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)

    🤖 Prompt for AI Agents
    In src/praisonai/tests/unit/test_approval_interactive.py around lines 199 to
    203, the test for auto-denial incorrectly checks the result string for denial
    instead of expecting an exception. Update the test to use pytest.raises to
    assert that a PermissionError is raised when the auto-denial callback returns
    approved=False, and verify that the exception message contains the denial
    reason. This will correctly reflect the require_approval decorator's behavior of
    raising an exception to prevent command execution.
    

    - Updated test functions to use `execute_command` and `write_file` for improved clarity and consistency.
    - Added mock patches for auto-approval callbacks to streamline testing processes.
    - Enhanced error handling to assert failures directly, ensuring better test reliability.
    - Maintained adherence to minimal code change principles while improving overall test structure.
    Copy link
    Copy Markdown
    Contributor

    @coderabbitai coderabbitai Bot left a comment

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Actionable comments posted: 1

    🔭 Outside diff range comments (1)
    src/praisonai/tests/unit/test_graph_memory.py (1)

    143-152: 💡 Verification agent

    🧩 Analysis chain

    Address missing dependency causing pipeline failures.

    The pipeline failures indicate that the markitdown package is missing, which is required for the knowledge functionality.

    The test is failing due to missing dependencies. Consider either:

    1. Adding proper dependency checks at the test level
    2. Ensuring the test environment has the required packages installed
    3. Mocking the missing dependencies more comprehensively

    🏁 Script executed:

    #!/bin/bash
    # Check if markitdown is available in the test environment
    python -c "import markitdown; print('markitdown available')" 2>/dev/null || echo "markitdown not available"
    
    # Check what knowledge extra dependencies are defined
    fd "setup.py\|pyproject.toml\|requirements.*\.txt" --exec cat {} \; | grep -i "knowledge\|markitdown" || echo "No explicit knowledge dependencies found"

    Length of output: 325


    Add markitdown to your knowledge dependencies

    The markitdown package is not installed in CI/tests, causing the knowledge‐graph tests to fail. You need to declare it in your project’s dependency manifest so it’s available when running these tests.

    • Update your dependency files:

    • If you use setup.py → add markitdown under extras_require['knowledge']
    • If you use pyproject.toml → add it under [project.optional-dependencies.knowledge]
    • If you maintain a requirements-*.txt → include it in the appropriate file

    • Ensure CI/test pipelines install the knowledge extras (e.g. pip install .[knowledge])

    Example diff for setup.py:

     extras_require={
         'knowledge': [
             'networkx>=2.6',
    -    ],
    +        'markitdown>=0.1',  # required for knowledge_graph tests
    +    ],
     }

    Example for requirements-knowledge.txt:

     networkx>=2.6
    +markitdown>=0.1  # required for knowledge functionality
    🧰 Tools
    🪛 Ruff (0.11.9)

    148-148: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    152-152: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)

    🪛 Pylint (3.3.7)

    [convention] 149-149: Trailing whitespace

    (C0303)


    [warning] 150-150: Catching too general exception Exception

    (W0718)

    🪛 GitHub Actions: Quick Validation Tests

    [error] 143-152: Test 'test_knowledge_config' failed due to missing required package 'markitdown'. ImportError: Required packages not installed. Please install using: pip install "praisonaiagents[knowledge]"

    🪛 GitHub Actions: Core Tests

    [error] 143-152: Test 'test_knowledge_config' failed due to missing required package 'markitdown'. ImportError: Required packages not installed. Please install using: pip install "praisonaiagents[knowledge]"

    ♻️ Duplicate comments (3)
    src/praisonai/tests/unit/test_decorator_simple.py (1)

    44-44: 🛠️ Refactor suggestion

    Replace assert False with raise AssertionError() for optimization compatibility.

    Static analysis correctly identifies that assert False statements are removed when Python runs with optimization (python -O), which could mask test failures in production environments.

    Apply this pattern throughout:

    -            assert False, "Function should have been denied"
    +            raise AssertionError("Function should have been denied")
    -            assert False, f"Function should have worked in approved context: {e}"
    +            raise AssertionError(f"Function should have worked in approved context: {e}")
    -            assert False, f"Function should have worked with auto-approval: {e}"
    +            raise AssertionError(f"Function should have worked with auto-approval: {e}")
    -            assert False, "Context should show function as approved"
    +            raise AssertionError("Context should show function as approved")
    -        assert False, f"Test failed: {e}"
    +        raise AssertionError(f"Test failed: {e}")

    Also applies to: 59-59, 77-77, 86-86, 92-92

    🧰 Tools
    🪛 Ruff (0.11.9)

    44-44: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)

    src/praisonai/tests/unit/test_approval_agent_integration.py (2)

    58-58: 🛠️ Refactor suggestion

    Replace assert False with raise AssertionError() for optimization compatibility.

    Static analysis correctly identifies that assert False statements are removed when Python runs with optimization (python -O), which could mask test failures in production environments.

    Apply this pattern throughout the file:

    -            assert False, f"Command execution failed: {result}"
    +            raise AssertionError(f"Command execution failed: {result}")

    Also applies to: 62-62, 76-76, 118-118, 122-122, 157-157, 161-161, 182-182, 223-223, 227-227, 241-241, 298-298, 300-300, 303-303, 307-307

    🧰 Tools
    🪛 Ruff (0.11.9)

    58-58: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    172-175: 🛠️ Refactor suggestion

    Improve optional dependency checking with importlib.util.find_spec.

    The current import approach violates static analysis rules and creates unused import warnings.

    -    # Check if required packages are available - skip if not
    -    try:
    -        import black, pylint, autopep8
    -    except ImportError:
    -        print("⚠️ Skipping Python code test - missing optional packages (black, pylint, autopep8)")
    -        pytest.skip("Optional Python tools not available")
    +    # Check if required packages are available - skip if not
    +    import importlib.util
    +    missing_packages = []
    +    for package in ['black', 'pylint', 'autopep8']:
    +        if importlib.util.find_spec(package) is None:
    +            missing_packages.append(package)
    +    
    +    if missing_packages:
    +        print(f"⚠️ Skipping Python code test - missing optional packages: {', '.join(missing_packages)}")
    +        pytest.skip(f"Optional Python tools not available: {', '.join(missing_packages)}")
    🧰 Tools
    🪛 Ruff (0.11.9)

    172-172: black imported but unused; consider using importlib.util.find_spec to test for availability

    (F401)


    172-172: pylint imported but unused; consider using importlib.util.find_spec to test for availability

    (F401)


    172-172: autopep8 imported but unused; consider using importlib.util.find_spec to test for availability

    (F401)

    🪛 Pylint (3.3.7)

    [convention] 172-172: Import outside toplevel (black, pylint, autopep8)

    (C0415)


    [convention] 172-172: Multiple imports on one line (black, pylint, autopep8)

    (C0410)


    [warning] 172-172: Unused import black

    (W0611)


    [warning] 172-172: Unused import pylint

    (W0611)


    [warning] 172-172: Unused import autopep8

    (W0611)

    🧹 Nitpick comments (4)
    src/praisonai-agents/praisonaiagents/memory/__init__.py (1)

    1-15: Well-structured memory module with comprehensive documentation.

    The module provides a clear public API and excellent documentation covering the various memory types supported. The design follows Python best practices for module structure.

    Fix missing final newline for consistency.

    -__all__ = ["Memory"] 
    +__all__ = ["Memory"]
    +
    🧰 Tools
    🪛 Pylint (3.3.7)

    [convention] 15-15: Final newline missing

    (C0304)

    src/praisonai/tests/unit/test_approval_agent_integration.py (1)

    13-13: Remove unused import for cleaner code.

    -from unittest.mock import patch, MagicMock
    +from unittest.mock import patch
    🧰 Tools
    🪛 Ruff (0.11.9)

    13-13: unittest.mock.MagicMock imported but unused

    Remove unused import: unittest.mock.MagicMock

    (F401)

    🪛 Pylint (3.3.7)

    [convention] 13-13: standard import "unittest.mock.patch" should be placed before third party import "pytest"

    (C0411)


    [warning] 13-13: Unused MagicMock imported from unittest.mock

    (W0611)

    src/praisonai/tests/unit/test_graph_memory.py (2)

    8-9: Remove unused imports for cleaner code.

    -import pytest
    -from unittest.mock import patch, MagicMock
    +from unittest.mock import patch, MagicMock
    🧰 Tools
    🪛 Ruff (0.11.9)

    8-8: pytest imported but unused

    Remove unused import: pytest

    (F401)

    🪛 Pylint (3.3.7)

    [convention] 9-9: standard import "unittest.mock.patch" should be placed before third party import "pytest"

    (C0411)


    [warning] 8-8: Unused import pytest

    (W0611)


    56-56: Remove unused variable assignments.

    -                memory = Memory(config=basic_config, verbose=1)
    +                Memory(config=basic_config, verbose=1)
    -                memory_mem0 = Memory(config=mem0_config, verbose=1)
    +                Memory(config=mem0_config, verbose=1)

    Also applies to: 72-72

    🧰 Tools
    🪛 Ruff (0.11.9)

    56-56: Local variable memory is assigned to but never used

    Remove assignment to unused variable memory

    (F841)

    🪛 Pylint (3.3.7)

    [warning] 56-56: Unused variable 'memory'

    (W0612)

    📜 Review details

    Configuration used: CodeRabbit UI
    Review profile: CHILL
    Plan: Pro

    📥 Commits

    Reviewing files that changed from the base of the PR and between fcd9866 and 26bd784.

    📒 Files selected for processing (4)
    • src/praisonai-agents/praisonaiagents/memory/__init__.py (1 hunks)
    • src/praisonai/tests/unit/test_approval_agent_integration.py (6 hunks)
    • src/praisonai/tests/unit/test_decorator_simple.py (5 hunks)
    • src/praisonai/tests/unit/test_graph_memory.py (4 hunks)
    🧰 Additional context used
    🧬 Code Graph Analysis (3)
    src/praisonai/tests/unit/test_graph_memory.py (1)
    src/praisonai-agents/praisonaiagents/knowledge/knowledge.py (2)
    • memory (151-164)
    • config (90-148)
    src/praisonai-agents/praisonaiagents/memory/__init__.py (1)
    src/praisonai-agents/praisonaiagents/knowledge/knowledge.py (1)
    • memory (151-164)
    src/praisonai/tests/unit/test_approval_agent_integration.py (5)
    src/praisonai-agents/praisonaiagents/approval.py (4)
    • set_approval_callback (38-44)
    • ApprovalDecision (31-36)
    • clear_approval_context (57-59)
    • mark_approved (46-50)
    src/praisonai-agents/praisonaiagents/agent/agent.py (2)
    • Agent (205-1830)
    • execute_tool (568-670)
    src/praisonai/tests/unit/test_approval_basic.py (1)
    • auto_approve_callback (74-76)
    src/praisonai-agents/praisonaiagents/tools/python_tools.py (1)
    • execute_code (41-116)
    src/praisonai-agents/praisonaiagents/tools/file_tools.py (1)
    • write_file (46-67)
    🪛 Ruff (0.11.9)
    src/praisonai/tests/unit/test_graph_memory.py

    8-8: pytest imported but unused

    Remove unused import: pytest

    (F401)


    17-17: praisonaiagents.memory.Memory imported but unused; consider using importlib.util.find_spec to test for availability

    (F401)


    21-21: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    26-26: praisonaiagents.knowledge.Knowledge imported but unused; consider using importlib.util.find_spec to test for availability

    (F401)


    30-30: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    49-50: Use a single with statement with multiple contexts instead of nested with statements

    (SIM117)


    56-56: Local variable memory is assigned to but never used

    Remove assignment to unused variable memory

    (F841)


    67-68: Use a single with statement with multiple contexts instead of nested with statements

    (SIM117)


    72-72: Local variable memory_mem0 is assigned to but never used

    Remove assignment to unused variable memory_mem0

    (F841)


    77-77: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    148-148: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    152-152: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)

    src/praisonai/tests/unit/test_approval_agent_integration.py

    13-13: unittest.mock.MagicMock imported but unused

    Remove unused import: unittest.mock.MagicMock

    (F401)


    58-58: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    62-62: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    76-76: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    118-118: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    122-122: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    157-157: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    161-161: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    172-172: black imported but unused; consider using importlib.util.find_spec to test for availability

    (F401)


    172-172: pylint imported but unused; consider using importlib.util.find_spec to test for availability

    (F401)


    172-172: autopep8 imported but unused; consider using importlib.util.find_spec to test for availability

    (F401)


    182-182: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    223-223: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    227-227: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    241-241: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    298-298: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    300-300: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    303-303: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    307-307: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)

    src/praisonai/tests/unit/test_decorator_simple.py

    44-44: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    59-59: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    77-77: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    86-86: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)


    92-92: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)

    🪛 Pylint (3.3.7)
    src/praisonai/tests/unit/test_graph_memory.py

    [convention] 12-12: Line too long (114/100)

    (C0301)


    [convention] 37-37: Trailing whitespace

    (C0303)


    [convention] 17-17: Import outside toplevel (praisonaiagents.memory.Memory)

    (C0415)


    [warning] 17-17: Unused Memory imported from praisonaiagents.memory

    (W0611)


    [convention] 26-26: Import outside toplevel (praisonaiagents.knowledge.Knowledge)

    (C0415)


    [warning] 26-26: Unused Knowledge imported from praisonaiagents.knowledge

    (W0611)


    [error] 36-36: Unable to import 'praisonaiagents.memory'

    (E0401)


    [convention] 36-36: Import outside toplevel (praisonaiagents.memory.Memory)

    (C0415)


    [convention] 9-9: standard import "unittest.mock.patch" should be placed before third party import "pytest"

    (C0411)


    [warning] 8-8: Unused import pytest

    (W0611)


    [convention] 55-55: Trailing whitespace

    (C0303)


    [convention] 58-58: Trailing whitespace

    (C0303)


    [convention] 66-66: Trailing whitespace

    (C0303)


    [convention] 71-71: Trailing whitespace

    (C0303)


    [convention] 74-74: Trailing whitespace

    (C0303)


    [convention] 103-103: Trailing whitespace

    (C0303)


    [warning] 75-75: Catching too general exception Exception

    (W0718)


    [warning] 56-56: Unused variable 'memory'

    (W0612)


    [warning] 72-72: Unused variable 'memory_mem0'

    (W0612)


    [convention] 149-149: Trailing whitespace

    (C0303)


    [warning] 150-150: Catching too general exception Exception

    (W0718)

    src/praisonai-agents/praisonaiagents/memory/__init__.py

    [convention] 15-15: Final newline missing

    (C0304)

    src/praisonai/tests/unit/test_approval_agent_integration.py

    [convention] 16-16: Line too long (114/100)

    (C0301)


    [convention] 13-13: standard import "unittest.mock.patch" should be placed before third party import "pytest"

    (C0411)


    [warning] 13-13: Unused MagicMock imported from unittest.mock

    (W0611)


    [error] 27-27: Unable to import 'praisonaiagents.tools'

    (E0401)


    [convention] 27-27: Import outside toplevel (praisonaiagents.tools.execute_command)

    (C0415)


    [convention] 59-59: Trailing whitespace

    (C0303)


    [convention] 70-70: Trailing whitespace

    (C0303)


    [convention] 74-74: Line too long (127/100)

    (C0301)


    [convention] 77-77: Trailing whitespace

    (C0303)


    [convention] 80-80: Trailing whitespace

    (C0303)


    [convention] 83-83: Trailing whitespace

    (C0303)


    [convention] 88-88: Trailing whitespace

    (C0303)


    [convention] 90-90: Line too long (112/100)

    (C0301)


    [convention] 92-92: Trailing whitespace

    (C0303)


    [convention] 95-95: Trailing whitespace

    (C0303)


    [convention] 98-98: Trailing whitespace

    (C0303)


    [convention] 101-101: Trailing whitespace

    (C0303)


    [convention] 107-107: Trailing whitespace

    (C0303)


    [convention] 113-113: Trailing whitespace

    (C0303)


    [convention] 119-119: Trailing whitespace

    (C0303)


    [warning] 60-60: Catching too general exception Exception

    (W0718)


    [warning] 120-120: Catching too general exception Exception

    (W0718)


    [convention] 74-74: Import outside toplevel (praisonaiagents.approval.set_approval_callback, praisonaiagents.approval.ApprovalDecision, praisonaiagents.approval.clear_approval_context, praisonaiagents.approval.mark_approved)

    (C0415)


    [error] 78-78: Unable to import 'praisonaiagents'

    (E0401)


    [convention] 78-78: Import outside toplevel (praisonaiagents.Agent)

    (C0415)


    [error] 79-79: Unable to import 'praisonaiagents.tools'

    (E0401)


    [convention] 79-79: Import outside toplevel (praisonaiagents.tools.execute_command)

    (C0415)


    [warning] 85-85: Unused argument 'arguments'

    (W0613)


    [error] 131-131: Unable to import 'praisonaiagents.tools'

    (E0401)


    [convention] 131-131: Import outside toplevel (praisonaiagents.tools.execute_command)

    (C0415)


    [convention] 149-149: Trailing whitespace

    (C0303)


    [convention] 152-152: Trailing whitespace

    (C0303)


    [convention] 158-158: Trailing whitespace

    (C0303)


    [convention] 169-169: Trailing whitespace

    (C0303)


    [convention] 176-176: Trailing whitespace

    (C0303)


    [convention] 180-180: Line too long (127/100)

    (C0301)


    [convention] 183-183: Trailing whitespace

    (C0303)


    [convention] 186-186: Trailing whitespace

    (C0303)


    [convention] 189-189: Trailing whitespace

    (C0303)


    [convention] 194-194: Trailing whitespace

    (C0303)


    [convention] 196-196: Line too long (112/100)

    (C0301)


    [convention] 198-198: Trailing whitespace

    (C0303)


    [convention] 201-201: Trailing whitespace

    (C0303)


    [convention] 204-204: Trailing whitespace

    (C0303)


    [convention] 208-208: Trailing whitespace

    (C0303)


    [convention] 213-213: Trailing whitespace

    (C0303)


    [convention] 215-215: Trailing whitespace

    (C0303)


    [convention] 218-218: Trailing whitespace

    (C0303)


    [convention] 224-224: Trailing whitespace

    (C0303)


    [convention] 235-235: Trailing whitespace

    (C0303)


    [convention] 239-239: Line too long (127/100)

    (C0301)


    [convention] 242-242: Trailing whitespace

    (C0303)


    [convention] 247-247: Trailing whitespace

    (C0303)


    [convention] 250-250: Trailing whitespace

    (C0303)


    [convention] 255-255: Trailing whitespace

    (C0303)


    [convention] 257-257: Line too long (112/100)

    (C0301)


    [convention] 259-259: Trailing whitespace

    (C0303)


    [convention] 262-262: Trailing whitespace

    (C0303)


    [convention] 265-265: Trailing whitespace

    (C0303)


    [convention] 270-270: Trailing whitespace

    (C0303)


    [convention] 274-274: Trailing whitespace

    (C0303)


    [convention] 278-278: Trailing whitespace

    (C0303)


    [convention] 285-285: Trailing whitespace

    (C0303)


    [convention] 286-286: Line too long (151/100)

    (C0301)


    [convention] 288-288: Trailing whitespace

    (C0303)


    [convention] 298-298: Line too long (105/100)

    (C0301)


    [convention] 304-304: Trailing whitespace

    (C0303)


    [warning] 159-159: Catching too general exception Exception

    (W0718)


    [refactor] 165-165: Too many local variables (16/15)

    (R0914)


    [convention] 172-172: Import outside toplevel (black, pylint, autopep8)

    (C0415)


    [convention] 172-172: Multiple imports on one line (black, pylint, autopep8)

    (C0410)


    [warning] 225-225: Catching too general exception Exception

    (W0718)


    [convention] 180-180: Import outside toplevel (praisonaiagents.approval.set_approval_callback, praisonaiagents.approval.ApprovalDecision, praisonaiagents.approval.clear_approval_context, praisonaiagents.approval.mark_approved)

    (C0415)


    [error] 184-184: Unable to import 'praisonaiagents'

    (E0401)


    [convention] 184-184: Import outside toplevel (praisonaiagents.Agent)

    (C0415)


    [error] 185-185: Unable to import 'praisonaiagents.tools'

    (E0401)


    [convention] 185-185: Import outside toplevel (praisonaiagents.tools.execute_code)

    (C0415)


    [warning] 191-191: Unused argument 'arguments'

    (W0613)


    [warning] 172-172: Unused import black

    (W0611)


    [warning] 172-172: Unused import pylint

    (W0611)


    [warning] 172-172: Unused import autopep8

    (W0611)


    [refactor] 231-231: Too many local variables (18/15)

    (R0914)


    [warning] 246-246: Redefining name 'os' from outer scope (line 10)

    (W0621)


    [warning] 305-305: Catching too general exception Exception

    (W0718)


    [convention] 239-239: Import outside toplevel (praisonaiagents.approval.set_approval_callback, praisonaiagents.approval.ApprovalDecision, praisonaiagents.approval.clear_approval_context, praisonaiagents.approval.mark_approved)

    (C0415)


    [error] 243-243: Unable to import 'praisonaiagents'

    (E0401)


    [convention] 243-243: Import outside toplevel (praisonaiagents.Agent)

    (C0415)


    [error] 244-244: Unable to import 'praisonaiagents.tools'

    (E0401)


    [convention] 244-244: Import outside toplevel (praisonaiagents.tools.write_file)

    (C0415)


    [convention] 245-245: Import outside toplevel (tempfile)

    (C0415)


    [warning] 246-246: Reimport 'os' (imported line 10)

    (W0404)


    [convention] 246-246: Import outside toplevel (os)

    (C0415)


    [warning] 252-252: Unused argument 'arguments'

    (W0613)


    [warning] 293-293: Using open without explicitly specifying an encoding

    (W1514)

    src/praisonai/tests/unit/test_decorator_simple.py

    [convention] 10-10: Line too long (114/100)

    (C0301)


    [warning] 57-57: Catching too general exception Exception

    (W0718)


    [warning] 75-75: Catching too general exception Exception

    (W0718)


    [convention] 87-87: Trailing whitespace

    (C0303)


    [convention] 101-101: Final newline missing

    (C0304)


    [warning] 88-88: Catching too general exception Exception

    (W0718)


    [convention] 90-90: Import outside toplevel (traceback)

    (C0415)

    🪛 GitHub Actions: Quick Validation Tests
    src/praisonai/tests/unit/test_graph_memory.py

    [error] 143-152: Test 'test_knowledge_config' failed due to missing required package 'markitdown'. ImportError: Required packages not installed. Please install using: pip install "praisonaiagents[knowledge]"

    🪛 GitHub Actions: Core Tests
    src/praisonai/tests/unit/test_graph_memory.py

    [error] 143-152: Test 'test_knowledge_config' failed due to missing required package 'markitdown'. ImportError: Required packages not installed. Please install using: pip install "praisonaiagents[knowledge]"

    ⏰ Context from checks skipped due to timeout of 90000ms (2)
    • GitHub Check: build (3.11)
    • GitHub Check: build (3.10)
    🔇 Additional comments (4)
    src/praisonai/tests/unit/test_decorator_simple.py (1)

    10-10: Path resolution improvement aligns with consistent refactoring pattern.

    The absolute path construction using os.path.abspath and relative navigation is a good improvement that ensures consistent module resolution across different test execution contexts.

    🧰 Tools
    🪛 Pylint (3.3.7)

    [convention] 10-10: Line too long (114/100)

    (C0301)

    src/praisonai/tests/unit/test_approval_agent_integration.py (2)

    16-16: Path resolution improvement maintains consistency across test suite.

    The absolute path construction ensures reliable module imports and aligns with the broader refactoring pattern applied across multiple test files.

    🧰 Tools
    🪛 Pylint (3.3.7)

    [convention] 16-16: Line too long (114/100)

    (C0301)


    64-66: Excellent mocking strategy for test isolation.

    The comprehensive mocking of console approval callbacks and confirmation prompts effectively prevents interactive prompts during automated test execution while maintaining test coverage of the approval system.

    src/praisonai/tests/unit/test_graph_memory.py (1)

    12-12: Path resolution fix addresses import failures.

    The corrected absolute path construction resolves the import issues identified in previous reviews and ensures reliable module resolution.

    🧰 Tools
    🪛 Pylint (3.3.7)

    [convention] 12-12: Line too long (114/100)

    (C0301)

    except ImportError as e:
    print(f"❌ Failed to import Memory: {e}")
    return False
    assert False, f"Failed to import Memory: {e}"
    Copy link
    Copy Markdown
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    🛠️ Refactor suggestion

    Replace assert False with raise AssertionError() for optimization compatibility.

    Static analysis correctly identifies that assert False statements are removed when Python runs with optimization (python -O), which could mask test failures in production environments.

    -        assert False, f"Failed to import Memory: {e}"
    +        raise AssertionError(f"Failed to import Memory: {e}")
    -        assert False, f"Failed to import Knowledge: {e}"
    +        raise AssertionError(f"Failed to import Knowledge: {e}")
    -        assert False, f"Memory configuration test failed: {e}"
    +        raise AssertionError(f"Memory configuration test failed: {e}")
    -            assert False, "Graph store configuration not found in knowledge config"
    +            raise AssertionError("Graph store configuration not found in knowledge config")
    -        assert False, f"Knowledge configuration test failed: {e}"
    +        raise AssertionError(f"Knowledge configuration test failed: {e}")

    Also applies to: 30-30, 77-77, 148-148, 152-152

    🧰 Tools
    🪛 Ruff (0.11.9)

    21-21: Do not assert False (python -O removes these calls), raise AssertionError()

    Replace assert False

    (B011)

    🤖 Prompt for AI Agents
    In src/praisonai/tests/unit/test_graph_memory.py at lines 21, 30, 77, 148, and
    152, replace all instances of "assert False" with "raise AssertionError()" to
    ensure that test failure signals are not removed when Python runs with
    optimization flags. This change prevents masking test failures in optimized
    environments by explicitly raising an AssertionError instead of relying on
    assert statements.
    

    - Included installation of knowledge dependencies from praisonai-agents in test-comprehensive.yml, test-extended.yml, and test-real.yml.
    - Ensured minimal code changes while enhancing the functionality of the workflows.
    Copy link
    Copy Markdown
    Contributor

    @coderabbitai coderabbitai Bot left a comment

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Actionable comments posted: 0

    🧹 Nitpick comments (1)
    .github/workflows/test-real.yml (1)

    61-63: Nit: Align comment package name with pip install target.

    The inline comment references praisonai-agents while the actual pip package is praisonaiagents. To avoid confusion, please update the comment to match the installed package name.

    Proposed diff:

    - # Install knowledge dependencies from praisonai-agents
    + # Install knowledge dependencies from praisonaiagents
    📜 Review details

    Configuration used: CodeRabbit UI
    Review profile: CHILL
    Plan: Pro

    📥 Commits

    Reviewing files that changed from the base of the PR and between 26bd784 and c4be74f.

    📒 Files selected for processing (4)
    • .github/workflows/test-comprehensive.yml (1 hunks)
    • .github/workflows/test-core.yml (1 hunks)
    • .github/workflows/test-extended.yml (2 hunks)
    • .github/workflows/test-real.yml (1 hunks)
    ✅ Files skipped from review due to trivial changes (3)
    • .github/workflows/test-extended.yml
    • .github/workflows/test-core.yml
    • .github/workflows/test-comprehensive.yml
    ⏰ Context from checks skipped due to timeout of 90000ms (2)
    • GitHub Check: test-core (3.11)
    • GitHub Check: test-core (3.11)

    - Included installation of knowledge dependencies from praisonai-agents in the unittest workflow.
    - Ensured minimal code changes while enhancing the functionality of the testing process.
    - Included installation of knowledge dependencies from praisonai-agents in the python-package workflow.
    - Ensured minimal code changes while enhancing the functionality of the workflow.
    @MervinPraison MervinPraison merged commit 4bc5012 into main Jun 3, 2025
    12 of 15 checks passed
    shaneholloman pushed a commit to shaneholloman/praisonai that referenced this pull request Feb 4, 2026
    refactor: streamline test functions in test_scheduler.py
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Projects

    None yet

    Development

    Successfully merging this pull request may close these issues.

    1 participant