콘텐츠로 이동
OmniRoute source

Playground Studio (한국어)

Playground Studio는 /dashboard/playground를 단순한 Monaco 기반 편집기에서 모든 기능을 갖춘 테스트 워크스페이스로 전환합니다. 기존 page.tsx를 네 개의 탭과 공유 구성 창을 렌더링하는 PlaygroundStudio 셸로 대체합니다.

┌ Playground ──────────────────────────────────────────────────────────┐
│ [💬 채팅] [⚖ 비교] [{} API] [🔧 빌드] 142↑ 38↓ · $0.002 </>│
├──────────────────────────────────────────┬───────────────────────────┤
│ {활성 탭 콘텐츠} │ ─ 구성 │
│ │ 엔드포인트 [chat ∨] │
│ │ 모델 [gpt-5.4 ∨] │
│ │ 시스템 [텍스트 영역] │
│ │ 온도 ▕▕▔▔ 0.7 │
│ │ 프리셋 [▾ 불러오기][저장] │
│ │ [✨ 프롬프트 개선] │
└──────────────────────────────────────────┴───────────────────────────┘

ChatPlayground.tsx를 멀티턴 스트리밍 워크벤치로 발전시킵니다.

  • MarkdownMessage.tsx를 통한 완전한 마크다운 렌더링(코드 블록, 표, 목록, 링크).
  • 공유 구성 창에서 시스템 프롬프트를 가져옵니다.
  • 메시지별 토큰/비용(프롬프트 + 완성 토큰).
  • 마지막 응답 다시 생성.
  • SSE 스트리밍을 사용하여 POST /v1/chat/completions로 전송합니다.

프록시의 핵심 차별점: 하나의 프롬프트를 최대 4개 모델에서 병렬로 실행합니다.

  • 최대 4개의 열에서 각각 /v1/chat/completions의 응답을 독립적으로 스트리밍합니다.
  • 열을 추가하는 + 모델 추가 버튼(Cmd+K 단축키).
  • 모두 실행 ▶은 Promise.all과 열별 AbortController를 통해 모든 스트림을 동시에 시작합니다.
  • 전역 모두 취소는 진행 중인 모든 스트림을 중단합니다.
  • 열별 ProviderMetrics는 TTFT, TPS, 토큰 및 예상 비용을 실시간으로 표시합니다.
  • 메트릭에는 “클라이언트 측 추정치”(D12)라는 레이블이 지정되며, 첫 번째 SSE 청크부터 측정됩니다.

고급 사용자를 위해 기존 Monaco 편집기의 기능을 100% 유지합니다(D14).

  • 10개 엔드포인트: 채팅 완성, 완성, 임베딩, 이미지, 오디오, 음성, 전사, 조정, 재순위 지정, 검색.
  • 멀티모달 파일 업로드.
  • 실시간 출력을 지원하는 SSE 스트리밍.
  • ApiTab.tsx로 래핑됩니다(지연 로드, ssr: false).

도구/함수 호출 및 구조화된 출력 UI:

  • ToolsBuilder.tsx — 도구별 JSON 스키마 편집기를 사용하여 tools[]를 추가/편집/제거합니다. ToolDefinitionSchema(Zod)를 통해 매개변수를 검증합니다.
  • StructuredOutputEditor.tsx — JSON 모드 및 JSON 스키마 편집기를 전환합니다. 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의 정적 테이블에서 가져옵니다(“estimated”로 표시 — D13).

메서드 경로 핸들러
POST /api/playground/improve-prompt ImprovePromptRequestSchema으로 Zod 검증 후 메타 프롬프트와 함께 /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 클라이언트 측 메트릭 훅
src/app/(dashboard)/dashboard/playground/hooks/usePresets.ts 프리셋 CRUD 훅
src/app/(dashboard)/dashboard/playground/hooks/useImprovePrompt.ts 프롬프트 개선 훅
src/lib/playground/codeExport.ts curl/Python/TS 생성기(Search Tools와 공유)
src/lib/playground/promptImprover.ts 메타 프롬프트 빌더
src/lib/playground/streamMetrics.ts 순수 메트릭 계산
src/lib/db/playgroundPresets.ts DB 모듈(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 DB 마이그레이션

증상 원인 해결 방법
API 탭에서 Monaco 편집기가 렌더링되지 않음 SSR에서 Monaco를 로드함 ApiTab이 dynamic(..., { ssr: false })를 사용하는지 확인
비교 스트림이 순차적으로 실행됨 잘못된 Promise.all 사용 모든 스트림 시작 작업을 하나의 Promise.all 호출에서 디스패치해야 함
메트릭에 null TTFT가 표시됨 첫 번째 청크 핸들러가 연결되지 않음 SSE 리더 루프에서 useStreamMetrics.onFirstChunk()가 호출되는지 확인
프리셋이 유지되지 않음 DB 마이그레이션이 실행되지 않음 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 방문