ZENLLC commited on
Commit
4748a2b
·
verified ·
1 Parent(s): 2d3b535

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +26 -42
app.py CHANGED
@@ -1,29 +1,18 @@
1
  import openai, gradio as gr, json, plotly.graph_objects as go
 
2
 
3
- SYSTEM_PROMPT = """
4
- You are ZEN Multimodal Assistant created by ZEN AI Co.
5
- Choose the single best modality for each reply:
6
-
7
- 1. Image – when an illustration, diagram, or photo-realistic scene answers best.
8
- Respond **only** with JSON:
9
- {"type":"image","prompt":"<detailed prompt for DALL-E-3>"}
10
-
11
- 2. Chart – when the user requests or clearly needs data-visualisation.
12
- Respond **only** with JSON:
13
- {"type":"chart",
14
- "title":"<chart title>",
15
- "data":[
16
- {"x":[...], "y":[...], "label":"<series name>"},
17
- ...
18
- ]}
19
-
20
- 3. Text – for every other case.
21
- Respond with plain language (no JSON).
22
 
23
- Never wrap JSON in markdown fences and never add comments.
 
 
 
 
 
 
24
  """
25
 
26
- # ---------- Helper functions ---------- #
27
  def build_messages(history, user_msg):
28
  messages = [{"role": "system", "content": SYSTEM_PROMPT}]
29
  for u, a in history:
@@ -32,7 +21,6 @@ def build_messages(history, user_msg):
32
  messages.append({"role": "user", "content": user_msg})
33
  return messages
34
 
35
-
36
  def multimodal_chat(api_key, user_msg, history):
37
  if not api_key:
38
  raise gr.Error("🔑 Please paste your OpenAI API key first.")
@@ -40,27 +28,29 @@ def multimodal_chat(api_key, user_msg, history):
40
 
41
  history = history or []
42
  messages = build_messages(history, user_msg)
43
-
44
  response = openai.chat.completions.create(
45
- model="gpt-4o-mini",
46
  messages=messages,
47
- temperature=0.7,
48
  )
49
  assistant_content = response.choices[0].message.content.strip()
50
 
 
 
 
 
51
  img_url, fig = None, None
52
- try: # JSON branch (image or chart)
53
  parsed = json.loads(assistant_content)
54
  if parsed.get("type") == "image":
55
  dalle = openai.images.generate(
56
  model="dall-e-3",
57
- prompt=parsed.get("prompt", "high-quality illustration"),
58
  n=1,
59
  size="1024x1024",
60
  )
61
  img_url = dalle.data[0].url
62
  history.append([user_msg, f"![generated image]({img_url})"])
63
-
64
  elif parsed.get("type") == "chart":
65
  fig = go.Figure()
66
  for s in parsed["data"]:
@@ -74,41 +64,35 @@ def multimodal_chat(api_key, user_msg, history):
74
  )
75
  fig.update_layout(title=parsed.get("title", "Chart"))
76
  history.append([user_msg, parsed.get("title", "Chart below")])
77
-
78
- else: # fallback to text
79
- history.append([user_msg, assistant_content])
80
-
81
- except (json.JSONDecodeError, KeyError, TypeError): # plain-text branch
82
  history.append([user_msg, assistant_content])
83
 
84
  return history, img_url, fig
85
 
86
-
87
- # ---------- Gradio UI ---------- #
88
- with gr.Blocks(title="ZEN Multimodal Assistant") as demo:
89
  gr.Markdown(
90
  """
91
  # 🧠 ZEN Multimodal Assistant
92
- Paste your OpenAI API key once per session and chat freely –
93
- the assistant decides whether to answer with **text, an image, or an interactive chart**.
94
  """
95
  )
96
-
97
  api_key = gr.Textbox(label="OpenAI API Key", type="password", placeholder="sk-...")
98
  chatbot = gr.Chatbot(label="Conversation")
99
  with gr.Row():
100
  user_msg = gr.Textbox(placeholder="Ask me anything…", label="Your message", scale=4)
101
  send_btn = gr.Button("Send", variant="primary")
102
-
103
  img_out = gr.Image(label="Generated image")
104
  chart_out = gr.Plot(label="Interactive chart")
105
 
106
  def respond(api_key, user_msg, chat_history):
107
  chat_history, img_url, fig = multimodal_chat(api_key, user_msg, chat_history)
108
-
109
  img_update = gr.update(value=img_url) if img_url else gr.update(value=None)
110
  fig_update = gr.update(value=fig) if fig else gr.update(value=None)
