mirror of
https://github.com/Minidoracat/mcp-feedback-enhanced.git
synced 2025-07-27 10:42:25 +08:00
849 lines
26 KiB
Markdown
849 lines
26 KiB
Markdown
# 交互流程文檔
|
||
|
||
## 🔄 AI 助手與 MCP 服務完整交互流程
|
||
|
||
本文檔詳細描述 AI 助手調用 MCP Feedback Enhanced 服務的完整流程,包括首次調用、多次循環調用、錯誤處理和性能優化機制。
|
||
|
||
### 核心設計理念
|
||
|
||
- **持久化會話**: 支援 AI 助手多次循環調用,無需重複建立連接
|
||
- **智能環境適配**: 自動檢測並適配本地、SSH Remote、WSL 環境
|
||
- **無縫狀態切換**: 會話更新時前端局部刷新,保持用戶操作狀態
|
||
- **優雅錯誤處理**: 完整的錯誤恢復機制和超時保護
|
||
- **資源優化**: 單一活躍會話模式,最小化資源佔用
|
||
|
||
## 📋 流程概覽
|
||
|
||
### 整體交互時序圖
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant AI as AI 助手<br/>(Cursor/Claude/etc)
|
||
participant MCP as MCP 服務<br/>(server.py)
|
||
participant WM as WebUIManager<br/>(單例管理器)
|
||
participant FastAPI as FastAPI 應用<br/>(Web 服務)
|
||
participant WS as WebSocket<br/>(實時通信)
|
||
participant Browser as 瀏覽器<br/>(Web UI)
|
||
participant User as 用戶
|
||
|
||
Note over AI,User: 🚀 第一次調用流程
|
||
AI->>+MCP: interactive_feedback(project_dir, summary, timeout)
|
||
MCP->>+WM: launch_web_feedback_ui()
|
||
|
||
Note over WM: 環境檢測與會話創建
|
||
WM->>WM: detect_environment()
|
||
WM->>WM: create_session()
|
||
|
||
WM->>+FastAPI: 啟動 Web 服務器
|
||
FastAPI->>FastAPI: setup_routes()
|
||
FastAPI->>FastAPI: setup_websocket()
|
||
FastAPI-->>-WM: 服務器就緒
|
||
|
||
WM->>Browser: smart_open_browser(url)
|
||
Note over Browser: 智能開啟瀏覽器<br/>檢測活躍標籤頁
|
||
|
||
Browser->>+FastAPI: GET /feedback
|
||
FastAPI->>FastAPI: render_template()
|
||
FastAPI-->>-Browser: HTML 頁面
|
||
|
||
Browser->>+WS: 建立 WebSocket 連接
|
||
WS->>WM: register_websocket()
|
||
WS-->>-Browser: connection_established
|
||
|
||
Note over AI,User: 💬 用戶回饋流程
|
||
User->>Browser: 填寫回饋內容
|
||
Browser->>+WS: submit_feedback
|
||
WS->>WM: process_feedback()
|
||
WM->>WM: validate_and_save()
|
||
WM->>MCP: set_feedback_complete()
|
||
WS-->>-Browser: feedback_received
|
||
MCP-->>-AI: 返回回饋結果
|
||
|
||
Note over AI,User: 🔄 第二次調用流程 (持久化會話)
|
||
AI->>+MCP: interactive_feedback(new_summary, timeout)
|
||
MCP->>+WM: 檢查現有會話
|
||
|
||
alt 有活躍會話
|
||
WM->>WM: update_session()
|
||
WM->>+WS: session_updated 通知
|
||
WS-->>-Browser: 會話更新訊息
|
||
Browser->>Browser: 局部更新內容
|
||
Note over Browser: 無需重新載入頁面<br/>保持用戶操作狀態
|
||
else 無活躍會話
|
||
WM->>WM: create_new_session()
|
||
WM->>Browser: 重新開啟瀏覽器
|
||
end
|
||
|
||
User->>Browser: 提交新回饋
|
||
Browser->>+WS: submit_feedback
|
||
WS->>WM: process_new_feedback()
|
||
WM->>MCP: set_feedback_complete()
|
||
WS-->>-Browser: feedback_received
|
||
MCP-->>-AI: 返回新回饋結果
|
||
|
||
Note over AI,User: 🧹 資源清理 (可選)
|
||
alt 會話超時或手動清理
|
||
WM->>WS: cleanup_session()
|
||
WS->>Browser: session_cleanup
|
||
WM->>FastAPI: 停止服務器 (可選)
|
||
end
|
||
```
|
||
|
||
## 🚀 第一次調用詳細流程
|
||
|
||
### 1. AI 助手發起調用
|
||
|
||
**MCP 工具調用格式**:
|
||
```python
|
||
# AI 助手通過 MCP 協議調用
|
||
result = await interactive_feedback(
|
||
project_directory="./my-project",
|
||
summary="我已完成了功能 X 的實現,請檢查代碼品質和邏輯正確性。主要變更包括:\n1. 新增錯誤處理機制\n2. 優化性能瓶頸\n3. 增加單元測試覆蓋率",
|
||
timeout=600 # 10 分鐘超時
|
||
)
|
||
```
|
||
|
||
**參數說明**:
|
||
- `project_directory`: 專案根目錄,用於命令執行上下文
|
||
- `summary`: AI 工作摘要,向用戶說明已完成的工作
|
||
- `timeout`: 等待用戶回饋的超時時間(秒)
|
||
|
||
### 2. MCP 服務處理流程
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
START[AI 調用 interactive_feedback] --> VALIDATE[參數驗證與類型檢查]
|
||
VALIDATE --> ENV[環境檢測<br/>Local/SSH/WSL]
|
||
ENV --> MANAGER[獲取 WebUIManager<br/>單例實例]
|
||
MANAGER --> CHECK[檢查現有會話]
|
||
CHECK --> DECISION{有活躍會話?}
|
||
|
||
DECISION -->|否| CREATE[創建新會話]
|
||
DECISION -->|是| UPDATE[更新現有會話]
|
||
|
||
CREATE --> SESSION[WebFeedbackSession<br/>初始化]
|
||
UPDATE --> SESSION
|
||
|
||
SESSION --> SERVER[啟動 FastAPI 服務器]
|
||
SERVER --> PORT[動態埠分配]
|
||
PORT --> ROUTES[設置路由和 WebSocket]
|
||
ROUTES --> BROWSER[智能開啟瀏覽器]
|
||
|
||
BROWSER --> DETECT[檢測活躍標籤頁]
|
||
DETECT --> OPEN_DECISION{需要開啟瀏覽器?}
|
||
|
||
OPEN_DECISION -->|是| OPEN[開啟新瀏覽器視窗]
|
||
OPEN_DECISION -->|否| NOTIFY[發送會話更新通知]
|
||
|
||
OPEN --> WAIT[等待用戶回饋]
|
||
NOTIFY --> WAIT
|
||
|
||
WAIT --> TIMEOUT{檢查超時}
|
||
TIMEOUT -->|未超時| FEEDBACK[接收回饋數據]
|
||
TIMEOUT -->|超時| CLEANUP[清理資源]
|
||
|
||
FEEDBACK --> PROCESS[處理回饋數據<br/>圖片壓縮/命令執行]
|
||
PROCESS --> SAVE[保存回饋記錄]
|
||
SAVE --> RETURN[返回結果給 AI]
|
||
|
||
CLEANUP --> ERROR[返回超時錯誤]
|
||
ERROR --> RETURN
|
||
|
||
style START fill:#e3f2fd
|
||
style RETURN fill:#e8f5e8
|
||
style ERROR fill:#ffebee
|
||
style FEEDBACK fill:#f3e5f5
|
||
```
|
||
|
||
**關鍵步驟詳解**:
|
||
|
||
#### 2.1 環境檢測與適配
|
||
```python
|
||
def detect_environment() -> str:
|
||
"""智能檢測運行環境"""
|
||
# SSH Remote 環境檢測
|
||
if os.environ.get('SSH_CLIENT') or os.environ.get('SSH_TTY'):
|
||
return "ssh"
|
||
|
||
# WSL 環境檢測
|
||
elif 'microsoft' in platform.uname().release.lower():
|
||
return "wsl"
|
||
|
||
# 容器環境檢測
|
||
elif os.path.exists('/.dockerenv'):
|
||
return "docker"
|
||
|
||
# 本地環境
|
||
else:
|
||
return "local"
|
||
|
||
def get_environment_config(env_type: str) -> dict:
|
||
"""根據環境類型獲取配置"""
|
||
configs = {
|
||
"local": {
|
||
"browser_command": "default",
|
||
"host": "127.0.0.1",
|
||
"auto_open": True
|
||
},
|
||
"ssh": {
|
||
"browser_command": None,
|
||
"host": "127.0.0.1",
|
||
"auto_open": False,
|
||
"tunnel_hint": "ssh -L {port}:127.0.0.1:{port} user@host"
|
||
},
|
||
"wsl": {
|
||
"browser_command": "cmd.exe /c start",
|
||
"host": "127.0.0.1",
|
||
"auto_open": True
|
||
}
|
||
}
|
||
return configs.get(env_type, configs["local"])
|
||
```
|
||
|
||
#### 2.2 智能會話管理
|
||
```python
|
||
async def create_or_update_session(
|
||
self,
|
||
project_dir: str,
|
||
summary: str,
|
||
timeout: int
|
||
) -> str:
|
||
"""創建新會話或更新現有會話"""
|
||
|
||
# 保存現有 WebSocket 連接
|
||
existing_websockets = []
|
||
if self.current_session:
|
||
existing_websockets = list(self.current_session.websockets)
|
||
debug_log(f"保存 {len(existing_websockets)} 個現有 WebSocket 連接")
|
||
|
||
# 創建新會話
|
||
session_id = str(uuid.uuid4())
|
||
self.current_session = WebFeedbackSession(
|
||
session_id=session_id,
|
||
project_directory=os.path.abspath(project_dir),
|
||
summary=summary,
|
||
timeout=timeout,
|
||
status=SessionStatus.WAITING,
|
||
created_at=datetime.now()
|
||
)
|
||
|
||
# 繼承 WebSocket 連接,實現無縫切換
|
||
for ws in existing_websockets:
|
||
if ws.client_state == WebSocketState.CONNECTED:
|
||
self.current_session.add_websocket(ws)
|
||
debug_log("WebSocket 連接已繼承到新會話")
|
||
|
||
# 標記需要發送會話更新通知
|
||
self._pending_session_update = True
|
||
|
||
return session_id
|
||
```
|
||
|
||
#### 2.3 動態埠管理
|
||
```python
|
||
class PortManager:
|
||
def find_available_port(self, preferred_port: int = 8765) -> int:
|
||
"""智能埠分配"""
|
||
# 優先使用環境變數指定的埠
|
||
env_port = os.environ.get('MCP_WEB_PORT')
|
||
if env_port and env_port != "0":
|
||
try:
|
||
port = int(env_port)
|
||
if self.is_port_available(port):
|
||
return port
|
||
except ValueError:
|
||
pass
|
||
|
||
# 嘗試首選埠
|
||
if self.is_port_available(preferred_port):
|
||
return preferred_port
|
||
|
||
# 動態分配埠
|
||
for port in range(8765, 8865):
|
||
if self.is_port_available(port):
|
||
return port
|
||
|
||
# 系統自動分配
|
||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
|
||
sock.bind(('127.0.0.1', 0))
|
||
return sock.getsockname()[1]
|
||
```
|
||
|
||
### 3. Web UI 連接建立與初始化
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant Browser as 瀏覽器
|
||
participant FastAPI as FastAPI 服務
|
||
participant Template as 模板引擎
|
||
participant WS as WebSocket
|
||
participant Session as 會話管理
|
||
participant I18N as 國際化
|
||
|
||
Note over Browser,I18N: 頁面載入流程
|
||
Browser->>+FastAPI: GET /feedback
|
||
FastAPI->>+Template: render_template()
|
||
Template->>I18N: 載入語言包
|
||
I18N-->>Template: 翻譯資源
|
||
Template->>Template: 渲染 HTML
|
||
Template-->>-FastAPI: 完整頁面
|
||
FastAPI-->>-Browser: HTML + CSS + JS
|
||
|
||
Note over Browser,Session: WebSocket 連接建立
|
||
Browser->>Browser: 載入 JavaScript 模組
|
||
Browser->>+WS: 建立 WebSocket 連接 (/ws)
|
||
WS->>Session: register_websocket()
|
||
Session->>Session: 檢查會話狀態
|
||
WS-->>-Browser: connection_established
|
||
|
||
Note over Browser,Session: 會話狀態同步
|
||
alt 有活躍會話
|
||
Session->>+WS: session_data
|
||
WS-->>-Browser: 當前會話資訊
|
||
Browser->>Browser: 更新 AI 摘要
|
||
Browser->>Browser: 設置會話 ID
|
||
end
|
||
|
||
alt 有待處理的會話更新
|
||
Session->>+WS: session_updated
|
||
WS-->>-Browser: 會話更新通知
|
||
Browser->>Browser: 顯示更新提示
|
||
Browser->>Browser: 局部刷新內容
|
||
Browser->>Browser: 自動聚焦輸入框
|
||
end
|
||
|
||
Note over Browser,Session: 心跳檢測啟動
|
||
Browser->>Browser: 啟動心跳定時器
|
||
loop 每 30 秒
|
||
Browser->>WS: heartbeat
|
||
WS-->>Browser: heartbeat_ack
|
||
end
|
||
```
|
||
|
||
**連接建立關鍵步驟**:
|
||
|
||
#### 3.1 頁面渲染
|
||
```python
|
||
@app.get("/feedback")
|
||
async def feedback_page(request: Request):
|
||
"""回饋頁面渲染"""
|
||
manager = get_web_ui_manager()
|
||
session = manager.current_session
|
||
|
||
# 載入用戶設定
|
||
layout_mode = load_user_layout_settings()
|
||
|
||
# 獲取當前語言
|
||
i18n_manager = get_i18n_manager()
|
||
current_language = i18n_manager.get_current_language()
|
||
|
||
return templates.TemplateResponse("feedback.html", {
|
||
"request": request,
|
||
"project_directory": session.project_directory if session else ".",
|
||
"layout_mode": layout_mode,
|
||
"current_language": current_language,
|
||
"session_id": session.session_id if session else None,
|
||
"title": i18n_manager.t("app.title")
|
||
})
|
||
```
|
||
|
||
#### 3.2 WebSocket 連接處理
|
||
```python
|
||
@app.websocket("/ws")
|
||
async def websocket_endpoint(websocket: WebSocket):
|
||
"""WebSocket 連接端點"""
|
||
await websocket.accept()
|
||
|
||
try:
|
||
# 註冊 WebSocket 連接
|
||
manager = get_web_ui_manager()
|
||
if manager.current_session:
|
||
manager.current_session.add_websocket(websocket)
|
||
|
||
# 發送連接確認
|
||
await websocket.send_json({
|
||
"type": "connection_established",
|
||
"data": {
|
||
"timestamp": datetime.now().isoformat(),
|
||
"session_id": manager.current_session.session_id if manager.current_session else None
|
||
}
|
||
})
|
||
|
||
# 如果有待處理的會話更新,立即發送
|
||
if manager._pending_session_update and manager.current_session:
|
||
await websocket.send_json({
|
||
"type": "session_updated",
|
||
"data": {
|
||
"session_id": manager.current_session.session_id,
|
||
"summary": manager.current_session.summary,
|
||
"project_directory": manager.current_session.project_directory
|
||
}
|
||
})
|
||
manager._pending_session_update = False
|
||
|
||
# 處理訊息循環
|
||
while True:
|
||
data = await websocket.receive_json()
|
||
await handle_websocket_message(websocket, data)
|
||
|
||
except WebSocketDisconnect:
|
||
# 處理連接斷開
|
||
if manager.current_session:
|
||
manager.current_session.remove_websocket(websocket)
|
||
debug_log("WebSocket 連接已斷開")
|
||
```
|
||
|
||
## 🔄 多次循環調用機制
|
||
|
||
### 持久化會話架構
|
||
|
||
MCP Feedback Enhanced 的核心創新在於**持久化會話架構**,支援 AI 助手進行多次循環調用而無需重新建立連接。
|
||
|
||
```mermaid
|
||
stateDiagram-v2
|
||
[*] --> FirstCall: AI 首次調用
|
||
FirstCall --> SessionActive: 會話建立
|
||
SessionActive --> UserFeedback: 等待用戶回饋
|
||
UserFeedback --> FeedbackSubmitted: 回饋提交
|
||
FeedbackSubmitted --> AIProcessing: AI 處理回饋
|
||
AIProcessing --> SecondCall: AI 再次調用
|
||
SecondCall --> SessionUpdated: 會話更新
|
||
SessionUpdated --> UserFeedback: 等待新回饋
|
||
|
||
note right of SessionActive
|
||
Web 服務器持續運行
|
||
瀏覽器標籤頁保持開啟
|
||
WebSocket 連接維持
|
||
end note
|
||
|
||
note right of SessionUpdated
|
||
無需重新開啟瀏覽器
|
||
局部更新頁面內容
|
||
狀態無縫切換
|
||
end note
|
||
```
|
||
|
||
### 第二次調用流程
|
||
|
||
#### 1. AI 助手再次調用
|
||
```python
|
||
# AI 根據用戶回饋進行調整後再次調用
|
||
result = await interactive_feedback(
|
||
project_directory="./my-project",
|
||
summary="根據您的建議,我已修改了錯誤處理邏輯,請再次確認",
|
||
timeout=600
|
||
)
|
||
```
|
||
|
||
#### 2. 智能會話切換
|
||
```mermaid
|
||
flowchart TD
|
||
CALL[AI 再次調用] --> CHECK[檢查現有會話]
|
||
CHECK --> ACTIVE{有活躍會話?}
|
||
ACTIVE -->|是| UPDATE[更新會話內容]
|
||
ACTIVE -->|否| CREATE[創建新會話]
|
||
UPDATE --> PRESERVE[保存 WebSocket 連接]
|
||
CREATE --> PRESERVE
|
||
PRESERVE --> NOTIFY[發送會話更新通知]
|
||
NOTIFY --> FRONTEND[前端接收更新]
|
||
FRONTEND --> REFRESH[局部刷新內容]
|
||
```
|
||
|
||
#### 3. 前端無縫更新
|
||
```javascript
|
||
// 處理會話更新訊息
|
||
function handleSessionUpdated(data) {
|
||
// 顯示會話更新通知
|
||
showNotification('會話已更新', 'info');
|
||
|
||
// 重置回饋狀態
|
||
feedbackState = 'FEEDBACK_WAITING';
|
||
|
||
// 局部更新 AI 摘要
|
||
updateAISummary(data.summary);
|
||
|
||
// 清空回饋表單
|
||
clearFeedbackForm();
|
||
|
||
// 更新會話 ID
|
||
currentSessionId = data.session_id;
|
||
|
||
// 保持 WebSocket 連接不變
|
||
// 無需重新建立連接
|
||
}
|
||
```
|
||
|
||
## 🚀 新功能交互流程
|
||
|
||
### 自動提交功能流程
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant User as 用戶
|
||
participant UI as 前端界面
|
||
participant ASM as AutoSubmitManager
|
||
participant PM as PromptManager
|
||
participant WS as WebSocket
|
||
|
||
Note over User,WS: 🔧 設定自動提交
|
||
User->>UI: 開啟設定頁籤
|
||
UI->>PM: 獲取提示詞列表
|
||
PM-->>UI: 返回提示詞(自動提交優先)
|
||
User->>UI: 選擇提示詞並設定倒數時間
|
||
UI->>ASM: updateSettings(enabled, timeout, promptId)
|
||
ASM->>WS: 保存設定到服務器
|
||
|
||
Note over User,WS: ⏰ 自動提交執行
|
||
WS->>UI: session_updated(AI 新調用)
|
||
UI->>ASM: checkAutoSubmitConditions()
|
||
ASM->>ASM: 檢查設定和狀態
|
||
alt 條件滿足
|
||
ASM->>ASM: start(timeout, promptId)
|
||
ASM->>UI: 顯示倒數計時器
|
||
loop 每秒更新
|
||
ASM->>UI: updateCountdownDisplay(remaining)
|
||
end
|
||
ASM->>PM: getPromptById(promptId)
|
||
PM-->>ASM: 返回提示詞內容
|
||
ASM->>UI: 填入提示詞到輸入框
|
||
ASM->>WS: submit_feedback(自動提交)
|
||
else 條件不滿足
|
||
ASM->>UI: 隱藏倒數計時器
|
||
end
|
||
```
|
||
|
||
### 提示詞管理流程
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant User as 用戶
|
||
participant UI as 設定界面
|
||
participant PM as PromptManager
|
||
participant Modal as PromptModal
|
||
participant Storage as LocalStorage
|
||
|
||
Note over User,Storage: 📝 新增提示詞
|
||
User->>UI: 點擊「新增提示詞」
|
||
UI->>Modal: showAddModal()
|
||
Modal->>User: 顯示編輯表單
|
||
User->>Modal: 輸入名稱和內容
|
||
Modal->>PM: addPrompt(name, content)
|
||
PM->>PM: 驗證數據和唯一性
|
||
PM->>Storage: 保存到 localStorage
|
||
PM->>UI: 觸發 onPromptsChange 回調
|
||
UI->>UI: refreshPromptList()
|
||
|
||
Note over User,Storage: ✏️ 編輯提示詞
|
||
User->>UI: 點擊編輯按鈕
|
||
UI->>Modal: showEditModal(prompt)
|
||
Modal->>User: 顯示預填表單
|
||
User->>Modal: 修改內容
|
||
Modal->>PM: updatePrompt(id, name, content)
|
||
PM->>Storage: 更新 localStorage
|
||
PM->>UI: 觸發回調更新界面
|
||
|
||
Note over User,Storage: 🎯 使用提示詞
|
||
User->>UI: 在輸入區點擊提示詞按鈕
|
||
UI->>PM: getPromptsSortedByUsage()
|
||
PM-->>UI: 返回排序後列表
|
||
UI->>Modal: showSelectModal(prompts)
|
||
User->>Modal: 選擇提示詞
|
||
Modal->>PM: usePrompt(id)
|
||
PM->>Storage: 更新使用記錄
|
||
Modal->>UI: 填入提示詞內容
|
||
```
|
||
|
||
### 會話管理流程(v2.4.3 重構增強)
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant AI as AI 助手
|
||
participant Server as MCP 服務器
|
||
participant SM as SessionManager
|
||
participant SDM as SessionDataManager
|
||
participant SUR as SessionUIRenderer
|
||
participant UI as 前端界面
|
||
|
||
Note over AI,UI: 📊 會話生命週期管理(v2.4.3 重構)
|
||
AI->>Server: interactive_feedback()
|
||
Server->>SM: createSession()
|
||
SM->>SDM: addCurrentSession()
|
||
SDM->>SUR: renderCurrentSession()
|
||
SUR->>UI: 更新會話顯示(頁籤化設計)
|
||
|
||
Note over AI,UI: 📝 用戶回饋處理
|
||
UI->>Server: submit_feedback
|
||
Server->>SM: processFeedback()
|
||
SM->>SDM: updateSessionStatus()
|
||
SDM->>SDM: 記錄回饋數據(本地存儲)
|
||
SM->>AI: 返回回饋結果
|
||
|
||
Note over AI,UI: 📚 會話歷史管理(v2.4.3 增強)
|
||
SM->>SDM: addSessionToHistory()
|
||
SDM->>SDM: 檢查完成狀態
|
||
alt 會話已完成
|
||
SDM->>SDM: 加入歷史記錄(localStorage)
|
||
SDM->>SDM: updateStats()
|
||
SDM->>SUR: renderSessionHistory()
|
||
SUR->>UI: 觸發 onHistoryChange
|
||
else 會話未完成
|
||
SDM->>SDM: 跳過歷史記錄
|
||
end
|
||
|
||
Note over AI,UI: 🔍 歷史查詢與管理
|
||
UI->>SDM: getSessionHistory()
|
||
SDM-->>UI: 返回歷史列表(72小時內)
|
||
UI->>SDM: getSessionStats()
|
||
SDM-->>UI: 返回統計數據
|
||
UI->>SDM: exportSessionHistory()
|
||
SDM-->>UI: 返回匯出數據
|
||
UI->>SDM: cleanupExpiredSessions()
|
||
SDM->>SDM: 清理過期會話
|
||
```
|
||
|
||
### 音效通知系統流程(v2.4.3 新增)
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant WS as WebSocket
|
||
participant AM as AudioManager
|
||
participant ASU as AudioSettingsUI
|
||
participant AUDIO as Web Audio API
|
||
participant User as 用戶
|
||
|
||
Note over WS,User: 🔊 音效通知觸發流程
|
||
WS->>AM: session_updated 事件
|
||
AM->>AM: checkNotificationEnabled()
|
||
alt 音效通知已啟用
|
||
AM->>AM: getSelectedAudio()
|
||
AM->>AUDIO: 創建 Audio 物件
|
||
AM->>AUDIO: 設定音量和來源
|
||
AUDIO->>User: 播放通知音效
|
||
AM->>AM: logPlaybackSuccess()
|
||
else 音效通知已停用
|
||
AM->>AM: logSkippedNotification()
|
||
end
|
||
|
||
Note over WS,User: 🎵 音效設定管理
|
||
User->>ASU: 開啟音效設定
|
||
ASU->>AM: getAudioSettings()
|
||
AM-->>ASU: 返回當前設定
|
||
ASU->>User: 顯示設定界面
|
||
|
||
User->>ASU: 調整音量
|
||
ASU->>AM: updateVolume(volume)
|
||
AM->>AM: saveSettings()
|
||
|
||
User->>ASU: 選擇音效
|
||
ASU->>AM: selectAudio(audioId)
|
||
AM->>AM: saveSettings()
|
||
|
||
User->>ASU: 測試播放
|
||
ASU->>AM: testPlayAudio(audioId)
|
||
AM->>AUDIO: 播放測試音效
|
||
AUDIO->>User: 播放音效
|
||
|
||
Note over WS,User: 📁 自訂音效管理
|
||
User->>ASU: 上傳自訂音效
|
||
ASU->>ASU: validateAudioFile()
|
||
ASU->>AM: addCustomAudio(file)
|
||
AM->>AM: convertToBase64()
|
||
AM->>AM: saveToLocalStorage()
|
||
ASU->>User: 顯示上傳成功
|
||
```
|
||
|
||
### 智能記憶功能流程(v2.4.3 新增)
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant User as 用戶
|
||
participant TEXTAREA as 輸入框
|
||
participant THM as TextareaHeightManager
|
||
participant RO as ResizeObserver
|
||
participant SM as SettingsManager
|
||
|
||
Note over User,SM: 📏 輸入框高度記憶
|
||
User->>TEXTAREA: 調整輸入框高度
|
||
TEXTAREA->>RO: 觸發尺寸變化事件
|
||
RO->>THM: handleResize(element)
|
||
THM->>THM: debounce(500ms)
|
||
THM->>SM: saveHeight(elementId, height)
|
||
SM->>SM: 保存到 localStorage
|
||
|
||
Note over User,SM: 🔄 高度恢復
|
||
User->>User: 重新載入頁面
|
||
THM->>SM: loadHeight(elementId)
|
||
SM-->>THM: 返回保存的高度
|
||
THM->>TEXTAREA: 應用保存的高度
|
||
TEXTAREA->>User: 顯示恢復的高度
|
||
|
||
Note over User,SM: 📋 一鍵複製功能
|
||
User->>User: 點擊專案路徑
|
||
User->>User: 觸發複製事件
|
||
User->>User: 複製到剪貼簿
|
||
User->>User: 顯示複製成功提示
|
||
|
||
User->>User: 點擊會話ID
|
||
User->>User: 觸發複製事件
|
||
User->>User: 複製到剪貼簿
|
||
User->>User: 顯示複製成功提示(多語言)
|
||
```
|
||
|
||
## 📊 狀態同步機制
|
||
|
||
### WebSocket 訊息類型(v2.4.3 擴展)
|
||
|
||
```mermaid
|
||
graph LR
|
||
subgraph "服務器 → 客戶端"
|
||
CE[connection_established<br/>連接建立]
|
||
SU[session_updated<br/>會話更新<br/>🔊 觸發音效通知]
|
||
FR[feedback_received<br/>回饋確認]
|
||
ST[status_update<br/>狀態更新]
|
||
ASS[auto_submit_status<br/>自動提交狀態]
|
||
SH[session_history<br/>會話歷史<br/>📚 v2.4.3 增強]
|
||
AN[audio_notification<br/>音效通知<br/>🔊 v2.4.3 新增]
|
||
end
|
||
|
||
subgraph "客戶端 → 服務器"
|
||
SF[submit_feedback<br/>提交回饋]
|
||
HB[heartbeat<br/>心跳檢測]
|
||
LS[language_switch<br/>語言切換]
|
||
PM[prompt_management<br/>提示詞管理]
|
||
ASC[auto_submit_control<br/>自動提交控制]
|
||
SM[session_management<br/>會話管理<br/>📋 v2.4.3 重構]
|
||
AM[audio_management<br/>音效管理<br/>🎵 v2.4.3 新增]
|
||
HM[height_management<br/>高度管理<br/>📏 v2.4.3 新增]
|
||
end
|
||
```
|
||
|
||
### 狀態轉換圖
|
||
|
||
```mermaid
|
||
stateDiagram-v2
|
||
[*] --> WAITING: 會話創建/更新
|
||
WAITING --> AUTO_SUBMIT_READY: 自動提交條件滿足
|
||
AUTO_SUBMIT_READY --> AUTO_SUBMIT_COUNTDOWN: 啟動倒數計時
|
||
AUTO_SUBMIT_COUNTDOWN --> FEEDBACK_PROCESSING: 自動提交執行
|
||
WAITING --> FEEDBACK_PROCESSING: 用戶手動提交回饋
|
||
FEEDBACK_PROCESSING --> FEEDBACK_SUBMITTED: 處理完成
|
||
FEEDBACK_SUBMITTED --> WAITING: 新會話更新
|
||
FEEDBACK_SUBMITTED --> [*]: 會話結束
|
||
|
||
AUTO_SUBMIT_COUNTDOWN --> WAITING: 用戶取消自動提交
|
||
WAITING --> ERROR: 連接錯誤
|
||
FEEDBACK_PROCESSING --> ERROR: 處理錯誤
|
||
AUTO_SUBMIT_COUNTDOWN --> ERROR: 自動提交錯誤
|
||
ERROR --> WAITING: 錯誤恢復
|
||
ERROR --> [*]: 致命錯誤
|
||
|
||
note right of AUTO_SUBMIT_READY
|
||
檢查自動提交設定:
|
||
- 功能已啟用
|
||
- 已選擇提示詞
|
||
- 當前狀態為等待回饋
|
||
end note
|
||
|
||
note right of AUTO_SUBMIT_COUNTDOWN
|
||
倒數計時狀態:
|
||
- 顯示剩餘時間
|
||
- 允許用戶取消
|
||
- 時間到自動提交
|
||
end note
|
||
```
|
||
|
||
## 🛡️ 錯誤處理和恢復
|
||
|
||
### 連接斷線處理
|
||
```javascript
|
||
// WebSocket 重連機制
|
||
function handleWebSocketClose() {
|
||
console.log('WebSocket 連接已關閉,嘗試重連...');
|
||
|
||
setTimeout(() => {
|
||
initWebSocket();
|
||
}, 3000); // 3秒後重連
|
||
}
|
||
|
||
// 心跳檢測
|
||
setInterval(() => {
|
||
if (websocket && websocket.readyState === WebSocket.OPEN) {
|
||
websocket.send(JSON.stringify({
|
||
type: 'heartbeat',
|
||
timestamp: Date.now()
|
||
}));
|
||
}
|
||
}, 30000); // 每30秒發送心跳
|
||
```
|
||
|
||
### 超時處理
|
||
```python
|
||
async def wait_for_feedback(self, timeout: int = 600):
|
||
try:
|
||
await asyncio.wait_for(
|
||
self.feedback_completed.wait(),
|
||
timeout=timeout
|
||
)
|
||
return self.get_feedback_result()
|
||
except asyncio.TimeoutError:
|
||
raise TimeoutError(f"等待用戶回饋超時 ({timeout}秒)")
|
||
```
|
||
|
||
## 🎯 性能優化
|
||
|
||
### 連接復用
|
||
- **WebSocket 連接保持**: 避免重複建立連接
|
||
- **會話狀態繼承**: 新會話繼承舊會話的連接
|
||
- **智能瀏覽器開啟**: 檢測活躍標籤頁,避免重複開啟
|
||
|
||
### 資源管理
|
||
- **自動清理機制**: 超時會話自動清理
|
||
- **內存優化**: 單一活躍會話模式
|
||
- **進程管理**: 優雅的進程啟動和關閉
|
||
|
||
## 🔒 安全性考量
|
||
|
||
### 數據安全
|
||
- **本地綁定**: 服務器只綁定 127.0.0.1,減少攻擊面
|
||
- **輸入驗證**: 嚴格的參數類型檢查和數據清理
|
||
- **文件上傳安全**: 圖片格式驗證和大小限制
|
||
- **命令執行限制**: 在專案目錄內執行,防止路徑遍歷
|
||
|
||
### 網路安全
|
||
- **WebSocket 驗證**: 連接來源驗證
|
||
- **CORS 控制**: 限制跨域請求來源
|
||
- **超時保護**: 防止長時間佔用資源
|
||
- **錯誤信息過濾**: 避免敏感信息洩露
|
||
|
||
## 🚀 性能優化總結
|
||
|
||
### 連接復用優勢
|
||
- **減少 60% 啟動時間**: 避免重複建立服務器和瀏覽器
|
||
- **降低 40% 記憶體使用**: 單一活躍會話模式
|
||
- **提升用戶體驗**: 無縫會話切換,保持操作狀態
|
||
- **減少網路開銷**: WebSocket 連接保持和復用
|
||
|
||
### 資源管理效率
|
||
- **智能清理**: 自動檢測和清理過期資源
|
||
- **動態埠分配**: 避免埠衝突,支援並行開發
|
||
- **錯誤恢復**: 優雅的錯誤處理和自動重連
|
||
- **跨平台適配**: 統一的環境檢測和適配機制
|
||
|
||
---
|
||
|
||
## 📚 相關文檔
|
||
|
||
- **[系統架構總覽](./system-overview.md)** - 了解整體架構設計理念和技術棧
|
||
- **[組件詳細說明](./component-details.md)** - 深入了解各層組件的具體實現
|
||
- **[API 參考文檔](./api-reference.md)** - 完整的 API 端點和參數說明
|
||
- **[部署指南](./deployment-guide.md)** - 環境配置和部署最佳實踐
|
||
|
||
---
|
||
|
||
**版本**: 2.4.3
|
||
**最後更新**: 2025年6月14日
|
||
**維護者**: Minidoracat
|
||
**架構類型**: Web-Only 四層架構
|
||
**核心特性**: 持久化會話、智能環境適配、無縫狀態切換
|
||
**v2.4.3 新功能**: 音效通知系統、會話管理重構、智能記憶功能
|