File size: 5,159 Bytes
2249ab6
bbb241c
39eaf79
 
 
bbb241c
 
 
 
 
 
 
 
 
ab2b369
bbb241c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2249ab6
 
 
 
39eaf79
 
2249ab6
 
 
 
ab2b369
bbb241c
2249ab6
 
ab2b369
 
2249ab6
 
bbb241c
2249ab6
 
ab2b369
bbb241c
 
 
 
 
 
 
 
 
 
 
 
 
 
1e828d1
bbb241c
 
ab2b369
bbb241c
2249ab6
 
 
 
 
 
ab2b369
bbb241c
 
ab2b369
bbb241c
 
 
 
 
 
 
 
 
2249ab6
bbb241c
2249ab6
bbb241c
 
 
 
 
2249ab6
 
ab2b369
2249ab6
bbb241c
2249ab6
 
 
 
 
 
ab2b369
2249ab6
 
 
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import gradio as gr

from modules.case_loader import load_case, run_case

# test case names (for dropdown display)
CASE_NAMES = [
    "폐곡μž₯μ—μ„œ NPC와 λŒ€ν™”ν•˜λŠ” μž₯λ©΄",
    "λ§ˆμ„ λŒ€μž₯μž₯이와 무기 μˆ˜λ¦¬μ— λŒ€ν•΄ λŒ€ν™”ν•˜λŠ” μž₯λ©΄",
    "μˆ²μ† μ€λ‘”μžμ™€ 희귀 μ•½μ΄ˆμ— λŒ€ν•΄ λŒ€ν™”ν•˜λŠ” μž₯λ©΄",
    "항ꡬ 관리관과 μΆœν•­ ν—ˆκ°€μ— λŒ€ν•΄ λŒ€ν™”ν•˜λŠ” μž₯λ©΄",
    "λ§ˆλ²•μ‚¬ κ²¬μŠ΅μƒκ³Ό κ³ λŒ€ μ£Όλ¬Έμ„œμ— λŒ€ν•΄ λŒ€ν™”ν•˜λŠ” μž₯λ©΄"
]

def format_case_info(case: dict) -> dict:
    """returns formatted case info for UI display"""
    inp = case["input"]
    tags = inp.get("tags", {})
    context_lines = [f"{h['role'].upper()}: {h['text']}" for h in inp.get("context", [])]

    return {
        "npc_id": inp.get("npc_id", ""),
        "npc_location": inp.get("npc_location", ""),
        "quest_stage": tags.get("quest_stage", ""),
        "relationship": tags.get("relationship", ""),
        "trust": tags.get("trust", ""),
        "npc_mood": tags.get("npc_mood", ""),
        "player_reputation": tags.get("player_reputation", ""),
        "style": tags.get("style", ""),
        "lore": inp.get("lore", ""),
        "description": inp.get("description", ""),
        "player_state": inp.get("player_state", {}),
        "context": "\n".join(context_lines),
        "player_utterance": inp.get("player_utterance", "")
    }

def build_ui():
    with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="purple")) as demo:
        gr.Markdown("""
        # πŸ‘Ύ CWIE Neural Engine
        Qwen 3B 기반 LoRA νŒŒμΈνŠœλ‹ λͺ¨λΈμ„ μ‚¬μš©ν•˜μ—¬ NPC λŒ€μ‚¬μƒμ„±, κ²Œμž„ μƒνƒœλ³€ν™” μ˜ˆμΈ‘λ“± 세계와 μƒν˜Έμž‘μš© ν•˜λŠ” 엔진을 μ‹€ν–‰ν•©λ‹ˆλ‹€.
        """)

        with gr.Row():
            gr.Button("πŸ“„ 상세 λ¬Έμ„œ 보기",
                      link="https://huggingface.co/spaces/m97j/neuro-engine/blob/main/README.md")
            gr.Button("πŸ’» Colab λ…ΈνŠΈλΆ μ—΄κΈ°",
                      link="https://colab.research.google.com/drive/1_-qH8kdoU2Jj58TdaSnswHex-BFefInq?usp=sharing#scrollTo=cFJGv8BJ8oPD")

        gr.Markdown("### 🎯 ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€ 기반 Demo")
        gr.Markdown("⚠️ μΆ”λ‘ μ—λŠ” 수 λΆ„ ~ μ΅œλŒ€ μˆ˜μ‹­ λΆ„ 정도 μ†Œμš”λ  수 μžˆμŠ΅λ‹ˆλ‹€. μž μ‹œλ§Œ κΈ°λ‹€λ €μ£Όμ„Έμš”.")

        with gr.Row():
            case_dropdown = gr.Dropdown(choices=CASE_NAMES, label="ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€ 선택", value=CASE_NAMES[0])
            load_btn = gr.Button("μΌ€μ΄μŠ€ 뢈러였기")

        # case info display
        with gr.Row():
            with gr.Column():
                npc_id = gr.Textbox(label="NPC ID", interactive=False)
                npc_loc = gr.Textbox(label="NPC Location", interactive=False)
                quest_stage = gr.Textbox(label="Quest Stage", interactive=False)
                relationship = gr.Textbox(label="Relationship", interactive=False)
                trust = gr.Textbox(label="Trust", interactive=False)
                npc_mood = gr.Textbox(label="NPC Mood", interactive=False)
                player_rep = gr.Textbox(label="Player Reputation", interactive=False)
                style = gr.Textbox(label="Style", interactive=False)

            with gr.Column():
                lore = gr.Textbox(label="Lore", lines=3, interactive=False)
                desc = gr.Textbox(label="Description", lines=3, interactive=False)
                player_state = gr.JSON(label="Player State")
                context = gr.Textbox(label="Context", lines=6, interactive=False)

        # Player Utterance
        player_input = gr.Textbox(label="Player Utterance", lines=2)

        run_btn = gr.Button("πŸš€ Run Inference", variant="primary")
        npc_resp = gr.Textbox(label="NPC Response")
        deltas = gr.JSON(label="Deltas")
        flags = gr.JSON(label="Flags Probabilities")

        # case loading function
        def on_load_case(name):
            idx = CASE_NAMES.index(name)
            case = load_case(idx)  
            info = format_case_info(case)
            return (
                info["npc_id"], info["npc_location"], info["quest_stage"],
                info["relationship"], info["trust"], info["npc_mood"],
                info["player_reputation"], info["style"], info["lore"],
                info["description"], info["player_state"], info["context"],
                info["player_utterance"]
            )

        load_btn.click(
            fn=on_load_case,
            inputs=[case_dropdown],
            outputs=[
                npc_id, npc_loc, quest_stage, relationship, trust,
                npc_mood, player_rep, style, lore, desc, player_state, context,
                player_input
            ]
        )

        # execute inference
        run_btn.click(
            fn=lambda name, utt: run_case(CASE_NAMES.index(name), utt),
            inputs=[case_dropdown, player_input],
            outputs=[npc_resp, deltas, flags]
        )

        gr.Markdown("""
        ---
        ⚠️ **μ‹€μ œ κ²Œμž„ νŒŒμ΄ν”„λΌμΈ ν…ŒμŠ€νŠΈ**λŠ” [symbolic-processor Swagger](https://huggingface.co/spaces/m97j/symbolic-processor)μ—μ„œ μ§„ν–‰ν•˜μ„Έμš”.
        """)

    return demo