File size: 2,913 Bytes
c421c84
61d7017
f338c84
d518386
 
f338c84
 
61d7017
 
 
 
 
 
 
c421c84
61d7017
 
c421c84
f338c84
61d7017
 
 
 
 
 
 
 
 
 
7cd2a55
61d7017
 
c421c84
61d7017
 
 
c421c84
61d7017
 
d518386
61d7017
 
 
 
d518386
43bd06b
d518386
 
 
43bd06b
 
d518386
 
f338c84
 
 
61d7017
 
 
 
f338c84
61d7017
f338c84
 
7cd2a55
f338c84
 
 
 
 
61d7017
f338c84
 
 
61d7017
f338c84
61d7017
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
"""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)