omarash2016 commited on
Commit
8ba18ce
·
verified ·
1 Parent(s): 192ec5b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +174 -79
app.py CHANGED
@@ -20,9 +20,13 @@ nebius_client = OpenAI(
20
  base_url=NEBIUS_BASE_URL,
21
  )
22
 
23
- # --- 2. DEFINE TOOL FUNCTIONS (Standard Python) ---
 
 
24
 
25
- def web_search(query: str):
 
 
26
  """
27
  Performs a market research search using DuckDuckGo.
28
  """
@@ -36,7 +40,7 @@ def web_search(query: str):
36
  except Exception as e:
37
  return f"Search Error: {str(e)}"
38
 
39
- def generate_image(prompt: str):
40
  """
41
  Generates an image and returns the local file path.
42
  """
@@ -48,6 +52,7 @@ def generate_image(prompt: str):
48
  n=1,
49
  size="1024x1024",
50
  response_format="b64_json",
 
51
  )
52
  b64_data = response.data[0].b64_json
53
  image_bytes = base64.b64decode(b64_data)
@@ -58,102 +63,192 @@ def generate_image(prompt: str):
58
  img.save(filename)
59
  return filename
60
  except Exception as e:
61
- return None # Return None on error for image components
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
 
63
- # --- 3. INTERNAL AGENT LOGIC ---
64
 
65
  def run_autonomous_agent(company_name, business_type, style, progress=gr.Progress()):
66
- log = f"🚀 Agent Started for '{company_name}'\n"
67
 
68
- # 1. Planning
69
- progress(0.1, desc="Step 1: Planning...")
70
- plan_prompt = f"Create a 5-color palette for '{company_name}' ({business_type}), style: {style}. Return hex codes."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  try:
72
- resp = nebius_client.chat.completions.create(
73
- messages=[{"role":"user", "content":plan_prompt}], model=TEXT_MODEL
 
 
74
  )
75
- palette = resp.choices[0].message.content
76
- log += f"🎨 Palette: {palette}\n"
 
 
77
  except Exception as e:
78
- palette = "Blue, White"
79
- log += f"⚠️ Planning Error: {e}\n"
80
-
81
- # 2. Generate Logo (Direct Call)
82
- progress(0.3, desc="Step 2: Logo...")
83
- logo_path = generate_image(f"Minimalist logo for {company_name}, colors: {palette}. White background.")
84
- log += "🖼️ Logo Created.\n"
85
-
86
- # 3. Research (Direct Call)
87
- progress(0.6, desc="Step 3: Research...")
88
- research = web_search(f"marketing trends {business_type} 2025")
89
- log += f"📊 Research: {research[:50]}...\n"
90
-
91
- # 4. Copywriting
92
- progress(0.8, desc="Step 4: Copywriting...")
93
- copy_prompt = f"Write a tweet for {company_name} based on: {research}"
94
- try:
95
- resp = nebius_client.chat.completions.create(
96
- messages=[{"role":"user", "content":copy_prompt}], model=TEXT_MODEL
97
- )
98
- copy = resp.choices[0].message.content
99
- except:
100
- copy = "Error generating copy."
101
-
102
- log += "✅ Done."
103
- return logo_path, copy, log
104
 
105
- # --- 4. UI & MCP REGISTRATION ---
106
 
107
- with gr.Blocks(title="AutoBrand MCP") as demo:
108
- gr.Markdown("# 🚀 AutoBrand Agent + MCP Server")
109
 
110
- # --- VISIBLE UI ---
 
 
 
111
  with gr.Row():
112
- with gr.Column():
113
- c_input = gr.Textbox(label="Company Name", value="Lumina")
114
- t_input = gr.Textbox(label="Type", value="Candles")
115
- s_input = gr.Textbox(label="Style", value="Minimal")
116
- btn = gr.Button("Run Agent", variant="primary")
117
- log_box = gr.TextArea(label="Logs")
118
-
119
- with gr.Column():
120
- out_img = gr.Image(label="Logo", type="filepath")
121
- out_txt = gr.TextArea(label="Social Copy")
122
-
123
- # Connect the UI Agent
124
- btn.click(
125
- run_autonomous_agent,
126
- [c_input, t_input, s_input],
127
- [out_img, out_txt, log_box]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
  )
 
 
129
 
130
  # --- HIDDEN MCP TOOL REGISTRATION ---
131
- # To expose functions to MCP, we attach them to hidden triggers with `api_name`.
132
- # This tells Gradio: "These are API endpoints" -> which enables MCP.
133
-
134
  with gr.Row(visible=False):
135
  # Tool 1: Web Search
136
- search_input = gr.Textbox()
137
- search_output = gr.Textbox()
138
- search_btn = gr.Button("Search Tool")
139
- search_btn.click(
140
- web_search,
141
- inputs=search_input,
142
- outputs=search_output,
143
- api_name="web_search" # <--- THIS MAKES IT AN MCP TOOL
144
  )
145
 
146
  # Tool 2: Image Gen
