Skip to content

Conversation

@vinci-grape
Copy link
Collaborator

Change Summary

MS-Agent WebUI
image

Related issue number

Checklist

  • The pull request title is a good summary of the changes - it will be used in the changelog
  • Unit tests for the changes exist
  • Run pre-commit install and pre-commit run --all-files before git commit, and passed lint check.
  • Documentation reflects the changes where applicable

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @vinci-grape, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request adds a comprehensive web UI to the MS-Agent framework, significantly enhancing its usability and accessibility. The new UI provides a user-friendly way to manage projects, configure agents, monitor their execution, and view their output in real-time. This addition makes MS-Agent more approachable for users who prefer a graphical interface over command-line interactions.

Highlights

  • WebUI Introduction: This PR introduces a new web-based user interface for the MS-Agent framework, enabling users to interact with and monitor agents through a browser.
  • Backend Implementation: The backend is built using FastAPI and includes REST API endpoints for managing projects, sessions, and configurations, as well as WebSocket endpoints for real-time communication with the agents.
  • Agent Execution Management: The AgentRunner class manages the execution of MS-Agent processes, including building commands, setting up environment variables, and streaming output.
  • Configuration Management: The ConfigManager class handles global settings, LLM configuration, and MCP server configuration, allowing users to customize the behavior of the agents.
  • Frontend Implementation: The frontend is built using React and Material UI, providing a user-friendly interface for managing projects, sessions, and configurations, as well as viewing agent output and logs.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

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

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a comprehensive Web UI for MS-Agent, including a FastAPI backend and a React frontend. The overall structure is well-designed, with clear separation of concerns between frontend and backend components. The backend correctly uses asynchronous programming for handling long-running agent tasks and WebSockets for real-time communication. The frontend provides a polished and intuitive user experience. I've identified a few critical security and correctness issues that should be addressed, primarily related to insecure handling of secrets, potential path traversal, overly permissive CORS settings, and a missing dependency. I've also included some medium-severity suggestions to improve code quality and maintainability.

Comment on lines +161 to +168
cmd.extend(['--openai_api_key', llm_config['api_key']])

elif project_type == 'script':
# Run the script directly
cmd = [python, self.project['config_file']]
else:
cmd = [python, '-m', 'ms_agent', 'run', '--config', project_path]

Copy link
Contributor

Choose a reason for hiding this comment

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

high

Passing API keys as command-line arguments is a security risk, as they can be exposed to other users on the system through process lists (e.g., ps command). The application already correctly sets these keys as environment variables in _build_env. You should rely solely on environment variables for passing secrets and remove the logic that adds them as command-line arguments.

Comment on lines +292 to +297

return result

tree = build_tree(output_dir)
return {'tree': tree, 'output_dir': output_dir}

Copy link
Contributor

Choose a reason for hiding this comment

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

high

The security check to prevent path traversal is a good step, but it can be bypassed if the allowed directories contain symbolic links pointing outside. To mitigate this, you should resolve the real path of both the requested file and the allowed directories using os.path.realpath() before performing the check. This ensures you are comparing canonical, absolute paths without any symlinks.

Suggested change
return result
tree = build_tree(output_dir)
return {'tree': tree, 'output_dir': output_dir}
# Security check: ensure file is within allowed directories
allowed_dirs_real = [os.path.realpath(output_dir), os.path.realpath(projects_dir)]
real_path = os.path.realpath(full_path)
is_allowed = any(real_path.startswith(d) for d in allowed_dirs_real)
if not is_allowed:
raise HTTPException(status_code=403, detail="Access denied: file outside allowed directories")

Comment on lines +29 to +35
app.add_middleware(
CORSMiddleware,
allow_origins=['*'],
allow_credentials=True,
allow_methods=['*'],
allow_headers=['*'],
)
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The CORS configuration allow_origins=["*"] is too permissive for a production environment, as it allows any website to make requests to your backend. This can lead to security vulnerabilities. You should restrict the allowed origins to the specific URL of your frontend application.

Suggested change
app.add_middleware(
CORSMiddleware,
allow_origins=['*'],
allow_credentials=True,
allow_methods=['*'],
allow_headers=['*'],
)
app.add_middleware(
CORSMiddleware,
# In production, you should restrict this to your frontend's domain.
# For development, you can use a list of allowed origins.
allow_origins=["http://localhost:5173", "http://127.0.0.1:5173"], # Example for dev
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)

def get_project_config(self, project_id: str) -> Optional[Dict[str, Any]]:
"""Get the configuration for a project"""
project = self.get_project(project_id)
if not project:
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The PyYAML library is used here but is imported locally and is missing from webui/requirements.txt. This will cause a runtime error. Please add PyYAML to requirements.txt and move this import statement to the top of the file for better code organization and to make dependencies clear.


elif project_type == 'script':
# script类型:直接运行Python脚本
cmd = [python, self.project['config_file']] # run.py
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The code snippet for _build_command uses a python variable that is not defined within the snippet. While it's defined in the actual source code, for documentation clarity, it would be better to use a literal string like 'python' to make the example self-contained and easier to understand.

Suggested change
cmd = [python, self.project['config_file']] # run.py
cmd = ['python', self.project['config_file']] # run.py

const [input, setInput] = useState('');
const [outputFilesOpen, setOutputFilesOpen] = useState(false);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const [outputTree, setOutputTree] = useState<any>({folders: {}, files: []});
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Using any for the outputTree state weakens TypeScript's type safety. You should define a specific interface for the file tree structure to improve maintainability and prevent potential runtime errors.

For example:

interface FileNode {
  name: string;
  path: string;
  size: number;
  modified: number;
}

interface FolderNode {
  folders: Record<string, FolderNode>;
  files: FileNode[];
}

const [outputTree, setOutputTree] = useState<FolderNode>({folders: {}, files: []});

if [ ! -d "$SCRIPT_DIR/frontend/node_modules" ]; then
echo -e "${YELLOW}Installing frontend dependencies...${NC}"
cd "$SCRIPT_DIR/frontend"
npm install
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

For faster and more deterministic dependency installation, especially in CI/CD environments, it's recommended to use npm ci instead of npm install. npm ci performs a clean install based on the package-lock.json file, which ensures that the exact same dependency versions are used every time.

Suggested change
npm install
npm ci

@tastelikefeet tastelikefeet merged commit 3134af3 into main Jan 18, 2026
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants