awacke1 commited on
Commit
a0eb915
·
verified ·
1 Parent(s): a380d10

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +152 -0
app.py ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import gradio as gr
3
+ import openai as o
4
+ from threading import Thread
5
+
6
+ # 📜 CONFIG
7
+ UI_TITLE = "✨🧙‍♂️🔮"
8
+ KEY_FILE = "key.txt"
9
+ MODELS = {
10
+ "GPT-4o ✨": "gpt-4o",
11
+ "o3 🧠": "gpt-3.5-turbo", # Placeholder, o3 is not a public model name
12
+ "o4-mini 🚀": "gpt-4-turbo", # Placeholder, o4-mini is not a public model name
13
+ "GPT-4.5 🔬": "gpt-4-turbo", # Placeholder, gpt-4.5 is not a public model name
14
+ "GPT-4.1 💻": "gpt-4-turbo", # Placeholder, gpt-4.1 is not a public model name
15
+ "GPT-4.1-Mini ⚡": "gpt-4-turbo", # Placeholder, gpt-4.1-mini is not a public model name
16
+ }
17
+
18
+ # 🎨 STYLE
19
+ H1 = "# <font size='7'>{0}</font>"
20
+ H2 = "## <font size='6'>{0}</font>"
21
+ BTN_STYLE = "<font size='5'>{0}</font>"
22
+
23
+ # 🪄 HELPERS
24
+ def save_key(k: str) -> str:
25
+ "💾🔑"
26
+ if not k or not k.strip(): return "🚫 Empty Key"
27
+ with open(KEY_FILE, "w") as f: f.write(k.strip())
28
+ return "🔑✅"
29
+
30
+ def get_key(k: str) -> str:
31
+ "📜🔑"
32
+ k = k.strip() if k and k.strip() else (open(KEY_FILE).read().strip() if os.path.exists(KEY_FILE) else os.getenv("OPENAI_KEY", ""))
33
+ if not k: raise gr.Error("❗🔑 Missing OpenAI Key!")
34
+ o.api_key = k
35
+ return k
36
+
37
+ def summon_oracle(model_name: str, scribe_key: str, quest: str, scroll: list):
38
+ """
39
+ A pact with a chosen Oracle of OpenAI.
40
+ To seek its counsel, one must present a worthy key (scribe_key),
41
+ a quest (quest), and the Oracle's own name (model_name)
42
+ upon the ancient scroll (scroll) of dialogue.
43
+ """
44
+ get_key(scribe_key) # Present the key to the sanctum's guardian.
45
+
46
+ # Transcribe the history onto a celestial scroll for the Oracle to read.
47
+ celestial_scroll = [
48
+ {"role": "user", "content": user_words}
49
+ for user_words, _ in scroll
50
+ ] + [
51
+ {"role": "assistant", "content": oracle_words}
52
+ for _, oracle_words in scroll
53
+ ]
54
+ celestial_scroll.append({"role": "user", "content": quest})
55
+
56
+ # The Oracle whispers its response from the aether.
57
+ try:
58
+ prophecy = o.chat.completions.create(model=model_name, messages=celestial_scroll, stream=True)
59
+
60
+ # The new wisdom is recorded as it is spoken.
61
+ scroll.append((quest, ""))
62
+ for chunk in prophecy:
63
+ if chunk.choices[0].delta.content:
64
+ scroll[-1] = (quest, scroll[-1][1] + chunk.choices[0].delta.content)
65
+ yield scroll
66
+ except Exception as e:
67
+ scroll.append((quest, f"🧙‍♂️🔮 A magical disturbance occurred: {str(e)}"))
68
+ yield scroll
69
+
70
+
71
+ def manage_portals(selected_models: list):
72
+ """
73
+ Reveals or conceals the portals to the chosen Oracles.
74
+ """
75
+ updates = []
76
+ for model_display_name in MODELS.keys():
77
+ if model_display_name in selected_models:
78
+ updates.append(gr.update(visible=True))
79
+ else:
80
+ updates.append(gr.update(visible=False))
81
+ return updates
82
+
83
+ # 🔮 UI
84
+ with gr.Blocks(title=UI_TITLE, theme=gr.themes.Soft(primary_hue="red", secondary_hue="orange")) as demo:
85
+ gr.Markdown(H1.format(UI_TITLE))
86
+
87
+ # --- API Key Rune ---
88
+ with gr.Accordion("🔑 Eldritch Key", open=False):
89
+ with gr.Row():
90
+ api_key_box = gr.Textbox(
91
+ label="🔑",
92
+ type="password",
93
+ placeholder="sk-...",
94
+ value=get_key("") if os.path.exists(KEY_FILE) else os.getenv("OPENAI_KEY", ""),
95
+ scale=3
96
+ )
97
+ save_btn = gr.Button("💾", scale=1)
98
+ status_txt = gr.Textbox(interactive=False, scale=1, label="Status")
99
+ save_btn.click(save_key, inputs=api_key_box, outputs=status_txt)
100
+
101
+ # --- Oracle Selection ---
102
+ gr.Markdown(H2.format("🔮 Select Oracles"))
103
+ model_selector = gr.CheckboxGroup(choices=list(MODELS.keys()), label="Oracles", value=["GPT-4o ✨"])
104
+
105
+ # --- Portals to Oracles ---
106
+ gr.Markdown(H2.format("🌀 Portals"))
107
+
108
+ model_blocks = []
109
+ for display_name, api_name in MODELS.items():
110
+ # A block for each model, initially hidden unless selected by default
111
+ is_visible = display_name in model_selector.value
112
+ with gr.Blocks(visible=is_visible) as model_block:
113
+ gr.Markdown(f"### <font size='5'>{display_name}</font>")
114
+ chatbot = gr.Chatbot(height=350, label=f"Scroll of {display_name}")
115
+ with gr.Row():
116
+ run_btn = gr.Button(value=BTN_STYLE.format("▶️ Run"), variant="primary", scale=1)
117
+ stop_btn = gr.Button(value=BTN_STYLE.format("⏹️ Stop"), variant="stop", scale=1)
118
+
119
+ # Each run button triggers its own oracle
120
+ # The `_js` param is a trick to pass the model's API name to the Python function
121
+ run_event = run_btn.click(
122
+ fn=summon_oracle,
123
+ inputs=[gr.State(api_name), api_key_box, chatbot.i_am_a_dummy_component_for_the_event_to_work, chatbot],
124
+ outputs=[chatbot]
125
+ )
126
+ stop_btn.click(fn=None, inputs=None, outputs=None, cancels=[run_event])
127
+ model_blocks.append(model_block)
128
+
129
+ # --- Global Quest Input ---
130
+ gr.Markdown(H2.format("📜 Global Quest"))
131
+ global_msg_box = gr.Textbox(placeholder="❓ Pose your question to all active portals...", scale=3, lines=3)
132
+
133
+ # Link the global message box to all chatbot text inputs
134
+ # This uses a bit of Gradio event magic to update the hidden textboxes
135
+ for block in demo.blocks.values():
136
+ if isinstance(block, gr.Blocks) and block.visible:
137
+ for elem in block.children:
138
+ if isinstance(elem, gr.Chatbot):
139
+ global_msg_box.submit(lambda x: x, inputs=[global_msg_box], outputs=[elem.i_am_a_dummy_component_for_the_event_to_work])
140
+
141
+
142
+ # --- Event Listeners ---
143
+ model_selector.change(
144
+ fn=manage_portals,
145
+ inputs=[model_selector],
146
+ outputs=model_blocks
147
+ )
148
+
149
+ if __name__ == "__main__":
150
+ # Add a dummy attribute to Chatbot to make the global message box work
151
+ gr.Chatbot.i_am_a_dummy_component_for_the_event_to_work = gr.Textbox(visible=False)
152
+ demo.launch(share=True)