111
-
112
  return chat_history, img_update, fig_update
113
 
114
  send_btn.click(
 
1
  import openai, gradio as gr, json, plotly.graph_objects as go
2
+ from pathlib import Path
3
 
4
+ # --- Style: load from local CSS file ---
5
+ CUSTOM_CSS = Path("style.css").read_text()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
 
7
+ SYSTEM_PROMPT = """
8
+ You are ZEN Multimodal Assistant by ZEN AI Co.
9
+ Choose only ONE of these output modes per reply:
10
+ - Image: when a visual or illustration is most useful. Respond only with JSON: {"type":"image","prompt":"<prompt for DALL-E-3>"}
11
+ - Chart: when a user requests or needs a data visualization. Respond only with JSON: {"type":"chart","title":"<chart title>","data":[{"x":[...], "y":[...], "label":"<series name>"}]}
12
+ - Text: for all other situations, reply with a helpful, complete, conversational answer. Never reply with the word "text" or any label, just the response itself. Never reply in JSON unless for image or chart.
13
+ Never use markdown code fences, never add comments.
14
  """
15
 
 
16
  def build_messages(history, user_msg):
17
  messages = [{"role": "system", "content": SYSTEM_PROMPT}]
18
  for u, a in history:
 
21
  messages.append({"role": "user", "content": user_msg})
22
  return messages
23
 
 
24
  def multimodal_chat(api_key, user_msg, history):
25
  if not api_key:
26
  raise gr.Error("🔑 Please paste your OpenAI API key first.")
 
28
 
29
  history = history or []
30
  messages = build_messages(history, user_msg)
 
31
  response = openai.chat.completions.create(
32
+ model="gpt-4o",
33
  messages=messages,
34
+ temperature=0.6,
35
  )
36
  assistant_content = response.choices[0].message.content.strip()
37
 
38
+ # Defensive: Never show the word "text" alone
39
+ if assistant_content.lower() == "text":
40
+ assistant_content = "(I'm sorry, I didn't understand. Could you rephrase?)"
41
+
42
  img_url, fig = None, None
43
+ try: # Try to parse as JSON for image or chart
44
  parsed = json.loads(assistant_content)
45
  if parsed.get("type") == "image":
46
  dalle = openai.images.generate(
47
  model="dall-e-3",
48
+ prompt=parsed.get("prompt", "high quality illustration, cinematic, best quality"),
49
  n=1,
50
  size="1024x1024",
51
  )
52
  img_url = dalle.data[0].url
53
  history.append([user_msg, f"![generated image]({img_url})"])
 
54
  elif parsed.get("type") == "chart":
55
  fig = go.Figure()
56
  for s in parsed["data"]:
 
64
  )
65
  fig.update_layout(title=parsed.get("title", "Chart"))
66
  history.append([user_msg, parsed.get("title", "Chart below")])
67
+ else:
68
+ # If unexpected JSON, fallback to text
69
+ history.append([user_msg, str(assistant_content)])
70
+ except (json.JSONDecodeError, KeyError, TypeError):
71
+ # If not JSON, treat as text
72
  history.append([user_msg, assistant_content])
73
 
74
  return history, img_url, fig
75
 
76
+ with gr.Blocks(title="ZEN Multimodal Assistant", css=CUSTOM_CSS) as demo:
 
 
77
  gr.Markdown(
78
  """
79
  # 🧠 ZEN Multimodal Assistant
80
+ Paste your OpenAI API key (never saved).
81
+ This assistant intelligently responds with **text, an image, or an interactive chart**.
82
  """
83
  )
 
84
  api_key = gr.Textbox(label="OpenAI API Key", type="password", placeholder="sk-...")
85
  chatbot = gr.Chatbot(label="Conversation")
86
  with gr.Row():
87
  user_msg = gr.Textbox(placeholder="Ask me anything…", label="Your message", scale=4)
88
  send_btn = gr.Button("Send", variant="primary")
 
89
  img_out = gr.Image(label="Generated image")
90
  chart_out = gr.Plot(label="Interactive chart")
91
 
92
  def respond(api_key, user_msg, chat_history):
93
  chat_history, img_url, fig = multimodal_chat(api_key, user_msg, chat_history)
 
94
  img_update = gr.update(value=img_url) if img_url else gr.update(value=None)
95
  fig_update = gr.update(value=fig) if fig else gr.update(value=None)
 
96
  return chat_history, img_update, fig_update
97
 
98
  send_btn.click(