跳到內容
OmniRoute source

Playground Studio (中文 (繁體))

Playground Studio 將 /dashboard/playground 從簡易的 Monaco 編輯器轉變為 功能完整的測試工作區。它以 PlaygroundStudio 外殼取代舊版 page.tsx, 呈現四個分頁與共用設定窗格。

┌ Playground ──────────────────────────────────────────────────────────┐
│ [💬 聊天] [⚖ 比較] [{} API] [🔧 建置] 142↑ 38↓ · $0.002 </>│
├──────────────────────────────────────────┬───────────────────────────┤
│ {使用中分頁內容} │ ─ 設定 │
│ │ 端點 [chat ∨] │
│ │ 模型 [gpt-5.4 ∨] │
│ │ 系統 [文字區域] │
│ │ 溫度 ▕▕▔▔ 0.7 │
│ │ 預設集 [▾ 載入][儲存] │
│ │ [✨ 改善提示詞] │
└──────────────────────────────────────────┴───────────────────────────┘

將 ChatPlayground.tsx 發展為支援多輪串流的工作台:

  • 透過 MarkdownMessage.tsx 完整呈現 Markdown(程式碼區塊、表格、清單、連結)。
  • 系統提示詞取自共用的設定窗格。
  • 顯示每則訊息的 Token/成本(提示詞 + 完成 Token)。
  • 重新產生上一個回應。
  • 傳送至 POST /v1/chat/completions,並使用 SSE 串流。

代理服務的關鍵差異化功能:針對最多 4 個模型並行執行 1 個提示詞。

  • 最多 4 欄,每欄皆獨立從 /v1/chat/completions 接收串流。
  • 使用 + 新增模型 按鈕(Cmd+K 快捷鍵)新增欄位。
  • 全部執行 ▶ 透過 Promise.all 與各欄專屬的 AbortController 同時觸發所有串流。
  • 全域的全部取消會中止每個進行中的串流。
  • 各欄的 ProviderMetrics 會即時顯示 TTFT、TPS、Token 數量與預估成本。
  • 指標會標示為**「用戶端估算」**(D12)— 從第一個 SSE 區塊開始測量。

為進階使用者完整保留原始 Monaco 編輯器的所有功能(D14):

  • 10 個端點:聊天完成、文字完成、嵌入、影像、音訊、語音、轉錄、內容審核、重新排序、搜尋。
  • 多模態檔案上傳。
  • SSE 串流與即時輸出。
  • 封裝為 ApiTab.tsx(延遲載入,ssr: false)。

工具/函式呼叫與結構化輸出的使用者介面:

  • ToolsBuilder.tsx — 新增/編輯/移除 tools[],且每個工具皆有 JSON Schema 編輯器。 透過 ToolDefinitionSchema(Zod)驗證參數。
  • StructuredOutputEditor.tsx — 切換 JSON 模式 + JSON Schema 編輯器。 透過 StructuredOutputSchema(Zod)依據結構描述驗證回應。
  • 將包含 tools[] 和/或 response_format 的請求傳送至 /v1/chat/completions。

StudioConfigPane.tsx — 永遠可見,可收合。

欄位 元件 備註
端點 &lt;select&gt; 與 PlaygroundEndpoint 相符的 10 個選項
模型 &lt;input&gt; 自由文字,例如 openai/gpt-4o
系統提示 &lt;textarea&gt; 提供給所有分頁使用
參數 ParamSliders temperature、max_tokens、top_p、presence/frequency penalty、seed、stop
預設集 PresetPicker 載入/儲存具名設定快照(持久化於 DB)
改善提示 ImprovePromptButton 開啟配額警告對話框,呼叫 /api/playground/improve-prompt

狀態會提升至 PlaygroundStudio.tsx,並向下傳遞至所有分頁。切換分頁時會 保留設定狀態。


StudioTopBar.tsx:

  • 分頁切換器(role=“tablist”)。
  • TokenCostCounter — 即時權杖(↑/↓)與預估成本顯示。
  • 匯出程式碼按鈕(</>)— 開啟 ExportCodeModal。

ExportCodeModal.tsx 使用 codeExport.ts,根據目前的 PlaygroundState 產生 curl / Python / TypeScript 程式碼片段。 API 金鑰預留位置一律為 $OMNIROUTE_API_KEY(D11)。


ImprovePromptButton.tsx → useImprovePrompt.ts → POST /api/playground/improve-prompt:

  1. 對話框警告「將會消耗配額」。
  2. 確認後,將 { system, prompt, model, tone } 傳送至該路由。
  3. 路由在內部使用 promptImprover.META_SYSTEM_PROMPT 呼叫 /v1/chat/completions。
  4. 傳回 { improvedSystem?, improvedPrompt?, tokensIn, tokensOut }。
  5. UI 會更新設定窗格的系統提示,以及聊天分頁的使用者提示。

