adding function to print colored terminal output#554
adding function to print colored terminal output#554imran-siddique merged 18 commits intomicrosoft:mainfrom
Conversation
|
Welcome to the Agent Governance Toolkit! Thanks for your first pull request. |
🤖 AI Agent: test-generator — `packages/agent-os/src/agent_os/policies/cli.py`🧪 Test Coverage Analysis
|
🤖 AI Agent: docs-sync-checker — Issues Found📝 Documentation Sync ReportIssues Found
Suggestions
Additional Notes
Please address the above issues and suggestions to ensure the documentation and examples are in sync with the new functionality. |
🤖 AI Agent: breaking-change-detector — Summary🔍 API Compatibility ReportSummaryThis pull request introduces new functionality for colored terminal output in the Agent-OS CLI using the Findings
Migration GuideNo migration steps are necessary as no breaking changes were introduced. However, downstream users should be aware of the new colored output functionality and the optional dependency on the Additional Notes
✅ No breaking changes detected. |
🤖 AI Agent: security-scanner — Security Review of PR: Adding Colored Terminal OutputSecurity Review of PR: Adding Colored Terminal OutputThis PR introduces colored terminal output to the CLI using the Findings1. Prompt Injection Defense BypassRating: 🔵 LOW
2. Policy Engine CircumventionRating: 🔵 LOW
3. Trust Chain WeaknessesRating: 🔵 LOW 4. Credential ExposureRating: 🔵 LOW
5. Sandbox EscapeRating: 🔵 LOW 6. Deserialization AttacksRating: 🔵 LOW
7. Race ConditionsRating: 🔵 LOW 8. Supply Chain RisksRating: 🟠 HIGH
Additional Observations
Summary of Recommendations
Final Rating: 🟡 MEDIUMWhile the changes themselves are low-risk, the introduction of a new dependency ( |
🤖 AI Agent: contributor-guide — Welcome! 🎉Welcome! 🎉Hi there, and welcome to the microsoft/agent-governance-toolkit project! Thank you so much for taking the time to contribute to this repository. We’re thrilled to have you here, and we appreciate your effort in improving the project. 😊 PR Review 🧐First off, great job on this pull request! Here’s what I really liked about your contribution:
Suggestions for Improvement ✨Here are a few suggestions to align your contribution with our project conventions and best practices:
Resources 📚Here are some helpful links to get you up to speed with our project conventions:
Next Steps 🚀
Once you’ve made these updates, I’ll take another look and help you get this merged! Let me know if you have any questions or need assistance with anything. 😊 Thank you again for your contribution — we’re excited to have you on board! 🚀 |
There was a problem hiding this comment.
🤖 AI Agent: code-reviewer
Review Summary
This pull request introduces a new feature to enhance the CLI output of the agent-governance package by adding color-coded messages using the rich library. The changes improve the user experience by making CLI feedback more visually distinct and easier to interpret. The PR also includes test policies and scenarios to validate the new functionality.
While the changes are generally well-implemented, there are a few areas that need attention to ensure robustness, security, and maintainability.
🔴 CRITICAL
-
Unvalidated User Input in CLI Commands:
- The CLI commands (
cmd_validate,cmd_test,cmd_diff) directly use user-supplied file paths without sufficient validation or sanitization. This could lead to potential path traversal vulnerabilities or arbitrary file access. - Recommendation: Use
os.path.abspathto normalize paths and ensure they are within an expected directory. Additionally, validate the file extensions and ensure that only.yamlor.jsonfiles are processed.
- The CLI commands (
-
Error Messages May Leak Sensitive Information:
- The error messages in the
cmd_validate,cmd_test, andcmd_difffunctions include the exception message (exc) directly in the output. This could expose sensitive information about the system or stack traces in production environments. - Recommendation: Log detailed exception messages to a secure log file and provide generic error messages to the user.
- The error messages in the
🟡 WARNING
- Backward Compatibility:
- The new
rich-based output changes the format of CLI messages, which could break existing scripts or tools that parse the CLI output. - Recommendation: Add a
--plainor--no-colorflag to allow users to disable colored output and revert to plain text. This ensures backward compatibility for users relying on the previous output format.
- The new
💡 SUGGESTIONS
-
Error Handling Consistency:
- The
cmd_validate,cmd_test, andcmd_difffunctions use inconsistent return codes for errors. For example,cmd_validatereturns2for file-not-found errors, whilecmd_testalso uses2for parsing errors. - Recommendation: Define a consistent set of exit codes for different error types (e.g.,
1for validation errors,2for file-not-found errors, etc.) and document them.
- The
-
Unit Tests for Colored Output:
- While the PR includes test policies and scenarios, there are no explicit unit tests for the new colored output functions (
error,success,warn, etc.). - Recommendation: Add unit tests to verify that the
rich-based functions produce the expected output. You can use thepytestlibrary'scapsysfixture to capture and assert the printed output.
- While the PR includes test policies and scenarios, there are no explicit unit tests for the new colored output functions (
-
Optional Dependency Management:
- The
richlibrary is now a required dependency, but it may not be necessary for all users or environments. - Recommendation: Consider making
richan optional dependency and provide a fallback to plain text output if it is not installed. Alternatively, document the new dependency clearly in the README and installation instructions.
- The
-
Code Duplication in Error Messages:
- The error-handling code in
cmd_validate,cmd_test, andcmd_diffis repetitive. - Recommendation: Refactor the error-handling logic into a helper function (e.g.,
handle_error) to reduce duplication and improve maintainability.
- The error-handling code in
-
Default File Encoding:
- The
_load_filefunction does not specify an encoding when reading files. This could lead to issues on systems with non-UTF-8 default encodings. - Recommendation: Explicitly specify
encoding="utf-8"when reading files to ensure consistent behavior across platforms.
- The
-
Type Annotations for New Functions:
- The new functions (
error,success,warn, etc.) lack type annotations. - Recommendation: Add type annotations to improve code readability and maintainability. For example:
def error(msg: str) -> None: ...
- The new functions (
-
Documentation Update:
- The PR does not include updates to the documentation to reflect the new CLI output format or the addition of the
richdependency. - Recommendation: Update the CLI documentation to describe the new color-coded output and any new flags (e.g.,
--plain).
- The PR does not include updates to the documentation to reflect the new CLI output format or the addition of the
Additional Observations
-
Use of
sys.stderr:- The new output functions (
error,success, etc.) write tosys.stderrfor all message types, including success messages. While this is acceptable for error messages, success messages are typically written tosys.stdout. - Recommendation: Use
sys.stdoutfor non-error messages likesuccessandpassed_check.
- The new output functions (
-
Unused Test Files:
- The new test files (
test_policy_messages.yaml,test_scenarios_messages.yaml,test_success.yaml) are added but not integrated into the test suite. - Recommendation: Ensure these files are used in automated tests to validate the new functionality.
- The new test files (
Summary of Changes Required
🔴 CRITICAL
- Validate and sanitize user-supplied file paths to prevent path traversal and arbitrary file access.
- Avoid exposing sensitive information in error messages.
🟡 WARNING
- Add a
--plainor--no-colorflag to maintain backward compatibility with plain text output.
💡 SUGGESTIONS
- Define consistent exit codes for CLI commands.
- Add unit tests for the new colored output functions.
- Consider making
richan optional dependency or document it clearly. - Refactor repetitive error-handling code into a helper function.
- Specify
encoding="utf-8"when reading files. - Add type annotations to the new functions.
- Update CLI documentation to reflect the new output format and dependency.
- Use
sys.stdoutfor non-error messages. - Integrate the new test files into the test suite.
Final Assessment
The PR introduces a useful feature that improves the user experience of the CLI. However, it introduces potential security risks and backward compatibility concerns that must be addressed before merging.
imran-siddique
left a comment
There was a problem hiding this comment.
Thanks for the contribution @yacinemebarki! The colored output is a nice UX improvement, but a few issues:
-
New dependency not declared — \rom rich import print\ adds a runtime dependency on
ich, but agent-os-kernel's pyproject.toml only requires \pydantic. Either add
ich\ to dependencies or make it a lazy/optional import with fallback. -
Shadows built-in — \rom rich import print\ shadows Python's built-in \print. Use \rom rich import print as rprint\ or \rom rich.console import Console.
-
Output to stderr — All the color functions print to \sys.stderr. The validate command's normal output should go to stdout; only errors to stderr.
-
Removed blank lines — Several blank line removals change the code style without adding value. Please keep formatting changes minimal.
Please fix these and I'll re-review.
There was a problem hiding this comment.
🤖 AI Agent: code-reviewer
Review of Pull Request: Adding Function to Print Colored Terminal Output
Summary
This PR introduces a new feature to enhance the CLI output of the agent-governance package by adding colored terminal output using the rich library. It includes new functions for different message types (error, success, warn, policy_violation, passed_check) and updates the CLI commands (validate, test, diff) to use these functions. A new test script (test_cli_output.py) is also added to demonstrate the functionality.
Review
1. Policy Engine Correctness
- The changes in this PR do not directly affect the policy engine's logic or decision-making. The modifications are limited to improving the CLI output for better user experience. No issues identified in this area.
2. Trust/Identity: Cryptographic Operations, Credential Handling, SPIFFE/SVID
- This PR does not introduce or modify any cryptographic operations, credential handling, or SPIFFE/SVID-related functionality. No issues identified in this area.
3. Sandbox Escape Vectors
- The changes do not introduce any new sandbox escape vectors. The
richlibrary is a well-known and widely used library for terminal output formatting. However, it is important to ensure that user-controlled input is sanitized before being passed to therich.printfunction to avoid potential injection attacks. - 🔴 CRITICAL: The
error,warn,policy_violation, and other functions directly pass user-controlled input (msg) to therich.printfunction without sanitization. This could lead to potential injection attacks if the input contains malicious ANSI escape sequences. Consider sanitizing the input to prevent abuse.
4. Thread Safety in Concurrent Agent Execution
- The functions introduced in this PR (
error,success, etc.) are not thread-safe. If multiple threads call these functions simultaneously, the output may become interleaved, leading to garbled or unreadable terminal output. - 💡 SUGGESTION: Use a thread-safe mechanism (e.g., a
threading.Lock) to ensure that only one thread writes to the terminal at a time.
5. OWASP Agentic Top 10 Compliance
- The changes do not introduce any direct violations of OWASP Agentic Top 10 principles. However, as mentioned earlier, the lack of input sanitization for terminal output could potentially lead to security issues.
6. Type Safety and Pydantic Model Validation
- The new functions (
error,success, etc.) do not use type hints for their parameters. While this is not a critical issue, adding type hints would improve code readability and maintainability. - 💡 SUGGESTION: Add type hints to the new functions. For example:
def error(msg: str) -> None: ...
7. Backward Compatibility
- The changes in this PR are non-breaking, as they only modify the CLI output and do not affect the existing API or functionality. No issues identified in this area.
8. Testing
- A new test script (
test_cli_output.py) is included to demonstrate the functionality of the new CLI output functions. However, this script is not integrated into the automated test suite and does not use thepytestframework. - 💡 SUGGESTION: Convert the test script into proper unit tests using
pytest. For example:import pytest from rich.console import Console from agent_os.policies.cli import success, error, warn, policy_violation, passed_check @pytest.fixture def console(): return Console() def test_success(console, capsys): success("Test success message") captured = capsys.readouterr() assert "[green]Test success message[/green]" in captured.err def test_error(console, capsys): error("Test error message") captured = capsys.readouterr() assert "[red]Test error message[/red]" in captured.err # Add similar tests for warn, policy_violation, and passed_check
Recommendations
-
🔴 CRITICAL: Sanitize user-controlled input (
msg) before passing it to therich.printfunction to prevent potential injection attacks via ANSI escape sequences.- Consider using a library like
htmlorreto escape or sanitize input strings.
- Consider using a library like
-
💡 SUGGESTION: Add type hints to the new functions for better code readability and maintainability.
-
💡 SUGGESTION: Ensure thread safety for the new functions by using a
threading.Lockor similar mechanism to prevent interleaved output in multi-threaded scenarios. -
💡 SUGGESTION: Integrate the new test script into the automated test suite using the
pytestframework. This will ensure that the new functionality is tested consistently during CI/CD runs. -
💡 SUGGESTION: Update the documentation to include details about the new CLI output functions and their usage.
Final Assessment
- The PR introduces a useful feature for improving the user experience of the CLI.
- However, the lack of input sanitization for terminal output is a critical security issue that must be addressed before merging.
- Once the critical issue is resolved and the suggested improvements are implemented, the PR will be ready for approval.
There was a problem hiding this comment.
🤖 AI Agent: code-reviewer
Review Summary
This pull request introduces a new feature to enhance the CLI output of the agent-governance package by adding colored terminal output using the rich library. It also includes a new test script to verify the functionality of the colored output functions. While the feature improves the user experience, there are several areas that require attention to ensure robustness, maintainability, and security.
🔴 CRITICAL
-
Unvalidated User Input in CLI Functions:
- The
error,success,warn,policy_violation, andpassed_checkfunctions directly pass user-provided messages to theprintfunction without sanitization or validation. This could lead to unintended behavior, such as terminal escape sequence injection. - Recommendation: Sanitize or validate the input to ensure no malicious escape sequences are passed. For example:
from rich.text import Text def error(msg): sanitized_msg = Text.from_markup(msg, style="red") print(sanitized_msg, file=sys.stderr)
- The
-
Test Coverage for CLI Functions:
- The
test_cli_output.pyscript does not include automated tests. Instead, it relies on manual inspection of the terminal output. - Recommendation: Replace the manual test script with automated tests using a library like
pytestandpytest-console-scriptsorpytest-capturelog. This will ensure that the output is consistently validated in CI/CD pipelines.
- The
🟡 WARNING
- Backward Compatibility:
- The PR replaces all existing
printstatements with calls to the new functions. While this is a non-breaking change in terms of functionality, it alters the appearance of the CLI output, which may impact users relying on the previous format (e.g., for parsing logs). - Recommendation: Add a configuration flag (e.g.,
--no-color) to allow users to disable colored output and revert to plain text if needed. This ensures backward compatibility.
- The PR replaces all existing
💡 SUGGESTIONS
-
Use a Logging Library:
- Instead of using
printstatements, consider using Python's built-inloggingmodule with a custom handler forrich-formatted output. This approach provides better flexibility, configurability, and integration with existing logging systems. - Example:
from rich.logging import RichHandler import logging logging.basicConfig(level="INFO", handlers=[RichHandler()]) logger = logging.getLogger("agent-governance") def error(msg): logger.error(msg)
- Instead of using
-
Thread Safety:
- The
printfunction is not thread-safe. If the CLI is used in a multithreaded context, concurrent calls to these functions could result in interleaved or corrupted output. - Recommendation: Use a thread-safe logging mechanism or a thread-safe wrapper around
print.
- The
-
Dependency Management:
- The
richlibrary is introduced as a new dependency but is not added to therequirements.txtorpyproject.tomlfile. - Recommendation: Add
richto the appropriate dependency file to ensure it is installed during deployment.
- The
-
Function Naming:
- The function names (
error,success, etc.) are generic and could potentially conflict with other parts of the codebase or third-party libraries. - Recommendation: Use more descriptive names, such as
print_error,print_success, etc., to avoid potential naming conflicts.
- The function names (
-
Documentation:
- The PR does not include updates to the documentation to reflect the new CLI behavior.
- Recommendation: Update the CLI documentation to describe the new colored output and any new configuration options (e.g.,
--no-color).
-
Unit Test Assertions:
- The test script does not include assertions to verify the correctness of the output.
- Recommendation: Use
pytestand capture the output of the CLI functions to assert that the correct colors and formats are applied. For example:from rich.console import Console from io import StringIO def test_error_output(): console = Console(file=StringIO()) error("Test error message", console=console) output = console.file.getvalue() assert "[red]Test error message[/red]" in output
-
File Naming for Tests:
- The test file is named
test_cli_output.py, but it does not follow the naming conventions of the existing test suite. - Recommendation: Rename the file to match the project's test naming conventions (e.g.,
test_policies_cli.py).
- The test file is named
Final Assessment
- Security: 🔴 CRITICAL issues related to unvalidated user input in CLI functions.
- Backward Compatibility: 🟡 WARNING due to changes in CLI output format.
- Code Quality: 💡 Several suggestions for improvement, including better test coverage, thread safety, and dependency management.
Action Items
- Address the critical security issue by sanitizing user input in CLI functions.
- Add automated tests for the new functions to ensure consistent behavior.
- Introduce a
--no-colorflag to maintain backward compatibility. - Consider using a logging library for better flexibility and thread safety.
- Update the documentation to reflect the new CLI behavior.
- Add
richto the dependency management files. - Rename the test file to align with the project's conventions.
Let me know if you need further clarification or assistance!
There was a problem hiding this comment.
🤖 AI Agent: code-reviewer
Review of Pull Request: Adding Function to Print Colored Terminal Output
Summary:
This PR introduces a new feature to the agent-governance package by adding colored terminal output to the CLI using the rich library. It includes helper functions for different message types (error, success, warn, policy_violation, passed_check) and updates the CLI commands (validate, test, diff) to use these functions. A new test script (test_cli_output.py) is also added to verify the functionality.
Feedback:
🔴 CRITICAL
-
Error Handling for Missing
richLibrary:-
The fallback mechanism for when
richis not installed (rprintdefaults toprint) is insufficient for a security-focused library. Ifrichis not installed, the CLI will silently degrade to unformatted output, which could lead to confusion or missed critical messages. -
Recommendation: Explicitly check for the presence of
richduring initialization and fail with a clear error message if it is not installed. This ensures that the library's behavior is consistent and predictable.try: from rich import print as rprint except ImportError: sys.stderr.write("ERROR: The 'rich' library is required for this CLI. Please install it using 'pip install rich'.\n") sys.exit(2)
-
-
Potential Information Disclosure in Error Messages:
- The
errorandpolicy_violationfunctions directly output exception messages (e.g.,f"ERROR: failed to parse {path}: {exc}"). This could expose sensitive information (e.g., file paths, stack traces) to unauthorized users. - Recommendation: Sanitize error messages to avoid leaking sensitive information. For example:
error(f"ERROR: failed to parse {path}. Please check the file format.")
- The
-
Testing Script (
test_cli_output.py):- The test script is not a proper unit test. It is a standalone script that requires manual execution and observation of output, which is not suitable for automated CI/CD pipelines.
- Recommendation: Replace the script with proper unit tests using
pytestand mock therprintfunction to verify the output. For example:from unittest.mock import patch from agent_os.policies.cli import success, error def test_success_output(): with patch("rich.print") as mock_rprint: success("Test passed") mock_rprint.assert_called_once_with("[green]Test passed[/green]") def test_error_output(): with patch("rich.print") as mock_rprint: error("Test failed") mock_rprint.assert_called_once_with("[red]Test failed[/red]", file=sys.stderr)
🟡 WARNING
-
Backward Compatibility:
- The changes replace all instances of
printwithrprintor the new helper functions. While this improves readability and user experience, it may break existing scripts or integrations that rely on the previous plain-text output. - Recommendation: Add a CLI flag (e.g.,
--no-color) to allow users to disable colored output and revert to plain-text messages. This ensures backward compatibility for users who rely on parsing the CLI output.
- The changes replace all instances of
-
Removed YAML Test Files:
- The PR mentions the removal of "obsolete YAML test files" but does not provide details. If these files were used in existing tests, their removal could break the test suite or reduce coverage.
- Recommendation: Ensure that the removal of these files does not impact test coverage. If they are no longer needed, provide a clear explanation in the PR description.
💡 SUGGESTIONS
-
Improved Logging:
- Consider integrating a logging library (e.g., Python's
loggingmodule) for better control over message formatting and levels. This would allow for more granular control over output (e.g., debug, info, warning, error) and make it easier to redirect logs to files or other outputs.
- Consider integrating a logging library (e.g., Python's
-
Thread Safety:
- While the changes in this PR do not introduce threading, the use of global functions like
rprintcould lead to issues in a multithreaded environment if future changes introduce concurrency. - Recommendation: Ensure that the CLI functions are thread-safe by avoiding shared mutable state or using thread-local storage if necessary.
- While the changes in this PR do not introduce threading, the use of global functions like
-
Documentation:
- Update the CLI documentation to reflect the new colored output and the meaning of each color/style. If a
--no-colorflag is added, document its usage as well.
- Update the CLI documentation to reflect the new colored output and the meaning of each color/style. If a
-
Code Style:
- Some comments and docstrings have been removed or simplified (e.g., in
cmd_validate,cmd_test, andcmd_diff). While this reduces verbosity, it also makes the code less self-explanatory. - Recommendation: Retain or enhance comments and docstrings to ensure clarity, especially for critical functions.
- Some comments and docstrings have been removed or simplified (e.g., in
-
Testing Coverage:
- Extend test coverage to include edge cases, such as:
- Missing or malformed policy files.
- Scenarios with unexpected data types or missing keys.
- CLI commands with invalid arguments.
- Extend test coverage to include edge cases, such as:
Actionable Summary:
- 🔴 Critical: Improve error handling for missing
richlibrary and sanitize error messages to avoid information disclosure. - 🟡 Warning: Add a
--no-colorflag for backward compatibility and verify the impact of removed YAML test files. - 💡 Suggestions: Replace the standalone test script with proper unit tests, enhance documentation, and ensure thread safety.
Once these issues are addressed, the PR will be in a much stronger position for merging.
There was a problem hiding this comment.
🤖 AI Agent: code-reviewer
Review of Pull Request: Adding Function to Print Colored Terminal Output
General Feedback
This PR introduces a new feature to enhance the CLI output by adding color-coded messages using the rich library. The feature is well-scoped and improves the user experience by making the CLI output more readable and visually distinct. The implementation is clean and follows the project's coding style. However, there are a few areas that need attention to ensure robustness, maintainability, and security.
🔴 CRITICAL
-
Dynamic Import of
richLibrary:- The
_import_rprintfunction dynamically imports therichlibrary at runtime. While this is a fallback mechanism for environments whererichmight not be installed, it introduces potential security risks, as dynamic imports can be exploited if the environment is compromised. - Recommendation: Instead of dynamically importing
rich, add it as a required dependency in therequirements.txtorpyproject.tomlfile. This ensures that the library is always available and avoids runtime surprises.
- The
-
Error Handling in
_import_rprint:- If
richis not installed,_import_rprintsilently falls back toprint. This could lead to inconsistent behavior across environments. - Recommendation: If
richis a required dependency, raise an exception if it is not installed. If it is optional, log a warning to inform the user that colored output is disabled due to the missing dependency.
- If
🟡 WARNING
- Potential Breaking Change in CLI Output:
- The PR replaces plain text output with color-coded output. While this is a non-breaking change in terms of functionality, it could affect users or systems that parse the CLI output programmatically.
- Recommendation: Add a CLI flag (e.g.,
--no-color) to disable colored output and revert to plain text. This ensures backward compatibility for users who rely on the plain text format.
💡 SUGGESTIONS
-
Test Coverage:
- The
test_cli_output.pyfile is more of a manual testing script than an automated test. It does not verify the correctness of the output programmatically. - Recommendation: Use a testing framework like
pytestto capture and assert the output of the colored functions. For example, usecapsys(a pytest fixture) to capture printed output and compare it against expected values.
Example:
def test_success_output(capsys): success("Test passed") captured = capsys.readouterr() assert "[green]Test passed[/green]" in captured.out
- The
-
Centralized Import of
rich:- The
_import_rprintfunction is called repeatedly in each helper function, which is inefficient and could lead to inconsistent behavior. - Recommendation: Perform the
richimport once at the module level and handle the fallback toprintthere. For example:try: from rich import print as rprint except ImportError: rprint = print
- The
-
Documentation:
- The PR does not include updates to the documentation. Users need to know about the new colored output feature and how to use it.
- Recommendation: Update the CLI documentation to mention the new color-coded output and any new flags (e.g.,
--no-colorif implemented).
-
Code Duplication:
- The color-coded output functions (
error,success,warn, etc.) have repetitive code for importingrprintand checking if it isNone. - Recommendation: Refactor the functions to reduce duplication. For example:
def print_colored(msg: str, color: str, is_bold: bool = False, is_error: bool = False) -> None: style = f"[{color}]{msg}[/{color}]" if is_bold: style = f"[bold]{style}[/bold]" rprint = _import_rprint() if rprint is not None: rprint(style, file=sys.stderr if is_error else sys.stdout) else: print(msg, file=sys.stderr if is_error else sys.stdout)
- The color-coded output functions (
-
Unicode Compatibility:
- The
passed_checkfunction uses a Unicode checkmark (\u2714). While this enhances readability, it may not render correctly in all terminal environments. - Recommendation: Provide a fallback for environments that do not support Unicode, or allow users to disable Unicode characters via a CLI flag.
- The
-
Testing Edge Cases:
- The current implementation does not test edge cases, such as very long messages, multiline messages, or messages containing special characters.
- Recommendation: Add tests to cover these scenarios to ensure the functions handle them gracefully.
-
Performance Considerations:
- The repeated calls to
_import_rprintcould have a minor performance impact, especially in scenarios where the CLI is invoked frequently. - Recommendation: Cache the result of
_import_rprintto avoid redundant imports.
- The repeated calls to
Summary of Actionable Feedback
🔴 CRITICAL
- Replace dynamic import of
richwith a static import and add it as a required dependency. - Improve error handling in
_import_rprintto avoid silent failures.
🟡 WARNING
- Add a
--no-colorflag to ensure backward compatibility for users relying on plain text output.
💡 SUGGESTIONS
- Replace manual testing script with automated tests using
pytest. - Refactor color-coded output functions to reduce code duplication.
- Update documentation to reflect the new feature.
- Add fallback for Unicode characters in
passed_check. - Test edge cases for message formatting.
- Cache the result of
_import_rprintto improve performance.
Final Notes
The feature is a valuable addition to the project, enhancing the user experience for the CLI. Addressing the above feedback will ensure the implementation is robust, secure, and backward-compatible. Let me know if you need further clarification or assistance!
|
Thanks for the thorough review! @imran-siddique I've addressed all four points and tried to implimented:
Let me know if anything else needs adjusting! |
|
@microsoft-github-policy-service agree |
There was a problem hiding this comment.
🤖 AI Agent: code-reviewer
Review Summary
This pull request introduces a new feature to enhance the CLI output of the agent-os package by adding support for colored terminal output using the rich library. It also includes new utility functions for different message types (error, success, warn, policy_violation, passed_check) and updates the CLI commands (validate, test, diff) to use these functions. Additionally, tests for the new functionality have been added.
The changes are well-structured and improve the user experience by making the CLI output more readable. However, there are a few areas that need attention to ensure the robustness, security, and maintainability of the code.
🔴 CRITICAL
-
Dynamic Import of
richLibrary- The
_import_rprintfunction dynamically imports therichlibrary at runtime. This approach could lead to potential security vulnerabilities if therichmodule is replaced or tampered with in the Python environment. - Recommendation: Instead of dynamically importing
rich, add it as a required dependency inpyproject.tomland import it statically at the top of the file. If you want to support environments withoutrich, consider using a feature flag or environment variable to conditionally enable/disable colored output.
- The
-
Policy Violation Output to
stderr- The
policy_violationfunction outputs tostdoutinstead ofstderr. Policy violations are critical errors and should be directed tostderrfor proper logging and error handling. - Recommendation: Update the
policy_violationfunction to usefile=sys.stderrwhen callingrprintorprint.
- The
🟡 WARNING
- Backward Compatibility
- The introduction of colored output changes the format of the CLI output, which could potentially break scripts or tools that parse the output of the CLI commands.
- Recommendation: Add a
--no-colorflag to allow users to disable colored output and maintain compatibility with existing workflows. This flag should default toFalseto preserve the current behavior.
💡 SUGGESTIONS
-
Test Coverage
- While the new utility functions are tested, the tests only check for the presence of specific substrings in the output. This approach does not verify the presence of color codes or formatting.
- Recommendation: Use the
richlibrary'sConsoleobject with a customio.StringIOfile to capture and verify the actual formatted output. This will ensure that the color codes and formatting are applied correctly.
-
Error Handling for Missing
rich- The fallback to plain text when
richis not installed is a good approach. However, it might be helpful to log a warning message (e.g., "Rich library not found, falling back to plain text output.") to inform users about the fallback. - Recommendation: Add a one-time warning message when the
richlibrary is not found.
- The fallback to plain text when
-
Function Naming
- The function names (
error,success,warn, etc.) are clear, but they could be more descriptive to avoid potential conflicts with other modules or libraries. - Recommendation: Consider prefixing the function names with
cli_oroutput_(e.g.,cli_error,cli_success) to make them more specific to the CLI context.
- The function names (
-
Code Duplication in
_import_rprintUsage- The repeated calls to
_import_rprintin each utility function introduce unnecessary duplication. - Recommendation: Refactor
_import_rprintto a module-level variable (e.g.,RPRINT) that is initialized once and reused across all functions.
- The repeated calls to
-
Documentation
- The PR mentions that documentation updates are not included. However, the new functionality should be documented, especially for users who might want to disable colored output in the future.
- Recommendation: Update the CLI documentation to describe the new colored output feature and the potential addition of a
--no-colorflag.
-
Test Cases for CLI Commands
- The current tests only cover the utility functions but do not test the integration of these functions into the
validate,test, anddiffcommands. - Recommendation: Add integration tests for the CLI commands to ensure that the colored output works as expected in different scenarios.
- The current tests only cover the utility functions but do not test the integration of these functions into the
-
Unicode Handling
- The
passed_checkfunction uses the Unicode checkmark character (\u2714). While this improves readability, it may not render correctly in all terminal environments. - Recommendation: Provide a fallback option for environments that do not support Unicode characters.
- The
Summary of Changes Needed
Critical
- Replace dynamic import of
richwith a static import or feature flag. - Update
policy_violationto output tostderr.
Warning
- Add a
--no-colorflag to maintain backward compatibility.
Suggestions
- Improve test coverage to verify color codes and formatting.
- Log a warning when
richis not installed and falling back to plain text. - Refactor function names to avoid potential conflicts.
- Refactor
_import_rprintto a module-level variable to reduce duplication. - Update documentation to include details about the new feature.
- Add integration tests for CLI commands.
- Provide a fallback for Unicode characters in
passed_check.
These changes will improve the security, maintainability, and usability of the new feature while minimizing the risk of breaking existing workflows.
There was a problem hiding this comment.
🤖 AI Agent: code-reviewer
Review Summary
This PR introduces a new feature to enhance the CLI output of the agent-os package by adding colored text using the rich library. It also includes fallback behavior for environments where rich is not installed. The changes are well-structured and include tests to verify the functionality of the new output methods. However, there are some areas that require attention to ensure robustness, security, and maintainability.
🔴 CRITICAL
-
Dynamic Import of
richLibrary:- The
_import_rprintfunction dynamically imports therichlibrary. While this is done to provide a fallback mechanism, it introduces a potential security risk if therichmodule is replaced or tampered with in the environment. - Recommendation: Instead of dynamically importing
rich, make it a required dependency inpyproject.tomland handle the--no-colorflag explicitly to disable colored output. This ensures the library is always available and avoids runtime import risks.
- The
-
Policy Violation Output to
stdout:- The
policy_violationfunction outputs tostdoutinstead ofstderr. Policy violations are critical errors and should be directed tostderrto ensure proper logging and error handling. - Recommendation: Update the
policy_violationfunction to usesys.stderrfor output.
- The
🟡 WARNING
- Backward Compatibility:
- The PR introduces colored output to the CLI, which may break existing scripts or tools that parse the CLI output (e.g., CI pipelines or log parsers). Even though the fallback to plain text is implemented, the default behavior is now colored output.
- Recommendation: Add a
--no-colorflag to explicitly disable colored output, as mentioned in the PR description. This ensures backward compatibility for users who rely on plain text output.
💡 SUGGESTIONS
-
Test Coverage:
- The new tests in
test_cli_output.pyverify the presence of specific strings in the output but do not test the actual color codes whenrichis installed. - Recommendation: Use
pytest-mockor a similar library to mock therich.printfunction and verify that the correct color codes are being passed to it.
- The new tests in
-
Error Handling for
richImport:- The
_import_rprintfunction silently falls back toprintifrichis not installed. While this is acceptable, it might be helpful to log a warning message to inform users that colored output is disabled due to the missing dependency. - Recommendation: Add a warning log when
richis not installed, so users are aware of the fallback.
- The
-
Code Duplication:
- The
_import_rprintfunction is called repeatedly in each helper function, leading to redundant imports. - Recommendation: Import
richonce at the module level and use a global flag to determine whether to use colored output or plain text. This will improve performance and reduce code duplication.
- The
-
Documentation:
- The PR does not include updates to the documentation, which is marked as incomplete in the checklist.
- Recommendation: Update the CLI documentation to include details about the new colored output and the potential addition of the
--no-colorflag.
-
Error Message Consistency:
- Some error messages use "ERROR:" while others do not. Consistency in error message formatting improves readability and debugging.
- Recommendation: Standardize error message prefixes across all functions.
-
Unicode Handling:
- The
passed_checkfunction uses a Unicode checkmark (\u2714). While this is visually appealing, it may not render correctly in all terminal environments. - Recommendation: Provide a fallback for environments that do not support Unicode, or allow users to disable Unicode symbols via a CLI flag.
- The
Additional Notes
- The use of
richis a good choice for enhancing CLI output, as it is a well-maintained and widely used library. - The fallback mechanism for environments without
richis a thoughtful addition, but it could be improved as suggested above. - The removal of obsolete YAML test files is a good cleanup step, but it should be mentioned explicitly in the PR description as part of the "Maintenance" category.
Suggested Actions
-
Address the CRITICAL issues:
- Make
richa required dependency. - Update
policy_violationto output tostderr.
- Make
-
Address the WARNING issue:
- Add a
--no-colorflag to disable colored output.
- Add a
-
Consider implementing the SUGGESTIONS:
- Improve test coverage for color codes.
- Add a warning log for missing
rich. - Refactor
_import_rprintto avoid redundant imports. - Update documentation for the new feature.
- Standardize error message formatting.
- Add a fallback for Unicode symbols.
Final Assessment
The PR introduces a useful feature that improves the readability of CLI output. However, the dynamic import of rich and the use of stdout for critical policy violation messages are significant issues that need to be addressed before merging. Additionally, the potential for breaking changes due to the introduction of colored output should be mitigated by adding a --no-color flag. Once these issues are resolved, the PR will be ready for approval.
Head branch was pushed to by a user without write access
There was a problem hiding this comment.
🤖 AI Agent: code-reviewer
Review of Pull Request: Adding Function to Print Colored Terminal Output
General Feedback
The PR introduces a new feature to enhance the CLI output of the agent-governance package by adding color-coded messages using the rich library. This improves the readability and user experience of the CLI. The implementation is well-structured, and the use of helper functions for different message types ensures modularity and reusability. However, there are a few areas that require attention to ensure robustness, security, and backward compatibility.
🔴 CRITICAL
-
Error Handling for
richImport:- The
_import_consolefunction catches all exceptions (except Exception) when importingrich.console.Console. This is overly broad and could mask unexpected errors unrelated to therichlibrary. For example, if there is a syntax error or a misconfiguration in the environment, it would silently fail and degrade to plain text output. - Action: Narrow the exception handling to specifically catch
ModuleNotFoundErrororImportErrorfor therichlibrary.try: from rich.console import Console return Console(stderr=use_stderr, no_color=no_color) except (ModuleNotFoundError, ImportError): return None
- The
-
Policy Violation Output to
stderr:- The
policy_violation()function currently outputs tostdout. However, policy violations are critical errors and should be directed tostderrto align with standard CLI practices. - Action: Update the
policy_violation()function to useuse_stderr=Truewhen initializing theConsoleobject.
- The
🟡 WARNING
- Backward Compatibility:
- Adding the
richlibrary as a dependency could potentially break environments whererichis not installed or where dependency conflicts arise. While the fallback to plain text is implemented, the dependency itself may still cause issues. - Action: Consider marking
richas an optional dependency inpyproject.tomland provide a clear error message if it is not installed and the user explicitly requests colored output in the future (e.g., with a--colorflag).
- Adding the
💡 SUGGESTIONS
-
Add a
--no-colorFlag:- While the PR mentions the possibility of adding a
--no-colorflag in the future, it would be better to implement it now to provide users with the ability to disable colored output if needed (e.g., for logging or when piping output to a file). - Action: Add a
--no-colorflag to the CLI and pass its value to theno_colorparameter in the_import_consolefunction.
- While the PR mentions the possibility of adding a
-
Test Coverage:
- The tests in
test_cli_output.pyare a good start, but they only check for the presence of specific substrings in the output. They do not verify whether the correct color codes are applied whenrichis available. - Action: Use the
richlibrary'sConsoleobject in the tests to capture and verify the actual styled output. For example:from rich.console import Console from io import StringIO def test_success_with_color(): console = Console(file=StringIO(), no_color=False) console.print("This is a success message", style="green") output = console.file.getvalue() assert "[green]This is a success message[/green]" in output
- The tests in
-
Default Behavior for
no_color:- The
no_colorparameter defaults toFalsein the helper functions, but this is not explicitly documented in the docstrings. - Action: Update the docstrings for the helper functions to include the default value of
no_color.
- The
-
Use of Unicode Characters:
- The
passed_check()function uses a Unicode checkmark (\u2714). While this enhances readability, it may not render correctly in all terminal environments. - Action: Provide a fallback for environments that do not support Unicode, or document this behavior in the CLI's usage notes.
- The
-
Test for Fallback Behavior:
- The current tests do not verify the fallback behavior when
richis not installed. - Action: Add a test case that mocks the absence of the
richlibrary (e.g., usingunittest.mock) and verifies that the output falls back to plain text.
- The current tests do not verify the fallback behavior when
-
Code Duplication in Helper Functions:
- The helper functions (
error,success,warn, etc.) have repetitive code for importing the console and checking forNone. - Action: Refactor the helper functions to reduce duplication. For example:
def _print_message(msg: str, style: str, no_color: bool, use_stderr: bool = False) -> None: console = _import_console(no_color, use_stderr) if console: console.print(msg, style=style) else: print(msg, file=sys.stderr if use_stderr else sys.stdout) def error(msg: str, no_color: bool = False) -> None: _print_message(msg, style="red", no_color=no_color, use_stderr=True) def success(msg: str, no_color: bool = False) -> None: _print_message(msg, style="green", no_color=no_color)
- The helper functions (
-
Documentation Update:
- The PR does not include updates to the documentation to reflect the new colored output feature.
- Action: Update the CLI documentation to describe the new color-coded output and the potential addition of a
--no-colorflag.
-
Logging Integration:
- The current implementation uses
print()for output. While this is fine for a CLI, integrating with Python'sloggingmodule would provide more flexibility and allow users to configure logging levels and handlers. - Action: Consider refactoring the CLI to use the
loggingmodule for output, withrichused for formatting the log messages.
- The current implementation uses
Summary of Changes Needed
- 🔴 Critical: Narrow exception handling for
richimport and redirectpolicy_violation()output tostderr. - 🟡 Warning: Consider making
richan optional dependency to avoid potential backward compatibility issues. - 💡 Suggestions:
- Add a
--no-colorflag to the CLI. - Improve test coverage to verify color codes and fallback behavior.
- Refactor helper functions to reduce code duplication.
- Update documentation to reflect the new feature.
- Consider integrating with the
loggingmodule for more robust output handling.
- Add a
Let me know if you need further clarification or assistance!
There was a problem hiding this comment.
🤖 AI Agent: code-reviewer
Review of Pull Request: Adding function to print colored terminal output
General Feedback
The addition of colored terminal output using the rich library is a great enhancement for improving the user experience of the CLI. The implementation is clean, and the fallback mechanism for when rich is not installed is a thoughtful touch. Below is a detailed review of the changes, categorized by focus areas.
🔴 CRITICAL Issues
No critical security issues were identified in this pull request.
🟡 WARNING: Potential Breaking Changes
-
Dependency Addition:
- Adding the
richlibrary as a dependency inpyproject.tomlcould potentially break environments whererichis not available or conflicts with other dependencies. While the fallback to plain text is implemented, the dependency addition should be clearly documented in the release notes, and the maintainers should ensure that this change is communicated to users.
Action: Update the documentation and release notes to inform users about the new dependency on
rich. - Adding the
💡 Suggestions for Improvement
-
Optional
--no-colorFlag:- The PR mentions the possibility of adding a
--no-colorflag in the future to disable colored output. This is a good idea, especially for environments where color codes may not render correctly (e.g., CI pipelines or logs). Consider implementing this feature in this PR to provide users with more control over the output format.
Action: Add a
--no-colorflag to the CLI commands and pass the value to the_import_consolefunction. - The PR mentions the possibility of adding a
-
Error Handling for
richImport:- The
_import_consolefunction currently catches all exceptions (except Exception). This is too broad and could potentially mask other issues. It would be better to catch onlyImportErrororModuleNotFoundErrorwhen attempting to importrich.
Action: Update
_import_consoleto catch specific exceptions likeImportErrororModuleNotFoundError. - The
-
Test Coverage:
- While the new functions are tested for their output, the tests do not verify the behavior when
richis not installed. This is an important edge case to test, as the fallback to plain text is a key part of the implementation.
Action: Add tests to simulate the absence of the
richlibrary and verify that the fallback to plain text works as expected. - While the new functions are tested for their output, the tests do not verify the behavior when
-
Thread Safety:
- The
rich.console.Consoleobject is instantiated multiple times in the helper functions. If these functions are called concurrently, there could be potential thread-safety issues withrich. Whilerichis generally thread-safe, it might be more efficient and safer to create a singleConsoleinstance and reuse it across the application.
Action: Refactor the code to create a single
Consoleinstance (or two instances: one forstdoutand one forstderr) and reuse them across the CLI functions. - The
-
Default
no_colorBehavior:- The
no_colorparameter defaults toFalsein the helper functions. However, this behavior is not configurable by the user at runtime. If the--no-colorflag is not implemented in this PR, consider adding an environment variable (e.g.,AGENT_OS_NO_COLOR) that users can set to disable colors globally.
Action: Add support for an environment variable to control the
no_colorbehavior. - The
-
Error Messages Consistency:
- The error messages use the prefix
ERROR:in some places and not in others. For example:vs.error(f"ERROR: file not found: {path}")
This inconsistency might confuse users.error("ERROR: failed to load policies: {exc}")
Action: Standardize error message prefixes across the CLI.
- The error messages use the prefix
-
Use of Unicode Characters:
- The
passed_checkfunction uses a Unicode checkmark (\u2714). While this improves readability, it may not render correctly in all terminal environments.
Action: Consider providing a fallback for environments that do not support Unicode characters.
- The
-
Documentation:
- The PR does not include updates to the documentation. Since this change affects the CLI output, it would be helpful to update the documentation to reflect the new behavior and the potential future addition of the
--no-colorflag.
Action: Update the documentation to describe the new colored output and the fallback mechanism.
- The PR does not include updates to the documentation. Since this change affects the CLI output, it would be helpful to update the documentation to reflect the new behavior and the potential future addition of the
Code Quality
-
Code Duplication:
- The helper functions (
error,success,warn, etc.) have a lot of duplicated code for importing theConsoleand checking for its existence.
Action: Refactor the helper functions to reduce code duplication. For example, you could create a single function that takes the message, style, and output stream as parameters.
def print_message(msg: str, style: str, use_stderr: bool = False, no_color: bool = False) -> None: console = _import_console(no_color, use_stderr) if console: console.print(msg, style=style) else: print(msg, file=sys.stderr if use_stderr else sys.stdout) def error(msg: str, no_color: bool = False) -> None: print_message(msg, style="red", use_stderr=True, no_color=no_color) def success(msg: str, no_color: bool = False) -> None: print_message(msg, style="green", no_color=no_color)
- The helper functions (
-
Function Naming:
- The function names (
error,success, etc.) are clear, but they could be more descriptive to avoid potential naming conflicts. For example,print_errorinstead oferror.
Action: Consider renaming the functions to more descriptive names like
print_error,print_success, etc. - The function names (
Backward Compatibility
The changes in this PR are non-breaking, as the CLI commands retain their existing functionality and the colored output is an enhancement. However, the addition of the rich dependency should be clearly communicated to users.
Summary of Feedback
🔴 CRITICAL
- None identified.
🟡 WARNING
- Document the addition of the
richdependency to avoid potential breaking changes for users.
💡 SUGGESTIONS
- Implement the
--no-colorflag to allow users to disable colored output. - Update
_import_consoleto catch specific exceptions (ImportErrororModuleNotFoundError) instead ofException. - Add tests to verify the fallback behavior when
richis not installed. - Refactor to reuse a single
Consoleinstance for thread safety and efficiency. - Standardize error message prefixes for consistency.
- Provide a fallback for Unicode characters in
passed_check. - Update the documentation to reflect the new behavior and the potential addition of the
--no-colorflag. - Refactor the helper functions to reduce code duplication.
- Consider more descriptive function names to avoid potential naming conflicts.
Overall, this is a well-implemented feature that enhances the usability of the CLI. Addressing the above suggestions will further improve the robustness and maintainability of the code.
There was a problem hiding this comment.
🤖 AI Agent: code-reviewer
Review Summary
This pull request introduces a new feature to enhance the CLI output of the agent-os package by adding colored terminal output using the rich library. The changes include helper functions for different message types, integration of these functions into existing CLI commands, and corresponding tests to ensure the functionality works as expected. While the changes improve the user experience, there are several areas that need attention to ensure security, maintainability, and backward compatibility.
🔴 CRITICAL
-
Unvalidated Input in Output Functions:
- The
error,success,warn,policy_violation, andpassed_checkfunctions directly print user-provided strings without sanitization. This could lead to unintended consequences, such as terminal escape sequence injection. - Recommendation: Sanitize the input messages to ensure no malicious escape sequences can be injected. For example, use
rich.text.Text.from_markupwithvalidate=Trueto sanitize the input.
from rich.text import Text def error(msg: str, no_color: bool = False) -> None: """Print an error message in red to stderr.""" console = _import_console(no_color, use_stderr=True) if console: console.print(Text.from_markup(msg, validate=True), style="red") else: print(msg, file=sys.stderr)
- The
-
Fallback Behavior Without
rich:- If
richis not installed, the CLI falls back to plain text output. However, this behavior is not explicitly documented or tested. - Recommendation: Add a clear warning message when
richis not installed, so users are aware that they are seeing plain text output. Additionally, add test cases to verify the fallback behavior.
- If
🟡 WARNING
-
Dependency Addition:
- Adding
richas a dependency could potentially break environments where the library is not available or conflicts with other dependencies. - Recommendation: Ensure that
richis added to therequirements.txtor equivalent dependency management file. Also, consider making it an optional dependency and providing a clear error message if the library is not installed.
- Adding
-
Behavior Change in CLI Output:
- The introduction of colored output changes the appearance of CLI messages, which could affect scripts or tools that parse the output.
- Recommendation: Add a
--no-colorflag to disable colored output explicitly. This ensures backward compatibility for users who rely on plain text output.
💡 SUGGESTIONS
-
Centralized Console Initialization:
- The
_import_consolefunction is called multiple times in the helper functions. This could lead to redundant initialization of theConsoleobject. - Recommendation: Initialize the
Consoleobject once (e.g., at the module level or in a singleton pattern) and reuse it across the helper functions.
from rich.console import Console console = Console(stderr=False) error_console = Console(stderr=True) def error(msg: str, no_color: bool = False) -> None: """Print an error message in red to stderr.""" if no_color: print(msg, file=sys.stderr) else: error_console.print(msg, style="red")
- The
-
Test Coverage:
- The new test cases in
test_cli_output.pyare a good start, but they do not cover edge cases, such as:- Behavior when
richis not installed. - Behavior when
no_color=True. - Handling of special characters or escape sequences in messages.
- Behavior when
- Recommendation: Add test cases for these scenarios to ensure robust behavior.
- The new test cases in
-
Code Duplication in CLI Commands:
- The CLI commands (
cmd_validate,cmd_test,cmd_diff) have repetitive error-handling code that could be refactored into reusable utility functions. - Recommendation: Create a helper function for error handling and use it across the CLI commands.
def handle_error(message: str, no_color: bool = False) -> int: error(message, no_color) return 2
- The CLI commands (
-
Documentation:
- The PR mentions that documentation updates are pending. However, it is crucial to document the new colored output behavior, including the fallback mechanism and the potential
--no-colorflag. - Recommendation: Update the CLI documentation to reflect the changes and provide examples of the new output.
- The PR mentions that documentation updates are pending. However, it is crucial to document the new colored output behavior, including the fallback mechanism and the potential
-
Performance Considerations:
- The repeated initialization of the
Consoleobject in_import_consolecould have a minor performance impact, especially in scripts that generate a lot of output. - Recommendation: As mentioned earlier, centralize the
Consoleinitialization to avoid this overhead.
- The repeated initialization of the
Final Thoughts
This PR introduces a useful feature that improves the user experience of the CLI. However, there are critical security concerns related to unsanitized input and potential backward compatibility issues due to the change in output format. Addressing these issues and implementing the suggested improvements will ensure a more robust and secure implementation.
Head branch was pushed to by a user without write access
There was a problem hiding this comment.
🤖 AI Agent: code-reviewer
Review Summary
This PR introduces a feature to add colored terminal output to the Agent-OS Python CLI using the rich library. It enhances the readability of CLI outputs by categorizing messages into different types (e.g., success, error, warning, policy violation) and assigning distinct colors to each. The implementation includes helper functions for printing colored messages and updates the CLI commands (validate, test, and diff) to use these helpers. Additionally, basic tests for the new functionality have been added.
While the feature is a welcome improvement for user experience, there are several areas that need attention, particularly around error handling, testing, and potential edge cases.
🔴 CRITICAL
-
Improper Handling of Missing
richLibrary:- The
_import_consoleand_import_rich_textfunctions print warnings tostderrif therichlibrary is not installed but do not raise an exception or provide a fallback mechanism for theTextclass. - If
richis not installed, theText.from_markup()calls will fail, leading to runtime errors. - Fix: Add a proper fallback mechanism for the
Textclass whenrichis not available. For example:def _import_rich_text(): try: from rich.text import Text return Text except ImportError: return None
- The
-
Potential Security Issue with
Text.from_markup:- The
Text.from_markup()method interprets the input string as markup. If the input string contains user-controlled data, it could lead to unexpected rendering or even security vulnerabilities. - Fix: Use
Text(msg)instead ofText.from_markup(msg)to avoid interpreting user input as markup. If markup is necessary, sanitize the input to ensure it does not contain malicious content.
- The
🟡 WARNING
- Potential Breaking Change:
- The PR changes the CLI output format by adding colors and symbols (e.g., checkmarks). This could break any scripts or tools that rely on parsing the CLI output.
- Action: Clearly document this change in the release notes and consider adding a
--no-colorflag to allow users to opt out of colored output for backward compatibility.
💡 SUGGESTIONS
-
Improve Test Coverage:
- The current tests only check for the presence of specific substrings in the output. They do not verify the presence of color codes or the behavior when
richis not installed. - Enhancement: Add tests to:
- Verify that the output contains the expected ANSI color codes when
richis installed. - Verify that the fallback to plain text works correctly when
richis not installed. - Test the behavior of the
--no-colorflag (if implemented).
- Verify that the output contains the expected ANSI color codes when
- The current tests only check for the presence of specific substrings in the output. They do not verify the presence of color codes or the behavior when
-
Refactor
_import_consoleand_import_rich_text:- The
_import_consoleand_import_rich_textfunctions are called repeatedly in each helper function, leading to redundant imports and potential performance issues. - Enhancement: Refactor these functions to cache the imported modules or objects. For example:
_console = None _text = None def _get_console(no_color: bool = False, use_stderr: bool = False): global _console if _console is None: try: from rich.console import Console _console = Console(stderr=use_stderr, no_color=no_color) except ImportError: _console = None return _console def _get_text(): global _text if _text is None: try: from rich.text import Text _text = Text except ImportError: _text = None return _text
- The
-
Add Logging for Missing
richLibrary:- Instead of printing warnings to
stderrwhenrichis not installed, consider using the logging module. This will allow better control over the verbosity of the messages. - Enhancement: Replace
print()calls in_import_consoleand_import_rich_textwithlogging.warning().
- Instead of printing warnings to
-
Optimize Helper Functions:
- The helper functions (
error,success,warn, etc.) repeat similar logic for importingConsoleandText. This could be simplified by creating a single utility function that handles the common logic. - Enhancement: Refactor the helper functions to reduce code duplication. For example:
def _print_message(msg: str, style: str, no_color: bool, use_stderr: bool): console = _get_console(no_color, use_stderr) Text = _get_text() if console and Text: console.print(Text(msg), style=style) else: print(msg, file=sys.stderr if use_stderr else sys.stdout) def error(msg: str, no_color: bool = False): _print_message(msg, "red", no_color, use_stderr=True) def success(msg: str, no_color: bool = False): _print_message(msg, "green", no_color, use_stderr=False)
- The helper functions (
-
Add Type Hints:
- The new functions and imports lack type hints, which is inconsistent with the rest of the codebase.
- Enhancement: Add type hints to all new functions and variables. For example:
from typing import Optional from rich.console import Console from rich.text import Text def _import_console(no_color: bool = False, use_stderr: bool = False) -> Optional[Console]: ...
-
Consider Dependency Management:
- Adding
richas a dependency increases the size of the project and may not be necessary for all users. - Enhancement: Consider making
richan optional dependency and provide a way to disable colored output (e.g., via a--no-colorflag or an environment variable).
- Adding
-
Documentation:
- The PR mentions that documentation updates are not included. However, this change affects the CLI behavior and should be documented.
- Enhancement: Update the documentation to:
- Explain the new colored output feature.
- Provide usage examples for the CLI commands with colored output.
- Mention the fallback behavior when
richis not installed.
Final Notes
- The addition of colored output is a valuable enhancement for improving the user experience of the CLI.
- Addressing the critical issues and implementing the suggested improvements will ensure the feature is robust, secure, and backward-compatible.
- Once the above issues are resolved, this PR will be ready for approval.
Head branch was pushed to by a user without write access
There was a problem hiding this comment.
🤖 AI Agent: code-reviewer
Review Summary
This pull request introduces a new feature to enhance the CLI output by adding colored text using the rich library. It also includes helper functions for different message types (e.g., errors, warnings, success messages) and updates the CLI commands to use these functions. Additionally, tests for the new functionality are included.
While the feature is a good addition for improving user experience, there are some areas that require attention to ensure robustness, maintainability, and security.
🔴 CRITICAL
-
Unvalidated User Input in CLI Commands:
- The CLI commands (
cmd_validate,cmd_test,cmd_diff) directly use user-provided file paths without validating or sanitizing them. This could lead to potential security issues like path traversal attacks. - Action: Validate and sanitize user inputs to ensure they do not contain malicious paths or unexpected characters. Use libraries like
os.pathorpathlibto normalize paths and ensure they are within expected directories.
- The CLI commands (
-
Improper Error Handling:
- The
_import_consoleand_import_rich_textfunctions catchModuleNotFoundErrorandImportErrorbut do not handle other potential exceptions (e.g.,AttributeErrorifrichchanges its API in the future). - Action: Be more specific about the exceptions you expect and handle them appropriately. For example:
except ImportError as e: print(f"WARNING: {e}", file=sys.stderr)
- The
-
Potential Information Disclosure:
- The error messages in
cmd_validate,cmd_test, andcmd_diffmay leak sensitive information (e.g., file paths, exception details) to the user. - Action: Avoid exposing internal details in error messages. Instead, log detailed errors for debugging purposes and provide user-friendly error messages.
- The error messages in
🟡 WARNING
-
Backward Compatibility:
- The PR introduces new behavior in the CLI output by adding colors. While this is a non-breaking change for most users, it could potentially break scripts or tools that parse the CLI output.
- Action: Add a
--no-colorflag as mentioned in the PR description to allow users to disable colored output. This ensures backward compatibility for users who rely on plain text output.
-
Dependency Addition:
- Adding the
richlibrary as a dependency increases the attack surface of the application. Whilerichis a widely used library, it is important to ensure that it is actively maintained and does not introduce vulnerabilities. - Action: Regularly monitor the
richlibrary for security vulnerabilities and ensure it is updated to the latest version.
- Adding the
💡 SUGGESTIONS
-
Lazy Import Optimization:
- The
_import_consoleand_import_rich_textfunctions are called multiple times within each helper function, which is inefficient. - Action: Cache the imported
ConsoleandTextobjects to avoid redundant imports. For example:_console = None _text = None def _get_console(no_color: bool = False, use_stderr: bool = False): global _console if _console is None: try: from rich.console import Console _console = Console(stderr=use_stderr, no_color=no_color) except ImportError: print("WARNING: rich library not installed, using plain text output", file=sys.stderr) _console = None return _console def _get_text(): global _text if _text is None: try: from rich.text import Text _text = Text except ImportError: print("WARNING: rich library not installed, using plain text output", file=sys.stderr) _text = None return _text
- The
-
Test Coverage:
- The tests for the new helper functions are basic and only check for the presence of specific substrings in the output. They do not verify the presence of color codes or styles.
- Action: Use
rich'sConsoleobject to capture the rendered output and verify that the correct styles (e.g.,red,green,bold red) are applied. For example:from rich.console import Console from io import StringIO def test_success(): console = Console(file=StringIO()) success("This is a success message", console=console) output = console.file.getvalue() assert "[green]This is a success message[/green]" in output
-
Error Message Consistency:
- The error messages in the helper functions (e.g.,
error,policy_violation) include the word "ERROR" or "FAIL" in the message itself. This is redundant since the color and style already convey the severity. - Action: Remove redundant prefixes like "ERROR:" or "FAIL:" from the messages.
- The error messages in the helper functions (e.g.,
-
Documentation:
- The PR does not include any updates to the documentation, even though the CLI behavior has changed.
- Action: Update the documentation to reflect the new colored output and provide examples of the new
--no-colorflag (if implemented).
-
Default Behavior Without
rich:- When
richis not installed, the CLI falls back to plain text output. However, this behavior is not explicitly tested. - Action: Add tests to verify the fallback behavior when
richis not installed. This can be done by temporarily mocking therichimport to raise anImportError.
- When
-
Thread Safety:
- The
Consoleobject is instantiated multiple times and is not thread-safe by default. If the CLI is extended to support concurrent execution in the future, this could lead to race conditions. - Action: Use a single shared
Consoleinstance across threads or ensure thread safety by using thread-local storage.
- The
-
Code Duplication:
- The helper functions (
error,success,warn, etc.) have repetitive code for importingConsoleandText. - Action: Refactor the helper functions to reduce code duplication. For example:
def print_message(msg: str, style: str, no_color: bool = False, use_stderr: bool = False): console = _get_console(no_color, use_stderr) Text = _get_text() if console and Text: console.print(Text(msg), style=style) else: print(msg, file=sys.stderr if use_stderr else sys.stdout) def error(msg: str, no_color: bool = False): print_message(msg, style="red", no_color=no_color, use_stderr=True) def success(msg: str, no_color: bool = False): print_message(msg, style="green", no_color=no_color)
- The helper functions (
Final Recommendations
- Address the critical issues related to input validation, error handling, and information disclosure.
- Implement the
--no-colorflag for backward compatibility. - Optimize the lazy import mechanism and reduce code duplication in the helper functions.
- Enhance test coverage to include color/style validation and fallback behavior.
- Update the documentation to reflect the new feature and its usage.
Once these issues are addressed, the PR will be ready for merging. Let me know if you need further clarification or assistance!
There was a problem hiding this comment.
🤖 AI Agent: code-reviewer
Review Summary
This pull request introduces a new feature to enhance the CLI output by adding colored messages using the rich library. It also includes helper functions for different message types (error, success, warn, policy_violation, passed_check) and updates the CLI commands (validate, test, diff) to use these functions. Additionally, it includes tests for the new functionality.
While the feature is a good addition for improving user experience, there are some areas that need attention to ensure security, maintainability, and compliance with best practices.
🔴 CRITICAL
-
Unvalidated User Input in CLI Commands
- The CLI commands (
validate,test,diff) directly use user-provided file paths without sanitization or validation. This could lead to potential security issues such as path traversal attacks or arbitrary file access. - Action: Validate and sanitize user inputs for file paths to ensure they do not contain malicious patterns or access restricted directories.
- The CLI commands (
-
Improper Error Handling
- The
_import_consoleand_import_rich_textfunctions catchImportErrorandModuleNotFoundErrorbut do not provide a robust fallback mechanism. Ifrichis not installed, the CLI will print a warning but continue execution, potentially leading to inconsistent behavior. - Action: Ensure that the CLI gracefully handles the absence of
richby either:- Enforcing
richas a required dependency (e.g., inpyproject.toml). - Providing a robust fallback mechanism for all cases where
richis unavailable.
- Enforcing
- The
-
Potential Information Disclosure
- The error messages in the CLI commands (e.g.,
cmd_validate,cmd_test,cmd_diff) expose raw exceptions (exc) to the user. This could reveal sensitive information about the system or application internals. - Action: Log detailed error messages internally (e.g., to a debug log) and display user-friendly error messages in the CLI.
- The error messages in the CLI commands (e.g.,
🟡 WARNING
-
Backward Compatibility
- The addition of colored output may break existing automation or scripts that rely on parsing the CLI output. While the
--no-colorflag is mentioned in the PR description, it has not been implemented. - Action: Implement the
--no-colorflag to allow users to disable colored output and maintain backward compatibility.
- The addition of colored output may break existing automation or scripts that rely on parsing the CLI output. While the
-
Dependency Addition
- Adding
richas a dependency increases the attack surface and maintenance burden. Whilerichis a widely used library, its inclusion should be carefully considered. - Action: Evaluate whether the benefits of using
richoutweigh the risks and maintenance costs. If possible, consider making it an optional dependency.
- Adding
💡 SUGGESTIONS
-
Thread Safety
- The
_import_consoleand_import_rich_textfunctions are not thread-safe. If multiple threads invoke these functions simultaneously, it could lead to race conditions. - Action: Use a thread-safe mechanism (e.g.,
threading.Lock) to ensure that the imports are performed safely.
- The
-
Test Coverage
- While the new helper functions are tested, the tests only verify the presence of specific substrings in the output. They do not verify the actual color codes or styles.
- Action: Enhance the tests to verify the presence of expected ANSI color codes in the output when
richis installed.
-
Code Duplication
- The helper functions (
error,success,warn,policy_violation,passed_check) contain duplicated logic for importingrichcomponents and handling fallbacks. - Action: Refactor the helper functions to reduce duplication. For example, create a single function that handles the common logic and accepts parameters for the message type and style.
- The helper functions (
-
Documentation
- The PR does not include updates to the documentation to reflect the new feature.
- Action: Update the CLI documentation to include information about the new colored output and the planned
--no-colorflag.
-
Code Style
- The
_import_consoleand_import_rich_textfunctions use inconsistent formatting (e.g., unnecessary blank lines, inconsistent use of comments). - Action: Clean up the formatting to improve readability and maintain consistency with the project's style guidelines.
- The
-
Error Message Consistency
- The error messages in the CLI commands use different formats (e.g., some include "ERROR:" while others do not).
- Action: Standardize the format of error messages across all commands for consistency.
-
Performance
- The
_import_consoleand_import_rich_textfunctions are called repeatedly in the helper functions, which could lead to unnecessary overhead. - Action: Cache the imported
richcomponents to avoid redundant imports.
- The
Suggested Changes to the Code
-
Sanitize User Input
from pathlib import Path def sanitize_path(path: str) -> Path: """Sanitize and validate a file path.""" resolved_path = Path(path).resolve() if not resolved_path.is_file(): raise ValueError(f"Invalid file path: {path}") return resolved_path
Use this function in CLI commands to validate file paths.
-
Refactor Helper Functions
from rich.console import Console from rich.text import Text _console = Console() def print_message(msg: str, style: str, use_stderr: bool = False, no_color: bool = False) -> None: """Print a styled message using rich, with a plain text fallback.""" console = Console(stderr=use_stderr, no_color=no_color) if console: console.print(Text(msg), style=style) else: output = sys.stderr if use_stderr else sys.stdout print(msg, file=output) def error(msg: str, no_color: bool = False) -> None: print_message(msg, "red", use_stderr=True, no_color=no_color) def success(msg: str, no_color: bool = False) -> None: print_message(msg, "green", no_color=no_color) def warn(msg: str, no_color: bool = False) -> None: print_message(msg, "yellow", no_color=no_color) def policy_violation(msg: str, no_color: bool = False) -> None: print_message(msg, "bold red", use_stderr=True, no_color=no_color) def passed_check(msg: str, no_color: bool = False) -> None: print_message(f"\u2714 {msg}", "green", no_color=no_color)
-
Improve Tests
def test_success_with_color(capsys): success("This is a success message", no_color=False) captured = capsys.readouterr() assert "\033[32m" in captured.out # Check for green color code assert "success message" in captured.out.lower()
Final Assessment
- The feature is a good addition to improve the user experience of the CLI.
- Address the critical security issues and backward compatibility concerns before merging.
- Implement the suggested improvements to enhance code quality and maintainability.
There was a problem hiding this comment.
🤖 AI Agent: code-reviewer
Review Summary
This pull request introduces a new feature to enhance the CLI output of the agent-governance package by adding colored terminal output using the rich library. The changes improve the user experience by making the output more readable and visually distinct. The PR also includes tests for the new functionality.
While the changes are generally well-implemented, there are a few areas that require attention, including potential security concerns, code improvements, and suggestions for better practices.
🔴 CRITICAL
-
Unvalidated User Input in CLI Commands:
- The CLI commands (
cmd_validate,cmd_test,cmd_diff) directly use user-provided file paths (args.path,args.policy, etc.) without validating them for potential directory traversal attacks or malicious inputs. - Recommendation: Use
os.path.abspath()to normalize file paths and validate them against a whitelist of allowed directories or patterns. Additionally, ensure that symbolic links are resolved to prevent bypassing restrictions.
- The CLI commands (
-
Error Message Disclosure:
- The error messages in the CLI commands (e.g.,
error(f"ERROR: failed to parse {path}: {exc}")) directly expose exception details to the user. This could potentially leak sensitive information about the system or application. - Recommendation: Log detailed error messages internally and display generic error messages to the user. For example:
error(f"ERROR: Failed to parse the file at {path}. Please check the file format.") logger.exception("Failed to parse file: %s", path)
- The error messages in the CLI commands (e.g.,
🟡 WARNING
- Backward Compatibility:
- The introduction of colored output changes the format of CLI output. While this is a non-breaking change for most use cases, it could potentially break scripts or tools that rely on parsing the CLI output (e.g., CI pipelines).
- Recommendation: Add a
--no-colorflag to allow users to disable colored output explicitly. This is already mentioned in the PR description but should be implemented in this PR to ensure backward compatibility.
💡 SUGGESTIONS
-
Lazy Imports:
- The
_import_consoleand_import_rich_textfunctions introduce unnecessary complexity by performing lazy imports. This approach can lead to subtle bugs and makes the code harder to read. - Recommendation: Perform the imports at the top of the file and handle the
ImportErrorexception there. This will simplify the code and make it easier to maintain.
- The
-
Default Behavior Without
rich:- If the
richlibrary is not installed, the CLI falls back to plain text output. However, the current implementation prints a warning message tostderrevery time a function is called. - Recommendation: Check for the presence of
richonce at the start of the program and set a global flag. Use this flag to determine whether to use colored output or plain text, without repeatedly printing warnings.
- If the
-
Test Coverage:
- While the new test file (
test_cli_output.py) covers the basic functionality of the colored output functions, it does not test the fallback behavior whenrichis not installed. - Recommendation: Add tests to verify that the CLI functions correctly fall back to plain text output when
richis unavailable.
- While the new test file (
-
Error Handling in
_import_consoleand_import_rich_text:- The
_import_consoleand_import_rich_textfunctions catchImportErrorbut do not provide meaningful feedback or logging. - Recommendation: Log the error using a logger instead of printing to
stderr.
- The
-
Use of
Textinrich:- The
Textclass fromrich.textis imported but not used effectively. For example,console.print(Text(msg), style="red")can be simplified toconsole.print(msg, style="red"). - Recommendation: Remove the
_import_rich_textfunction and directly useconsole.printwith thestyleargument.
- The
-
Dependency Management:
- The
richlibrary is added as a dependency inpyproject.toml. While this is acceptable, it introduces a new runtime dependency. - Recommendation: Consider making
richan optional dependency and provide a clear error message if it is not installed.
- The
-
Code Duplication:
- The colored output functions (
error,success,warn, etc.) have repetitive code for importingConsoleand handling the fallback behavior. - Recommendation: Refactor these functions to reduce duplication. For example:
def print_message(msg: str, style: str, use_stderr: bool = False, no_color: bool = False): console = _import_console(no_color, use_stderr) if console: console.print(msg, style=style) else: print(msg, file=sys.stderr if use_stderr else sys.stdout)
- The colored output functions (
Additional Notes
- Documentation: Update the CLI documentation to reflect the new colored output feature and the potential addition of a
--no-colorflag. - Logging: Consider integrating a logging framework (e.g.,
logging) for better error handling and debugging. - Performance: The repeated calls to
_import_consoleand_import_rich_textmay have a minor performance impact. Caching theConsoleinstance could improve efficiency.
Suggested Actions
- Address the critical security issues related to unvalidated user input and error message disclosure.
- Implement the
--no-colorflag to ensure backward compatibility. - Refactor the colored output functions to reduce duplication and improve maintainability.
- Add tests for fallback behavior when
richis not installed. - Update documentation to reflect the changes.
Once these issues are addressed, the PR will be ready for approval.
Head branch was pushed to by a user without write access
There was a problem hiding this comment.
🤖 AI Agent: code-reviewer
Review Summary
This PR introduces colored terminal output for the Agent-OS CLI using the rich library. It enhances user experience by providing visual cues for errors, warnings, successes, and policy violations. The implementation includes fallback mechanisms for environments where rich is unavailable and adds unit tests to ensure correctness.
While the feature is well-implemented and improves usability, there are a few areas that require attention, particularly regarding security, backward compatibility, and code quality.
🔴 CRITICAL
-
Unvalidated User Input in CLI Messages:
- The
error,success,warn,policy_violation, andpassed_checkfunctions directly interpolate user-provided strings into theTextobject without sanitization. This could lead to unintended behavior if malicious input is passed, especially when combined withrich's support for Markdown-like syntax. - Recommendation: Escape user-provided strings before passing them to
Text. Userich.text.Text.from_markupwithescape=Trueto prevent unintended formatting or injection attacks.
from rich.text import Text from rich.markup import escape def error(msg: str, no_color: bool = False) -> None: console = _import_console(no_color, use_stderr=True) if console: console.print(Text(escape(msg)), style="red") else: print(msg, file=sys.stderr)
- The
🟡 WARNING
-
Potential Breaking Change in CLI Output:
- The introduction of colored output changes the format of CLI output, which might break scripts or tools that parse the CLI output. For example, the addition of color codes or the green checkmark (
✔) inpassed_checkcould cause issues for downstream consumers. - Recommendation: Add a
--no-colorflag immediately to allow users to disable colored output. This will provide backward compatibility for users relying on plain-text output.
parser.add_argument("--no-color", action="store_true", help="Disable colored output")
- The introduction of colored output changes the format of CLI output, which might break scripts or tools that parse the CLI output. For example, the addition of color codes or the green checkmark (
-
Dependency Addition:
- Adding
richas a dependency increases the attack surface of the project. Whilerichis a widely used library, it is still an additional dependency that could introduce vulnerabilities. - Recommendation: Ensure that
richis pinned to a specific version inpyproject.tomlto avoid unexpected issues from future updates. For example:rich = ">=13.0.0,<14.0.0"
- Adding
💡 SUGGESTIONS
-
Lazy Import Optimization:
- The
_import_consoleand_import_rich_textfunctions are called multiple times in each helper function, which is inefficient. Consider caching the imported modules to avoid repeated imports. - Recommendation: Use a global variable or a class-based approach to store the
ConsoleandTextobjects after the first import.
from functools import lru_cache @lru_cache(maxsize=None) def _get_rich_console(no_color: bool = False, use_stderr: bool = False): try: from rich.console import Console return Console(stderr=use_stderr, no_color=no_color) except ImportError: return None @lru_cache(maxsize=None) def _get_rich_text(): try: from rich.text import Text return Text except ImportError: return None
- The
-
Test Coverage:
- While the new
test_cli_output.pyfile provides good coverage for the new functions, the tests do not verify the fallback behavior whenrichis unavailable. - Recommendation: Add tests that simulate the absence of
rich(e.g., by mockingImportError) to ensure the CLI gracefully falls back to plain text.
def test_error_fallback(monkeypatch, capsys): monkeypatch.setattr("agent_os.policies.cli._import_console", lambda *args, **kwargs: None) error("This is a fallback error message") captured = capsys.readouterr() assert "fallback error message" in captured.err
- While the new
-
Documentation Update:
- The PR does not include updates to the documentation to reflect the new colored output feature.
- Recommendation: Update the CLI documentation to describe the new output format and the planned
--no-colorflag.
-
Thread Safety:
- The
rich.console.Consoleobject is instantiated multiple times in the CLI functions. Whilerichis generally thread-safe, creating multipleConsoleinstances could lead to unexpected behavior in multi-threaded environments. - Recommendation: Use a single, shared
Consoleinstance for the entire CLI module.
_console = None def _get_console(no_color: bool = False, use_stderr: bool = False): global _console if _console is None: from rich.console import Console _console = Console(stderr=use_stderr, no_color=no_color) return _console
- The
-
Error Message Consistency:
- The error messages in the CLI functions sometimes include the prefix
ERROR:orFAIL:while others do not. This inconsistency could confuse users. - Recommendation: Standardize error message prefixes across all functions.
- The error messages in the CLI functions sometimes include the prefix
Final Assessment
- Security: 🔴 Address the unvalidated user input issue immediately.
- Backward Compatibility: 🟡 Add a
--no-colorflag to avoid breaking downstream consumers. - Code Quality: 💡 Optimize imports, improve test coverage, and standardize error messages.
Once the critical and warning issues are addressed, this PR will be a valuable addition to the project.
yacinemebarki
left a comment
There was a problem hiding this comment.
This PR fixes the colored terminal output so that it works on non-color terminals.
Changes include:
- Added --no-color flag
- Updated output functions in cli.py
- Updated tests in test_cli_output.py
- adding test_cli_output to test
Tested using pytest.
There was a problem hiding this comment.
🤖 AI Agent: code-reviewer
Review Summary
This PR introduces colored terminal output for the Agent-OS CLI using the rich library. It provides utility functions for consistent formatting of messages (e.g., errors, warnings, success messages) and integrates them into existing CLI commands (validate, test, diff). The PR also includes tests for the new functionality and updates existing tests to accommodate the changes. While the feature improves CLI usability, there are a few areas that require attention, particularly around error handling, backward compatibility, and test coverage.
🔴 CRITICAL Issues
-
Error Handling for Missing
richLibrary- The
_import_consoleand_import_rich_textfunctions print warnings tostderrifrichis not installed but do not raise exceptions or provide a fallback mechanism for the caller. - Impact: If
richis unavailable, the CLI will silently degrade to plain text output, which might not be the intended behavior in all cases. - Recommendation: Explicitly document this behavior and consider adding a flag to enforce an error if
richis not installed (e.g.,--require-color).
- The
-
Potential for Silent Failures in
_import_consoleand_import_rich_text- The
_import_consoleand_import_rich_textfunctions returnNoneifrichis not installed, which could lead to unexpected behavior if the caller does not handle this case properly. - Recommendation: Raise a custom exception if
richis not installed, or ensure that all callers handle theNonecase explicitly.
- The
🟡 WARNING Issues
-
Backward Compatibility
- The addition of color codes to the CLI output may break scripts or tools that parse the CLI output programmatically.
- Recommendation: Add a
--no-colorflag immediately to allow users to disable colored output. This ensures backward compatibility for users relying on plain text output.
-
Behavior Change in
capsysTests- The tests for CLI commands (
test_policy_cli.py) have been modified to check for output in bothstdoutandstderr. This is a breaking change for any external tools or scripts that rely on the previous behavior of all output being sent tostdout. - Recommendation: Clearly document this change in the release notes and consider providing a migration guide for users.
- The tests for CLI commands (
💡 Suggestions
-
Consolidate
_import_consoleand_import_rich_text- The
_import_consoleand_import_rich_textfunctions are very similar and could be combined into a single function that imports the requiredrichcomponents. - Example:
def _import_rich_component(component: str, no_color: bool = False, use_stderr: bool = False): try: if component == "console": from rich.console import Console return Console(stderr=use_stderr, no_color=no_color) elif component == "text": from rich.text import Text return Text except ImportError: print(f"WARNING: rich library not installed, using plain text output", file=sys.stderr) return None
- The
-
Test Coverage for
--no-colorFlag- While the
--no-colorflag is mentioned as a potential future feature, it is not implemented in this PR. Adding this flag now would improve usability and backward compatibility. - Recommendation: Implement the
--no-colorflag and add tests to verify its behavior.
- While the
-
Test Coverage for Fallback Behavior
- The tests do not verify the fallback behavior when
richis not installed. - Recommendation: Add tests that simulate the absence of
rich(e.g., by mockingModuleNotFoundError) and verify that the CLI falls back to plain text output.
- The tests do not verify the fallback behavior when
-
Use of
TextClass- The
Textclass fromrich.textis imported but not used effectively. For example,Text(msg)is passed toconsole.print()without any additional formatting. - Recommendation: Remove the
Textclass and directly pass strings toconsole.print()with the appropriatestyleargument.
- The
-
Error Message Consistency
- Some error messages include the prefix
ERROR:, while others do not (e.g.,policy_violationmessages). - Recommendation: Standardize error message prefixes for consistency.
- Some error messages include the prefix
-
Dependency Management
- The
richlibrary is added as a dependency inpyproject.toml, but its version is not pinned to a specific range. - Recommendation: Pin the
richversion to a specific range (e.g.,rich>=13.0.0,<14.0.0) to avoid unexpected breaking changes in future releases.
- The
Summary of Changes Needed
- Address the critical issues related to error handling and backward compatibility.
- Implement the
--no-colorflag for immediate backward compatibility. - Add tests for fallback behavior when
richis not installed. - Refactor redundant code and improve the use of the
Textclass. - Standardize error message formatting.
- Pin the
richdependency version inpyproject.toml.
Once these changes are made, the PR will be in a much better state for merging. Let me know if you need further clarification or assistance!
Description
Added colored output to the Python CLI for Agent-OS using
rich. Created functions for each message type:rich:error()– red text for errors (stderr)success()– green text for success messages (stdout)warn()– yellow text for warnings (stdout)policy_violation()– bold red for policy violations (stderr)passed_check()– green checkmark for passed checks (stdout)validate,test, anddifftest_cli_output.pyin the tests folder to verify the functionsrichis not installed, CLI falls back to plain text--no-colorcan be added in future to disable colorsType of Change
Package(s) Affected
Checklist
Related Issues