-
Notifications
You must be signed in to change notification settings - Fork 442
feat: add simple webui #827
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,176 @@ | ||
| # MS-Agent WebUI Backend - 开发者指南 | ||
|
|
||
| ## 概述 | ||
|
|
||
| MS-Agent WebUI后端负责管理前端与ms-agent框架之间的通信,通过WebSocket实现实时交互,支持多种项目类型的运行和监控。 | ||
|
|
||
| ## 架构设计 | ||
|
|
||
| ### 核心组件 | ||
|
|
||
| ``` | ||
| ┌─────────────┐ WebSocket ┌──────────────────┐ | ||
| │ Frontend │ ◄────────────────────────► │ WebSocket Handler│ | ||
| └─────────────┘ └────────┬─────────┘ | ||
| │ | ||
| │ | ||
| ▼ | ||
| ┌──────────────────┐ ┌──────────────────────┐ | ||
| │Project Discovery │ │ Agent Runner │ | ||
| └──────────────────┘ └──────────┬───────────┘ | ||
| │ | ||
| ▼ | ||
| ┌──────────────────┐ ┌──────────────────────┐ | ||
| │ Session Manager │ │ ms-agent Process │ | ||
| └──────────────────┘ └──────────────────────┘ | ||
| ``` | ||
|
|
||
| ### 文件职责 | ||
|
|
||
| | 文件 | 职责 | | ||
| |------|--------| | ||
| | `main.py` | FastAPI应用入口,路由配置 | | ||
| | `api.py` | REST API端点定义 | | ||
| | `websocket_handler.py` | WebSocket连接管理和消息处理 | | ||
| | `agent_runner.py` | ms-agent进程管理和输出解析 | | ||
| | `project_discovery.py` | 项目发现和类型识别 | | ||
| | `session_manager.py` | 会话状态管理 | | ||
| | `config_manager.py` | 配置文件管理 | | ||
| | `shared.py` | 共享实例初始化 | | ||
|
|
||
| ## 请求处理流程 | ||
|
|
||
| ### 1. 项目发现阶段 | ||
|
|
||
| **文件**: `project_discovery.py` | ||
|
|
||
| 系统启动时扫描项目目录,根据配置文件识别项目类型: | ||
|
|
||
| ```python | ||
| def _analyze_project(self, name: str, path: str): | ||
| # 检查配置文件确定项目类型 | ||
| workflow_file = os.path.join(path, 'workflow.yaml') | ||
| agent_file = os.path.join(path, 'agent.yaml') | ||
| run_file = os.path.join(path, 'run.py') | ||
|
|
||
| if os.path.exists(workflow_file): | ||
| project_type = 'workflow' # 工作流项目 | ||
| config_file = workflow_file | ||
| elif os.path.exists(agent_file): | ||
| project_type = 'agent' # 代理项目 | ||
| config_file = agent_file | ||
| elif os.path.exists(run_file): | ||
| project_type = 'script' # 脚本项目 | ||
| config_file = run_file | ||
| ``` | ||
|
|
||
| **项目类型说明**: | ||
| - **workflow**: 使用`workflow.yaml`配置,通过ms-agent CLI运行 | ||
| - **agent**: 使用`agent.yaml`配置,通过ms-agent CLI运行 | ||
| - **script**: 使用`run.py`脚本,直接Python执行 | ||
|
|
||
| ### 2. WebSocket连接阶段 | ||
|
|
||
| **文件**: `websocket_handler.py` | ||
|
|
||
| 前端通过WebSocket连接到后端: | ||
|
|
||
| ```python | ||
| @router.websocket("/session/{session_id}") | ||
| async def websocket_session(websocket: WebSocket, session_id: str): | ||
| await connection_manager.connect(websocket, session_id) | ||
|
|
||
| try: | ||
| while True: | ||
| data = await websocket.receive_json() | ||
| await handle_session_message(session_id, data, websocket) | ||
| except WebSocketDisconnect: | ||
| connection_manager.disconnect(websocket, session_id) | ||
| ``` | ||
|
|
||
| **支持的消息类型**: | ||
| - `start`: 启动代理 | ||
| - `stop`: 停止代理 | ||
| - `send_input`: 向运行中的代理发送输入 | ||
| - `get_status`: 获取当前状态 | ||
|
|
||
| ### 3. 代理启动阶段 | ||
|
|
||
| **文件**: `websocket_handler.py` | ||
|
|
||
| 处理启动请求,创建AgentRunner实例: | ||
|
|
||
| ```python | ||
| async def start_agent(session_id: str, data: Dict[str, Any], websocket: WebSocket): | ||
| # 1. 获取会话信息 | ||
| session = session_manager.get_session(session_id) | ||
|
|
||
| # 2. 获取项目信息 | ||
| project = project_discovery.get_project(session['project_id']) | ||
|
|
||
| # 3. 创建AgentRunner | ||
| runner = AgentRunner( | ||
| session_id=session_id, | ||
| project=project, # 包含项目类型和配置文件路径 | ||
| config_manager=config_manager, | ||
| on_output=lambda msg: asyncio.create_task(on_agent_output(session_id, msg)), | ||
| on_log=lambda log: asyncio.create_task(on_agent_log(session_id, log)), | ||
| on_progress=lambda prog: asyncio.create_task(on_agent_progress(session_id, prog)), | ||
| on_complete=lambda result: asyncio.create_task(on_agent_complete(session_id, result)), | ||
| on_error=lambda err: asyncio.create_task(on_agent_error(session_id, err)) | ||
| ) | ||
|
|
||
| # 4. 启动代理 | ||
| task = asyncio.create_task(runner.start(data.get('query', ''))) | ||
| ``` | ||
|
|
||
| ### 4. 命令构建阶段 | ||
|
|
||
| **文件**: `agent_runner.py` | ||
|
|
||
| 根据项目类型构建对应的ms-agent命令: | ||
|
|
||
| ```python | ||
| def _build_command(self, query: str) -> list: | ||
| project_type = self.project.get('type') | ||
| config_file = self.project.get('config_file', '') | ||
|
|
||
| if project_type == 'workflow' or project_type == 'agent': | ||
| # workflow/agent类型:使用ms-agent CLI | ||
| cmd = [ | ||
| 'ms-agent', 'run', | ||
| '--config', config_file, # workflow.yaml 或 agent.yaml | ||
| '--trust_remote_code', 'true' | ||
| ] | ||
|
|
||
| if query: | ||
| cmd.extend(['--query', query]) | ||
|
|
||
| # 添加MCP服务器配置 | ||
| mcp_file = self.config_manager.get_mcp_file_path() | ||
| if os.path.exists(mcp_file): | ||
| cmd.extend(['--mcp_server_file', mcp_file]) | ||
|
|
||
| # 添加LLM配置 | ||
| llm_config = self.config_manager.get_llm_config() | ||
| if llm_config.get('api_key'): | ||
| provider = llm_config.get('provider', 'modelscope') | ||
| if provider == 'modelscope': | ||
| cmd.extend(['--modelscope_api_key', llm_config['api_key']]) | ||
| elif provider == 'openai': | ||
| cmd.extend(['--openai_api_key', llm_config['api_key']]) | ||
|
|
||
| elif project_type == 'script': | ||
| # script类型:直接运行Python脚本 | ||
| cmd = [python, self.project['config_file']] # run.py | ||
|
|
||
| return cmd | ||
| ``` | ||
|
|
||
| ## 不同项目类型的命令对应 | ||
|
|
||
| | 项目类型 | 配置文件 | ms-agent命令 | | ||
| |---------|----------|--------------| | ||
| | **workflow** | `workflow.yaml` | `ms-agent run --config workflow.yaml --trust_remote_code true --query "xxx" --mcp_server_file xxx.json --modelscope_api_key xxx` | | ||
| | **agent** | `agent.yaml` | `ms-agent run --config agent.yaml --trust_remote_code true --query "xxx" --mcp_server_file xxx.json --modelscope_api_key xxx` | | ||
| | **script** | `run.py` | `python run.py` | | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code snippet for
_build_commanduses apythonvariable 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.