Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughAdds three standalone MCP servers (media, quality, workflow) with package initializer, tests, FRAMEWORK_MCPS updates, a dependency upper bound, a version bump to 0.1.65, and documentation/release notes updates. Changes
Sequence Diagram(s)sequenceDiagram
participant Client as Client
participant MCP as FastMCP Server (massgen_media_tools)
participant Impl as massgen.media implementation
participant FS as Filesystem/Storage
rect rgba(0,128,0,0.5)
Client->>MCP: call generate_media(params)
end
rect rgba(0,0,255,0.5)
MCP->>MCP: sanitize params, build kwargs from non-None
MCP->>Impl: lazy-import & invoke media generate API (kwargs)
end
alt success
Impl->>FS: persist outputs (if applicable)
Impl->>MCP: return generation result (data / URLs)
MCP->>Client: return JSON result
else failure
Impl->>MCP: raises Exception / ImportError
MCP->>Client: return JSON-formatted error payload
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 3 | ❌ 3❌ Failed checks (3 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@CHANGELOG.md`:
- Line 46: Revert the edit to the existing "0.1.64" section so it remains
exactly as in history (do not change the line that currently reads
"**Contributors**: `@praneeth999`, `@ncrispino`, `@HenryQi`, `@db-ol` and the MassGen
team"); instead add a new top-level release section heading "## [0.1.65] -
2026-03-16" and beneath it add the required subsections (e.g., Added, Changed,
Fixed, Documentation/Configurations/Resources, Technical Details) with PR/issue
refs and file paths relevant to this release; ensure the new section follows the
same formatting style as other release entries in CHANGELOG.md and does not
alter any previous release text.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 722611fc-0bd9-4533-a0c0-d94a0d423718
📒 Files selected for processing (3)
CHANGELOG.mdROADMAP_v0.1.66.mdmassgen/__init__.py
Standalone entry points in massgen/mcp_tools/standalone/ that work without an orchestrator, for use with the massgen-refinery Claude Code plugin: - quality_server: init_session, generate_eval_criteria (storage), submit_checklist (verdict logic), propose_improvements (coverage validation), reset_evaluation. Per-session state in .massgen-quality/ - workflow_server: new_answer (snapshots deliverables per round), vote (stateless passthrough) - media_server: generate_media (image/video/audio with full param surface), read_media (critical-first analysis, multi-file comparison, continue_from for follow-ups) 31 tests covering all tools. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
feat: Add standalone MCP servers for general use, esp for massgen-refinery plugin
There was a problem hiding this comment.
Actionable comments posted: 6
🧹 Nitpick comments (2)
massgen/mcp_tools/standalone/media_server.py (1)
96-102: Don't override optional defaults with empty placeholders.Lines 96-102 and 208-215 always send
multimodal_config={}andtask_context="", even though the wrappers say they only forward non-Nonevalues. The wrapped helpers default those arguments toNone, so this can change fallback/config-loading behavior for the standalone server.♻️ Suggested cleanup
kwargs: dict[str, Any] = { "mode": mode, "agent_cwd": str(cwd), "allowed_paths": [str(cwd)], - "multimodal_config": {}, - "task_context": "", } @@ kwargs: dict[str, Any] = { "inputs": inputs, "max_concurrent": max_concurrent, "agent_cwd": str(cwd), "allowed_paths": [str(cwd)], - "multimodal_config": {}, - "task_context": "", }Also applies to: 208-215
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@massgen/mcp_tools/standalone/media_server.py` around lines 96 - 102, The kwargs construction in media_server.py unconditionally sets "multimodal_config" and "task_context" to empty placeholders, overriding helper defaults; update both places where kwargs is built (the blocks that include "mode", "agent_cwd", "allowed_paths" — lines around the existing kwargs and the second occurrence around lines 208-215) so that you only add the "multimodal_config" and "task_context" keys when their values are not None (i.e., check the local variables before inserting into kwargs), leaving them absent so the wrapped helpers can use their own None-based defaults.massgen/mcp_tools/standalone/__init__.py (1)
1-5: Add Google-style docstrings to the new MCP entrypoints.The new public tools in
massgen.mcp_tools.standalonecurrently rely on decorator descriptions alone. Please add Google-style docstrings to the new MCP entrypoints before release.As per coding guidelines,
**/*.py: For new or changed functions, include Google-style docstrings.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@massgen/mcp_tools/standalone/__init__.py` around lines 1 - 5, The new standalone MCP entrypoints in massgen.mcp_tools.standalone lack Google-style docstrings; update the public functions/classes exported from massgen.mcp_tools.standalone (start in the module __init__.py and any entrypoint functions/classes it exposes) to include Google-style docstrings that describe purpose, parameters (Args), return values (Returns), and possible exceptions (Raises) and an optional Example; ensure each top-level public symbol (functions, classes, and methods intended as MCP entrypoints) has a clear docstring following the Google style guide before merging.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@massgen/mcp_tools/standalone/__init__.py`:
- Around line 1-5: Add the three standalone MCP server names to the
FRAMEWORK_MCPS frozenset so they remain registered as direct protocol tools when
enable_code_based_tools is enabled; update the FRAMEWORK_MCPS definition in
massgen/filesystem_manager/_constants.py to include "massgen_quality_tools",
"massgen_workflow_tools", and "massgen_media_tools" (reference symbol:
FRAMEWORK_MCPS) ensuring the frozenset literal contains these exact string
identifiers so they are not wrapped as filesystem execution tools.
In `@massgen/mcp_tools/standalone/quality_server.py`:
- Around line 40-56: The session_id read in _get_session_dir (from
session_metadata.json) must be sanitized and validated before being used as a
filesystem path: generate a safe slug for session_id (allow only alphanumerics,
hyphen, underscore; drop/replace other chars and forbid empty or "."/".."),
import re for the slug logic, then resolve session_dir = (quality_root /
"sessions" / safe_slug).resolve() and ensure session_dir is a descendant of
(quality_root / "sessions").resolve() — if validation fails, fall back to
"default"; apply the same slugging + resolve-and-validate logic for any code
that appends raw labels to session IDs (e.g., where label is appended in
workflow_server.py) so no input can escape the .massgen-quality/sessions root.
- Around line 29-30: DEFAULT_CUTOFF is set to 70 but submit_checklist and its
tool description use a 1-10 score scale, causing a mismatch; change
DEFAULT_CUTOFF from 70 to 7 to match the 1-10 scale and update any user-facing
text in submit_checklist (and nearby guidance strings) to clearly state scores
are 1-10, or alternatively, if you intend a 0-100 scale, update submit_checklist
docs to accept 0-100 and keep DEFAULT_CUTOFF at 70; ensure consistency between
the DEFAULT_CUTOFF constant, DEFAULT_REQUIRED_RATIO, and the submit_checklist
description so callers and agents use the same score scale.
In `@massgen/mcp_tools/standalone/workflow_server.py`:
- Around line 92-106: The current loop accepts absolute paths and ../ segments
and copies them into snapshot_dir, allowing path traversal/data exfiltration;
change it to resolve each candidate (use src.resolve(strict=False) or
Path.resolve()) and reject any path that is not inside the intended workspace
root (compare against workspace_root.resolve() or Path.cwd().resolve() with
pathlib.Path.is_relative_to or equivalent) before performing
shutil.copytree/copy2. Specifically, in the block iterating over paths (variable
names: paths, src, snapshot_dir, copied) validate src_resolved =
src.resolve(strict=False) and only proceed if
src_resolved.is_relative_to(workspace_root_resolved) (or check that
workspace_root_resolved in src_resolved.parents or equal); otherwise log a
warning and skip copying to prevent absolute/../ escapes. Ensure directories and
files are still copied with shutil.copytree/shutil.copy2 after the validation.
In `@massgen/tests/test_standalone_mcp_servers.py`:
- Around line 135-449: The async tool-flow tests
(test_init_session_creates_timestamped_dir through test_vote) are
integration-style and should be marked with `@pytest.mark.integration`; update
each test function in that block (e.g.,
test_init_session_creates_timestamped_dir, test_init_session_without_label,
test_init_session_then_tools_use_it, test_generate_eval_criteria, ...,
test_vote) to add `@pytest.mark.integration` above the function (next to
`@pytest.mark.asyncio` where present), ensure pytest is imported, and optionally
move the file into the integration test folder; also add other opt-in markers
(e.g., `@pytest.mark.live_api`, `@pytest.mark.expensive`, `@pytest.mark.docker`) where
relevant per guidelines.
---
Nitpick comments:
In `@massgen/mcp_tools/standalone/__init__.py`:
- Around line 1-5: The new standalone MCP entrypoints in
massgen.mcp_tools.standalone lack Google-style docstrings; update the public
functions/classes exported from massgen.mcp_tools.standalone (start in the
module __init__.py and any entrypoint functions/classes it exposes) to include
Google-style docstrings that describe purpose, parameters (Args), return values
(Returns), and possible exceptions (Raises) and an optional Example; ensure each
top-level public symbol (functions, classes, and methods intended as MCP
entrypoints) has a clear docstring following the Google style guide before
merging.
In `@massgen/mcp_tools/standalone/media_server.py`:
- Around line 96-102: The kwargs construction in media_server.py unconditionally
sets "multimodal_config" and "task_context" to empty placeholders, overriding
helper defaults; update both places where kwargs is built (the blocks that
include "mode", "agent_cwd", "allowed_paths" — lines around the existing kwargs
and the second occurrence around lines 208-215) so that you only add the
"multimodal_config" and "task_context" keys when their values are not None
(i.e., check the local variables before inserting into kwargs), leaving them
absent so the wrapped helpers can use their own None-based defaults.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: ec8a0435-44e6-4fe2-8170-5a66f4e1bd94
📒 Files selected for processing (6)
massgen/mcp_tools/standalone/__init__.pymassgen/mcp_tools/standalone/media_server.pymassgen/mcp_tools/standalone/quality_server.pymassgen/mcp_tools/standalone/workflow_server.pymassgen/tests/test_standalone_mcp_servers.pypyproject.toml
docs: docs for v0.1.65
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@docs/source/index.rst`:
- Around line 203-206: Update the v0.1.65 "MassGen Refinery Plugin" release note
to include direct links to the three standalone server implementations
referenced: the quality server, the workflow server, and the media server; edit
the "MassGen Refinery Plugin" paragraph (v0.1.65 entry) to add reStructuredText
links or reference directives pointing to each server's implementation page or
repo (e.g., "quality server", "workflow server", "media server") so readers can
click through to their respective docs/implementations, and ensure the linked
labels match the actual target document IDs or URLs used elsewhere in the docs.
In `@README_PYPI.md`:
- Around line 161-165: The release notes under "What's New in v0.1.65" currently
list MassGen Refinery Plugin and then provide bullets for Quality Server and
Workflow Server but omit a corresponding Media Server bullet; add a third bullet
matching style and tone (e.g., "- **🎞️ Media Server** - Handles media
processing, storage and snapshot generation for deliverables, integrating with
the MassGen checklist workflow.") directly alongside the Quality and Workflow
bullets so all three MCP servers (quality, workflow, media) are documented
consistently under the "What's New in v0.1.65" section.
In `@ROADMAP.md`:
- Line 7: The "Last Updated" date at the top (the line containing "**Last
Updated:** March 18, 2026") conflicts with the footer date (March 11, 2026);
update whichever is incorrect so both show the same authoritative date (either
change the top "**Last Updated:**" line or modify the footer date text) and
ensure the phrase "**Last Updated:**" is used consistently in both places to
avoid duplicate/conflicting dates.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 3ef9412e-20f6-4ac8-93e2-0d9030ce8178
📒 Files selected for processing (13)
CHANGELOG.mdCONTRIBUTING.mdREADME.mdREADME_PYPI.mdROADMAP.mdROADMAP_v0.1.66.mddocs/announcements/archive/v0.1.64.mddocs/announcements/current-release.mddocs/announcements/feature-highlights.mddocs/announcements/github-release-v0.1.64.mddocs/announcements/github-release-v0.1.65.mddocs/source/index.rstmassgen/configs/README.md
💤 Files with no reviewable changes (1)
- docs/announcements/github-release-v0.1.64.md
✅ Files skipped from review due to trivial changes (4)
- docs/announcements/github-release-v0.1.65.md
- README.md
- CONTRIBUTING.md
- docs/announcements/archive/v0.1.64.md
🚧 Files skipped from review as they are similar to previous changes (1)
- CHANGELOG.md
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
massgen/mcp_tools/standalone/workflow_server.py (1)
64-75:⚠️ Potential issue | 🟠 MajorPersist the reserved round number before creating
round_*directories.
_get_round_number()computesround + 1but does not persist it, so repeatednew_answercalls in one session can reuse the same round directory and overwrite prior artifacts.💡 Suggested fix
-def _get_round_number(session_dir: Path) -> int: - """Read the current round from state.json, or default to 1.""" +def _reserve_round_number(session_dir: Path) -> int: + """Read, increment, and persist the round number in state.json.""" state_path = session_dir / "state.json" - if state_path.exists(): - try: - with open(state_path) as f: - state = json.load(f) - return state.get("round", 0) + 1 - except (json.JSONDecodeError, OSError): - pass - return 1 + state: dict[str, Any] = {"checklist_history": [], "last_result": None, "round": 0} + if state_path.exists(): + try: + with open(state_path) as f: + loaded = json.load(f) + if isinstance(loaded, dict): + state.update(loaded) + except (json.JSONDecodeError, OSError): + pass + next_round = int(state.get("round", 0)) + 1 + state["round"] = next_round + with open(state_path, "w") as f: + json.dump(state, f, indent=2) + return next_round @@ - round_num = _get_round_number(session_dir) + round_num = _reserve_round_number(session_dir)Also applies to: 89-94
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@massgen/mcp_tools/standalone/workflow_server.py` around lines 64 - 75, _get_round_number() only returns the next round number but doesn't persist it, allowing concurrent/repeated new_answer calls to reuse the same round directory; modify _get_round_number to compute next_round = state.get("round", 0) + 1, then immediately write the updated {"round": next_round} back to state.json (preferably via an atomic write: write to a temp file then os.replace) before returning next_round, and handle JSON/file errors gracefully; also apply the same persistence change wherever the code reserves a round (e.g., the new_answer flow that creates round_* directories) so the reserved round is stored prior to directory creation.
🧹 Nitpick comments (3)
massgen/mcp_tools/standalone/workflow_server.py (1)
183-196: Add Google-style docstrings to MCP tool entrypoints.
new_answerandvoteare new/changed functions and should carry Google-style docstrings for consistency with repo standards.As per coding guidelines, "
**/*.py: For new or changed functions, include Google-style docstrings".🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@massgen/mcp_tools/standalone/workflow_server.py` around lines 183 - 196, Add Google-style docstrings to the MCP tool entrypoints: insert a docstring for new_answer describing its purpose (create a new answer), parameters (answer: str, file_paths: list[str] | None) and return value (str), and a docstring for vote describing its purpose (cast a vote to accept the current best answer), parameters (choice: str, reasoning: str = "") and return value (str); place the docstrings immediately below the async def new_answer(...) and async def vote(...) signatures, following the project's Google-style format for short summary, Args, and Returns.massgen/tests/test_standalone_mcp_servers.py (1)
430-479: Add a regression test for repeatednew_answercalls in the same session.Right now the suite validates a single snapshot round, but not that a second submission gets a new round directory (
round_002) instead of reusinground_001. Adding that check will catch round-counter regressions early.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@massgen/tests/test_standalone_mcp_servers.py` around lines 430 - 479, Add a regression test that calls _init_session_impl once, then invokes _new_answer_impl twice (using the same session) and asserts the second response has round == 2 and its round_dir path name ends with or contains "round_002" (or otherwise differs from the first round_dir); use the existing test structure and helpers (_init_session_impl and _new_answer_impl) and reuse the deliverable file setup from test_new_answer_snapshots_deliverables to create files for the first submission and optionally none for the second, then assert both submission.json files exist in their respective round directories and that the two round_dir values are distinct.massgen/mcp_tools/standalone/quality_server.py (1)
458-511: Add Google-style docstrings to exported MCP tool functions.The public tool functions are new/changed and should include docstrings (
Args/Returns) to match repository standards.As per coding guidelines, "
**/*.py: For new or changed functions, include Google-style docstrings".🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@massgen/mcp_tools/standalone/quality_server.py` around lines 458 - 511, Add Google-style docstrings to each exported MCP tool function (init_session, generate_eval_criteria, submit_checklist, propose_improvements, reset_evaluation): for each function include a short description, an Args section describing parameter names and types (e.g., label: str, criteria: list[dict[str, str]], scores: dict[str, Any], report_path: str = "", improvements: dict[str, Any], preserve: dict[str, Any] | None), and a Returns section describing the returned str and any notable behavior; ensure docstrings follow the repository's Google-style format and are placed immediately below each async def declaration for the listed functions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@massgen/mcp_tools/standalone/quality_server.py`:
- Around line 101-107: The _extract_score function can raise when dict entries
contain non-numeric or None scores; update _extract_score to safely handle
strings and None by validating the obtained value before calling int(): get
value = entry.get("score"), if value is instance of (int, float) return
int(value), if value is str attempt to parse with a guarded try/except to int()
and fall back to 0 on ValueError, and for any other type (including None) return
0; ensure the same safe logic is applied for top-level numeric checks
(isinstance(entry, (int, float))) so no conversion ever raises inside
_extract_score.
In `@massgen/mcp_tools/standalone/workflow_server.py`:
- Around line 113-119: The current snapshot code uses src_resolved.name for dest
which can cause basename collisions; change the destination logic in the block
that sets dest (near variables snapshot_dir, src_resolved, dest, copied) to
preserve the source's relative path or otherwise guarantee uniqueness (for
example compute a relative path from a common base/root and use snapshot_dir /
relative_path, or fallback to a unique filename suffix/hash/UUID when the
relative path cannot be determined) before calling shutil.copytree or
shutil.copy2; ensure the updated dest is created with parents as needed and
append the final string path to copied.
---
Duplicate comments:
In `@massgen/mcp_tools/standalone/workflow_server.py`:
- Around line 64-75: _get_round_number() only returns the next round number but
doesn't persist it, allowing concurrent/repeated new_answer calls to reuse the
same round directory; modify _get_round_number to compute next_round =
state.get("round", 0) + 1, then immediately write the updated {"round":
next_round} back to state.json (preferably via an atomic write: write to a temp
file then os.replace) before returning next_round, and handle JSON/file errors
gracefully; also apply the same persistence change wherever the code reserves a
round (e.g., the new_answer flow that creates round_* directories) so the
reserved round is stored prior to directory creation.
---
Nitpick comments:
In `@massgen/mcp_tools/standalone/quality_server.py`:
- Around line 458-511: Add Google-style docstrings to each exported MCP tool
function (init_session, generate_eval_criteria, submit_checklist,
propose_improvements, reset_evaluation): for each function include a short
description, an Args section describing parameter names and types (e.g., label:
str, criteria: list[dict[str, str]], scores: dict[str, Any], report_path: str =
"", improvements: dict[str, Any], preserve: dict[str, Any] | None), and a
Returns section describing the returned str and any notable behavior; ensure
docstrings follow the repository's Google-style format and are placed
immediately below each async def declaration for the listed functions.
In `@massgen/mcp_tools/standalone/workflow_server.py`:
- Around line 183-196: Add Google-style docstrings to the MCP tool entrypoints:
insert a docstring for new_answer describing its purpose (create a new answer),
parameters (answer: str, file_paths: list[str] | None) and return value (str),
and a docstring for vote describing its purpose (cast a vote to accept the
current best answer), parameters (choice: str, reasoning: str = "") and return
value (str); place the docstrings immediately below the async def
new_answer(...) and async def vote(...) signatures, following the project's
Google-style format for short summary, Args, and Returns.
In `@massgen/tests/test_standalone_mcp_servers.py`:
- Around line 430-479: Add a regression test that calls _init_session_impl once,
then invokes _new_answer_impl twice (using the same session) and asserts the
second response has round == 2 and its round_dir path name ends with or contains
"round_002" (or otherwise differs from the first round_dir); use the existing
test structure and helpers (_init_session_impl and _new_answer_impl) and reuse
the deliverable file setup from test_new_answer_snapshots_deliverables to create
files for the first submission and optionally none for the second, then assert
both submission.json files exist in their respective round directories and that
the two round_dir values are distinct.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 15814977-876c-40ae-bf2b-51b27e1bae0b
📒 Files selected for processing (5)
massgen/filesystem_manager/_constants.pymassgen/mcp_tools/standalone/media_server.pymassgen/mcp_tools/standalone/quality_server.pymassgen/mcp_tools/standalone/workflow_server.pymassgen/tests/test_standalone_mcp_servers.py
🚧 Files skipped from review as they are similar to previous changes (1)
- massgen/mcp_tools/standalone/media_server.py
PR Title Format
Your PR title must follow the format:
<type>: <brief description>Valid types:
fix:- Bug fixesfeat:- New featuresbreaking:- Breaking changesdocs:- Documentation updatesrefactor:- Code refactoringtest:- Test additions/modificationschore:- Maintenance tasksperf:- Performance improvementsstyle:- Code style changesci:- CI/CD configuration changesExamples:
fix: resolve memory leak in data processingfeat: add export to CSV functionalitybreaking: change API response formatdocs: update installation guideDescription
Brief description of the changes in this PR
Type of change
fix:) - Non-breaking change which fixes an issuefeat:) - Non-breaking change which adds functionalitybreaking:) - Fix or feature that would cause existing functionality to not work as expecteddocs:) - Documentation updatesrefactor:) - Code changes that neither fix a bug nor add a featuretest:) - Adding missing tests or correcting existing testschore:) - Maintenance tasks, dependency updates, etc.perf:) - Code changes that improve performancestyle:) - Changes that do not affect the meaning of the code (formatting, missing semi-colons, etc.)ci:) - Changes to CI/CD configuration files and scriptsChecklist
Pre-commit status
How to Test
Add test method for this PR.
Test CLI Command
Write down the test bash command. If there is pre-requests, please emphasize.
Expected Results
Description/screenshots of expected results.
Additional context
Add any other context about the PR here.
Summary by CodeRabbit
New Features
Tests
Chores
Documentation