147
- img_input = gr.Textbox()
148
- img_output = gr.Image(type="filepath")
149
- img_btn = gr.Button("Image Tool")
150
- img_btn.click(
151
- generate_image,
152
- inputs=img_input,
153
- outputs=img_output,
154
- api_name="generate_image" # <--- THIS MAKES IT AN MCP TOOL
155
  )
156
 
157
  if __name__ == "__main__":
158
- # Launch with mcp_server=True
159
  demo.launch(ssr_mode=False, mcp_server=True)
 
20
  base_url=NEBIUS_BASE_URL,
21
  )
22
 
23
+ # Helper to convert bytes to PIL
24
+ def bytes_to_pil(image_bytes: bytes):
25
+ return Image.open(io.BytesIO(image_bytes))
26
 
27
+ # --- 2. DEFINE TOOLS (Used by Agent AND exposed to MCP) ---
28
+
29
+ def tool_web_search(query: str):
30
  """
31
  Performs a market research search using DuckDuckGo.
32
  """
 
40
  except Exception as e:
41
  return f"Search Error: {str(e)}"
42
 
43
+ def tool_generate_image(prompt: str):
44
  """
45
  Generates an image and returns the local file path.
46
  """
 
52
  n=1,
53
  size="1024x1024",
54
  response_format="b64_json",
55
+ style="flat",
56
  )
57
  b64_data = response.data[0].b64_json
58
  image_bytes = base64.b64decode(b64_data)
 
63
  img.save(filename)
64
  return filename
65
  except Exception as e:
66
+ print(f"❌ Image Tool Error: {e}")
67
+ return None
68
+
69
+ # Text generation helper (Internal only, usually not exposed as MCP tool directly)
70
+ def tool_generate_text(prompt: str, system_message: str = "You are a helpful assistant.") -> str:
71
+ try:
72
+ response = nebius_client.chat.completions.create(
73
+ messages=[
74
+ {"role": "system", "content": system_message},
75
+ {"role": "user", "content": prompt},
76
+ ],
77
+ model=TEXT_MODEL,
78
+ max_tokens=1024,
79
+ temperature=0.7,
80
+ )
81
+ return response.choices[0].message.content
82
+ except Exception as e:
83
+ return f"Error: {e}"
84
 
85
+ # --- 3. AGENT LOGIC ---
86
 
87
  def run_autonomous_agent(company_name, business_type, style, progress=gr.Progress()):
88
+ """Autonomous branding agent logic."""
89
 
90
+ # PHASE 1: PLANNING
91
+ progress(0.1, desc="Step 1: Planning & Color Palette...")
92
+ color_prompt = (
93
+ f"Create a distinct, 5-color palette for a {business_type} named '{company_name}' "
94
+ f"with a {style} style. Return ONLY a comma-separated list of hex codes."
95
+ )
96
+ colors_text = tool_generate_text(
97
+ color_prompt, "You are a design expert. Output only the requested list."
98
+ ).strip().strip('.')
99
+
100
+ log = f"✅ Plan Started for {company_name}\n"
101
+ log += f"🎨 Palette Decided: {colors_text}\n"
102
+
103
+ # PHASE 2: LOGO
104
+ progress(0.3, desc="Step 2: Generating Logo...")
105
+ logo_prompt = (
106
+ f"A professional, minimalist logo for a {business_type} named '{company_name}'. "
107
+ f"Use ONLY these colors: {colors_text}. Vector flat style, centered, no text, no Transparent background."
108
+ )
109
+ logo_path = tool_generate_image(logo_prompt)
110
+ log += "🖼️ Logo Generated.\n"
111
+
112
+ # PHASE 3: ASSET
113
+ progress(0.5, desc="Step 3: Generating Brand Guide...")
114
+ asset_prompt = (
115
+ f"A professional color palette guide with 5 circular swatches, arranged in a row. "
116
+ f"Use these colors: {colors_text}. Minimalist white background."
117
+ )
118
+ asset_path = tool_generate_image(asset_prompt)
119
+ log += "🖼️ Brand Asset Generated.\n"
120
+
121
+ # PHASE 4: SEARCH
122
+ progress(0.7, desc="Step 4: Researching Market Trends...")
123
+ search_query = f"marketing trends for {business_type} 2025"
124
+ search_data = tool_web_search(search_query)
125
+ log += f"🔍 Search Query: {search_query}\n"
126
+ log += f"📊 Research: {search_data[:100]}...\n"
127
+
128
+ # PHASE 5: COPY
129
+ progress(0.9, desc="Step 5: Writing Content...")
130
+ copy_prompt = f"""
131
+ Write 3 engaging Twitter/X posts for a new {business_type} called '{company_name}'.
132
+ Tone: {style}.
133
+ Use these market insights if helpful:
134
+ {search_data}
135
+ """
136
+ social_copy = tool_generate_text(copy_prompt, "You are a professional social media manager.")
137
+ log += "✍️ Social Copy Written.\n✅ Execution Complete."
138
+
139
+ return logo_path, asset_path, social_copy, log
140
+
141
+ # --- 4. CHATBOT LOGIC ---
142
+
143
+ def chat_response(message, history):
144
+ system_message = "You are a creative brand consultant."
145
+ messages = [{"role": "system", "content": system_message}]
146
+ for msg in history:
147
+ messages.append({"role": msg["role"], "content": msg["content"]})
148
+ messages.append({"role": "user", "content": message})
149
+
150
  try:
