"""Chosun proofreading demo — Gradio UI. Tabs: - v24 (new): solar-pro3 with FT + self-consistency × 2 + tool-calling judge. paragraph F1 47.04 (vs solar-pro2 prod_251231 mean 44.86). - 제목 교열 (sandbox): solar-pro2 vs solar-pro3 side-by-side comparison for newspaper title proofreading (default prompt hidden in UI). """ import os import gradio as gr from dotenv import load_dotenv from openai import OpenAI from pipelines import list_prompts from postprocess import load_vocabulary from blindtest import build_feedback_tab from title_proofread import build_title_proofread_tab load_dotenv() _api_key = os.getenv("UPSTAGE_API_KEY", "") client = OpenAI(api_key=_api_key, base_url="https://api.upstage.ai/v1") if _api_key else None _vocab_path = os.path.join(os.path.dirname(__file__), "data", "vocabulary.csv") vocabulary = load_vocabulary(_vocab_path) prompt_choices = list_prompts() or ["dev_260429_v24"] def _default_prompt(preferred_prefix: str, fallback: str) -> str: matches = [p for p in prompt_choices if p.startswith(preferred_prefix)] if matches: return matches[-1] return fallback _v24_prompt = _default_prompt("dev_260429_v24", "dev_260429_v24") with gr.Blocks(title="Chosun 교정교열 데모") as demo: gr.Markdown("# Chosun 교정교열 데모") with gr.Tabs(): with gr.Tab("v24 (new · 260429)"): build_feedback_tab( client=client, vocabulary=vocabulary, pipeline_config=("260429_v24", "solar-pro3", _v24_prompt), elem_id_prefix="v24", ) with gr.Tab("제목 교열 (sandbox)"): build_title_proofread_tab(client=client) _SHORTCUT_JS = """ () => { if (window.__chosunShortcutBound) return; window.__chosunShortcutBound = true; // Capture phase so Code-editor (Monaco) doesn't swallow the keystroke. document.addEventListener('keydown', (e) => { if (!((e.metaKey || e.ctrlKey) && e.key === 'Enter')) return; // Pick the run button on the *visible* tab (others' buttons are hidden). const ids = ['title-proofread-run-btn', 'v24-run-btn']; for (const id of ids) { const root = document.getElementById(id); if (!root) continue; if (root.offsetParent === null) continue; // hidden (different tab) const btn = root.querySelector('button') || root; e.preventDefault(); e.stopPropagation(); btn.click(); return; } }, true); } """ demo.load(None, None, None, js=_SHORTCUT_JS) if __name__ == "__main__": import uvicorn from fastapi import FastAPI app = FastAPI() @app.get("/ping") async def ping() -> dict: return {"status": "ok"} app = gr.mount_gradio_app(app, demo, path="/") uvicorn.run(app, host="0.0.0.0", port=7860)