Interface C4 Architecture¶
C1: System Context¶
┌─────────────────────────────────────────────────────────────────┐
│ User │
└────────────────────────────┬────────────────────────────────────┘
│
│ HTTP Browser
│
┌────────────────────────────▼────────────────────────────────────┐
│ │
│ Time Compass Gradio App │
│ (Frontend Application - Scheduling & Planning) │
│ │
└────────────┬──────────────────────────┬────────────┬────────────┘
│ │ │
│ Read/Write Events │ Chat Flow │ Streaming
│ │ │
┌────────────▼──────────────────────────▼────────────▼────────────┐
│ Domain Layer │
│ (Router, Orchestrator, LLM Manager, Streaming Manager) │
└────────────┬──────────────────────────┬────────────┬────────────┘
│ │ │
│ Integration APIs │ Models │ External
│ │ │
┌────────────▼──────────────────────────▼────────────▼────────────┐
│ External Systems / Integrations │
│ (Google Calendar, Google Tasks, Moodle, LiteLLM Proxy) │
└──────────────────────────────────────────────────────────────────┘
C2: 容器(gradio_app.py)¶
Gradio 應用作為 UI 容器,負責: - 組合 6 個 UI Tab(聊天、排程、模型管理、Moodle、快速測試、除錯) - 啟動 Gradio Blocks web 伺服器 - 路由 用戶事件到 domain 層(orchestrator、streaming manager) - 管理 環境變數與主題載入
┌────────────────────────────────────────────────────────────┐
│ Gradio Blocks (web 伺服器) │
├────────────────────────────────────────────────────────────┤
│ Tab 層(平行) │
│ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │ 聊天 │ │ 排程 │ │ 模型 │ │Moodle │ │ 快速 │ │
│ │ Tab │ │ Tab │ │ 管理 │ │ Tab │ │ 測試 │ │
│ │ │ │ │ │ Tab │ │ │ │ Tab │ │
│ └───┬────┘ └───┬────┘ └───┬────┘ └───┬───┘ └───┬────┘ │
│ │ │ │ │ │ │
│ ┌────────┐ │ │ │ │ │
│ │ 除錯 │ │ │ │ │ │
│ │ Tab │ │ │ │ │ │
│ └───┬────┘ │ │ │ │ │
│ │ │ │ │ │ │
│ └──────────┴──────────┴──────────┴─────────┘ │
│ ↓ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ 事件處理器與狀態管理 │ │
│ │ (gr.State、async callbacks、使用者事件) │ │
│ └──────────┬───────────────────────────────────────┘ │
│ ↓ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ 串流模組 (streaming.py) │ │
│ │ - format_stream_output() │ │
│ │ - stream_main_output() [async generator] │ │
│ │ - chat_fn() [Gradio 回調] │ │
│ └──────────┬───────────────────────────────────────┘ │
│ ↓ │
└─────────────┼───────────────────────────────────────────┘
│
└─→ 呼叫 Domain / Orchestrator
C3: 元件(UI Tabs 與串流)¶
3.1 聊天 Tab (ui/chat_tab.py)¶
目的:聊天機器人 UI,含訊息歷史路由至 orchestrator
| 面向 | 詳細說明 |
|---|---|
| 輸入 | 使用者文字、聊天歷史、工作階段狀態 |
| 輸出 | 更新後的聊天視圖、呼叫 router/orchestrator |
| 核心函數 | handle_send()、render_history()(預期) |
| 狀態 | 預留位置 - 等待 router/orchestrator 介面 |
3.2 排程 Tab (ui/scheduling_tab.py)¶
目的:兩階段事件鏈用於任務規劃與日曆回寫
| 面向 | 詳細說明 |
|---|---|
| 階段 1 | 解析使用者輸入 → 建立任務與草稿狀態 |
| 階段 2 | 渲染狀態 → Dataframe、Markdown、JSON 成品 |
| 核心函數 | stage1_chat()(async)、stage2_render() |
| 狀態 | gr.State(plan_state)儲存任務、draft_rows、回寫 |
| 回寫 | 目前為 dry-run;等待實際日曆 API 呼叫 |
3.3 模型管理 Tab (ui/model_management_tab.py)¶
目的:列出並重新載入 DSPy comfort 模型
| 面向 | 詳細說明 |
|---|---|
| 輸入 | 檔案系統:models/dspy/comfort_emotion_v*.json |
| 輸出 | 模型版本列表、重新載入狀態訊息 |
| 核心函數 | reload_latest_model() |
| 整合 | 可選橋接至 gradio_app._make_workflow() |
3.4 Moodle Tab (ui/moodle_tab.py)¶
目的:爬蟲取得 Moodle 課程事件並顯示
| 面向 | 詳細說明 |
|---|---|
| 輸入 | 使用者帳號、密碼、無頭模式旗標 |
| 輸出 | 事件數量、時間戳記、最近事件列表(Markdown) |
| 上游 | 呼叫 time_compass.integrations.moodle.scrape_moodle_events() |
| 安全提示 | 直接密碼輸入;建議生產環境改用 OAuth/token 方案 |
3.5 快速測試 Tab (ui/quick_test_tab.py)¶
目的:開發者專用介面,用於快速測試串流與 orchestrator
| 面向 | 詳細說明 |
|---|---|
| 輸入 | 使用者提示詞(Textbox) |
| 輸出 | 合併後的串流輸出(Markdown) |
| 核心函數 | _quick_run() 透過 asyncio.run() 執行 stream_main_output() |
| 用途 | 本地開發/除錯專用;生產環境應隱藏 |
3.6 除錯 Tab (ui/debug_tab.py)¶
目的:開發者工具,檢視系統狀態與即時日誌
| 面向 | 詳細說明 |
|---|---|
| 輸入 | 無(被動檢視) |
| 輸出 | 系統狀態、最近日誌、效能指標(Markdown/表格) |
| 核心函數 | debug_tab()、狀態更新回調 |
| 用途 | 本地開發/疑難排除;隱藏在生產環境 |
| 功能 | 顯示 MCP 連線、Orchestrator 狀態、記憶體使用、最近任務 |
⚠️ 待修正:本章節說明需要驗證實際實作,標記以便後續完善
3.7 串流模組 (streaming.py)¶
目的:統一非同步串流協調,管理分塊輸出
| 面向 | 詳細說明 |
|---|---|
| 核心函數 | format_stream_output()、stream_main_output()(async gen)、chat_fn() |
| 輸入 | 使用者訊息、domain orchestrator(可選) |
| 輸出 | 格式化分塊的非同步產生器 → Gradio UI |
| 回退機制 | Orchestrator 不可用時,yield 原始輸入 |
| 配置 | STREAM_DELAY 環境變數控制分塊間隔 |
工作流:
使用者訊息
↓
stream_main_output() [async]
↓
build_streaming_orchestrator() [若可用]
↓
迭代非同步輸出流
├─ 偵測欄位/模組變更
├─ 累積與格式化分塊
├─ 以 STREAM_DELAY 間隔 yield 到前端
└─ 處理例外 → error yield
C4: 程式碼層(主要介面)¶
4.1 Tab 介面(預期)¶
def {聊天,排程,moodle,模型管理,快速測試}_tab() -> Dict[str, Any]:
"""
回傳包含以下內容的字典:
- gr.Textbox/Chatbot 元件
- gr.Button(提交/動作)
- gr.Markdown/Dataframe(輸出)
- 事件處理器(click、submit)
"""
pass
4.2 串流介面¶
async def stream_main_output(user_input: str) -> AsyncGenerator[str, None]:
"""
核心串流產生器:
- 若可用,建立 orchestrator
- 從 orchestrator.output_stream 迭代非同步分塊
- 累積、格式化、以 STREAM_DELAY 频率 yield
"""
async def chat_fn(message: str, history: List[Dict[str, Any]]):
"""Gradio 回調:銜接 stream_main_output → 前端"""
def format_stream_output(module: str, field: str, text: str) -> str:
"""將分塊格式化為 [Module:field] text"""
4.3 Gradio 應用入口¶
from time_compass.interface.gradio_app import main
main() # 啟動伺服器,含所有 tabs、串流、主題
資料流總覽¶
使用者輸入(Textbox 或 Chat)
↓
Tab 事件處理器
├─ 聊天 Tab → router / streaming.chat_fn()
├─ 排程 Tab → stage1_chat() → stage2_render()
├─ Moodle Tab → scrape_moodle_events()
├─ 模型管理 Tab → reload_latest_model()
└─ 快速測試 Tab → stream_main_output()
↓
Domain 層(Orchestrator、Router、Integration)
↓
串流格式或直接回應
↓
更新 Gradio 元件
架構原則¶
- 關注點分離
gradio_app.py:Tab 組合與伺服器生命週期ui/*.py:UI 配置與事件綁定(薄適配層)streaming.py:統一非同步分塊管理-
Domain 層:業務邏輯(router、orchestrator、整合)
-
非同步優先
- 所有串流路徑使用非同步產生器
-
Gradio 回調視需要適配非同步/同步
-
可擴展性
- 新 Tab:加入
ui/、在gradio_app中匯入、綁定事件 -
新串流行為:擴展
stream_main_output()或建立新 orchestrator -
回退與錯誤處理
- 串流:yield 錯誤訊息而非崩潰
- Tabs:優雅降級(如模型重新載入失敗 → 顯示後備方案)
- Orchestrator 不可用 → 使用原始輸入作為後備