151
+ response = nebius_client.chat.completions.create(
152
+ messages=messages,
153
+ model=TEXT_MODEL,
154
+ max_tokens=300,
155
  )
156
+ bot_reply = response.choices[0].message.content
157
+ history.append({"role": "user", "content": message})
158
+ history.append({"role": "assistant", "content": bot_reply})
159
+ return history, ""
160
  except Exception as e:
161
+ history.append({"role": "assistant", "content": f"Error: {e}"})
162
+ return history, ""
163
+
164
+ # --- 5. UI CONSTRUCTION ---
165
+
166
+ theme = gr.themes.Soft(
167
+ primary_hue="indigo",
168
+ secondary_hue="blue",
169
+ neutral_hue="slate",
170
+ ).set(
171
+ button_primary_background_fill="linear-gradient(90deg, #6366f1 0%, #4338ca 100%)",
172
+ button_primary_background_fill_hover="linear-gradient(90deg, #4f46e5 0%, #3730a3 100%)",
173
+ button_primary_text_color="white",
174
+ block_title_text_weight="600",
175
+ block_shadow="0 4px 6px rgba(0,0,0,0.1)",
176
+ )
 
 
 
 
 
 
 
 
 
 
177
 
178
+ custom_css = """#main-header {text-align: center; margin-bottom: 2rem;}"""
179
 
180
+ with gr.Blocks(theme=theme, css=custom_css, title="AutoBrand MCP Studio") as demo:
 
181
 
182
+ with gr.Column(elem_id="main-header"):
183
+ gr.Markdown("# 🖼️ AutoBrand Studio (MCP Enabled)")
184
+ gr.Markdown("Autonomous Agent powered by AI Models & Web Search. Connect Claude Desktop to use these tools!")
185
+
186
  with gr.Row():
187
+ # LEFT PANE
188
+ with gr.Column(scale=1):
189
+ gr.Markdown("### 🚀 Brand Configuration")
190
+ company_input = gr.Textbox(label="Company Name", value="Lumina")
191
+ type_input = gr.Textbox(label="Business Type", value="Organic Candle Shop")
192
+ style_input = gr.Textbox(label="Style / Vibe", value="Minimalist, calming")
193
+
194
+ generate_btn = gr.Button("✨ Generate Brand Kit", variant="primary")
195
+
196
+ gr.Markdown("### ⚙️ System Logs")
197
+ out_log = gr.TextArea(label="Agent Log", lines=15, show_copy_button=True)
198
+
199
+ # RIGHT PANE
200
+ with gr.Column(scale=2):
201
+ with gr.Tabs():
202
+ with gr.TabItem("🎨 Brand Identity"):
203
+ with gr.Row():
204
+ out_logo = gr.Image(label="Logo Concept", height=350, type="filepath")
205
+ out_asset = gr.Image(label="Color Palette", height=350, type="filepath")
206
+
207
+ out_copy = gr.TextArea(
208
+ label="Generated Social Content",
209
+ lines=15,
210
+ show_copy_button=True,
211
+ interactive=False,
212
+ )
213
+
214
+ with gr.TabItem("💬 Brand Consultant"):
215
+ chatbot = gr.Chatbot(label="AI Consultant", height=650, type="messages")
216
+ chat_input = gr.Textbox(show_label=False, placeholder="Ask something...")
217
+ chat_btn = gr.Button("Send")
218
+
219
+ # --- AGENT & CHATBOT HANDLERS ---
220
+ generate_btn.click(
221
+ run_autonomous_agent,
222
+ [company_input, type_input, style_input],
223
+ [out_logo, out_asset, out_copy, out_log]
224
  )
225
+ chat_btn.click(chat_response, [chat_input, chatbot], [chatbot, chat_input])
226
+ chat_input.submit(chat_response, [chat_input, chatbot], [chatbot, chat_input])
227
 
228
  # --- HIDDEN MCP TOOL REGISTRATION ---
229
+ # This section registers the functions as MCP tools without showing them in the UI.
 
 
230
  with gr.Row(visible=False):
231
  # Tool 1: Web Search
232
+ search_in = gr.Textbox()
233
+ search_out = gr.Textbox()
234
+ btn_search = gr.Button("Search Tool")
235
+ btn_search.click(
236
+ tool_web_search,
237
+ inputs=search_in,
238
+ outputs=search_out,
239
+ api_name="web_search" # Exposes tool to MCP
240
  )
241
 
242
  # Tool 2: Image Gen
243
+ img_in = gr.Textbox()
244
+ img_out = gr.Image(type="filepath")
245
+ btn_img = gr.Button("Image Tool")
246
+ btn_img.click(
247
+ tool_generate_image,
248
+ inputs=img_in,
249
+ outputs=img_out,
250
+ api_name="generate_image" # Exposes tool to MCP
251
  )
252
 
253
  if __name__ == "__main__":
 
254
  demo.launch(ssr_mode=False, mcp_server=True)