PresetPicker.tsx → usePresets.ts → /api/playground/presets/*:

  • 儲存於 playground_presets SQLite 資料表(遷移檔案 084_playground_presets.sql)。
  • 每個預設集儲存:name、endpoint、model、system、params_json、created_at。
  • CRUD:GET 列出、POST 建立、GET /:id、PUT /:id、DELETE /:id。

useStreamMetrics.ts + streamMetrics.ts(純函式):

  • start() — 記錄請求開始時間。
  • onFirstChunk() — 記錄 TTFT。
  • onChunk(n) — 累計完成權杖數。
  • finish(usage?) — 計算最終指標:ttftMs、totalMs、tps、tokensIn、tokensOut、costUsd。
  • 定價來自 src/lib/playground/types.ts 中的靜態表格(標示為「預估」— D13)。

方法 路徑 處理程序
POST /api/playground/improve-prompt 使用 Zod 驗證 ImprovePromptRequestSchema;使用中繼提示呼叫 /v1/chat/completions
GET /api/playground/presets 傳回 { presets: PlaygroundPresetListItem[] }
POST /api/playground/presets 建立預設集;驗證 PlaygroundPresetCreateSchema
GET /api/playground/presets/:id 傳回單一預設集,若不存在則傳回 404
PUT /api/playground/presets/:id 部分更新
DELETE /api/playground/presets/:id 204

驗證:選用(REQUIRE_API_KEY)。錯誤透過 buildErrorBody() 處理(強制規則 #12)。


路徑 用途
src/app/(dashboard)/dashboard/playground/PlaygroundStudio.tsx 外殼元件、分頁協調器
src/app/(dashboard)/dashboard/playground/components/StudioTopBar.tsx 分頁 + 計數器 + 匯出按鈕
src/app/(dashboard)/dashboard/playground/components/StudioConfigPane.tsx 共用設定面板
src/app/(dashboard)/dashboard/playground/components/tabs/ChatTab.tsx 聊天工作台
src/app/(dashboard)/dashboard/playground/components/tabs/CompareTab.tsx 多模型比較
src/app/(dashboard)/dashboard/playground/components/tabs/ApiTab.tsx Monaco 編輯器(保留)
src/app/(dashboard)/dashboard/playground/components/tabs/BuildTab.tsx 工具 + 結構化輸出
src/app/(dashboard)/dashboard/playground/components/ExportCodeModal.tsx 程式碼匯出對話框
src/app/(dashboard)/dashboard/playground/components/CompareColumn.tsx 單一比較欄
src/app/(dashboard)/dashboard/playground/components/ProviderMetrics.tsx TTFT/TPS 顯示
src/app/(dashboard)/dashboard/playground/hooks/useStreamMetrics.ts 用戶端指標 Hook
src/app/(dashboard)/dashboard/playground/hooks/usePresets.ts 預設集 CRUD Hook
src/app/(dashboard)/dashboard/playground/hooks/useImprovePrompt.ts 改善提示詞 Hook
src/lib/playground/codeExport.ts curl/Python/TS 產生器(與搜尋工具共用)
src/lib/playground/promptImprover.ts 元提示詞建構器
src/lib/playground/streamMetrics.ts 純指標運算
src/lib/db/playgroundPresets.ts 資料庫模組(CRUD)
src/app/api/playground/improve-prompt/route.ts 改善提示詞 REST 路由
src/app/api/playground/presets/route.ts 預設集清單 + 建立
src/app/api/playground/presets/[id]/route.ts 取得/更新/刪除預設集
src/lib/db/migrations/084_playground_presets.sql 資料庫遷移

症狀 原因 修正方式
Monaco 編輯器未顯示於 API 分頁中 SSR 載入了 Monaco 確認 ApiTab 使用 dynamic(..., { ssr: false })
比較串流依序啟動 Promise.all 使用方式錯誤 所有串流啟動作業都必須在單一 Promise.all 呼叫中分派
指標顯示 null TTFT 未連接第一個區塊處理常式 檢查 SSE 讀取器迴圈中是否呼叫了 useStreamMetrics.onFirstChunk()
預設集未持續保存 未執行資料庫遷移 執行 npm run db:migrate 或重新啟動伺服器(遷移會在啟動時自動執行)
改善提示詞時傳回 502 Config 中未設定模型 使用者必須先在 Config 窗格中輸入模型名稱,才能進行改善
匯出的程式碼顯示 MISSING_API_KEY 未插入預留位置 codeExport.ts 一律使用 API_KEY_PLACEHOLDER = "$OMNIROUTE_API_KEY"

  • 總體計畫:_tasks/features-v3.8.6/refactorpages/_orchestration/master-plan-group-C.md
  • 功能計畫:_tasks/features-v3.8.6/refactorpages/17-playground-studio-redesign.plan.md
  • 程式碼匯出:src/lib/playground/codeExport.ts
  • 提示詞改善器:src/lib/playground/promptImprover.ts
  • Search Tools Studio:docs/frameworks/SEARCH_TOOLS_STUDIO.md

OmniRoute 原始碼 (a58000c7685f)

HagiCode

HagiCode 是智慧代理程式開發工作台,結合結構化工作流程、多代理程式執行與 Hero Dungeon 介面,將想法化為交付成果。

以更聰明、更快速且更有趣的智慧代理程式工作流程,打造實用的軟體。

HagiCode 淺色主題介面畫面
  • Smart結構化流程將意圖轉化為從構想到交付的可執行步驟。
  • Efficient多代理程式工作流程讓研究、實作與審查並行進行。
  • FunHero Dungeon 讓長時間的程式協作更直覺、更有參與感。
造訪 HagiCode