File size: 10,756 Bytes
dd1ce4f 45b4b82 14c4133 dd1ce4f 9df9025 90fbefa 24b72a4 dd1ce4f 45b4b82 4e19813 9df9025 491d085 800b8f7 59cf03e 4e19813 24b72a4 dd1ce4f aa94a48 dd1ce4f 8ba18ce 90fbefa 5f00c4c aa94a48 8ba18ce aa94a48 dd1ce4f 24b72a4 192ec5b 24b72a4 dd1ce4f 24b72a4 9df9025 8ba18ce aa94a48 dd1ce4f 4e19813 9df9025 3e054a1 aa94a48 4e19813 9df9025 24b72a4 aa94a48 192ec5b 24b72a4 192ec5b 45b4b82 8ba18ce aa94a48 5f00c4c 8ba18ce 5f00c4c 8ba18ce 9df9025 aa94a48 0f09c47 aa94a48 0f09c47 aa94a48 0f09c47 aa94a48 0f09c47 5f00c4c 45b4b82 aa94a48 0f09c47 aa94a48 5f00c4c aa94a48 8ba18ce aa94a48 8ba18ce aa94a48 8ba18ce aa94a48 0f09c47 aa94a48 8ba18ce 0f09c47 8ba18ce aa94a48 0f09c47 8ba18ce 0f09c47 8ba18ce aa94a48 0f09c47 aa94a48 0f09c47 aa94a48 5f00c4c aa94a48 ec9aeda 5f00c4c 8ba18ce 5f00c4c 8ba18ce aa94a48 8ba18ce aa94a48 24b72a4 8ba18ce 24b72a4 8ba18ce 24b72a4 8ba18ce 99b5081 aa94a48 ec9aeda aa94a48 0f09c47 f168392 d8429ac aa94a48 437e63a aa94a48 8ba18ce dd1ce4f 0f09c47 8ba18ce aa94a48 8ba18ce aa94a48 8ba18ce 0f09c47 8ba18ce aa94a48 8ba18ce aa94a48 0f09c47 aa94a48 8ba18ce aa94a48 8ba18ce aa94a48 cac9495 aa94a48 cac9495 5f00c4c cac9495 8ba18ce 5f00c4c 8ba18ce ebdd354 a1cfc3e cac9495 8ba18ce 9df9025 aa94a48 192ec5b 8ba18ce 5f00c4c 192ec5b 8ba18ce 5f00c4c 0f09c47 5f00c4c cac9495 dd1ce4f acd31d7 | 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 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 | import gradio as gr
from openai import OpenAI
from ddgs import DDGS
import os
import base64
import io
from PIL import Image
# --- 1. CONFIGURATION ---
NEBIUS_API_KEY = os.environ.get("NEBIUS_API_KEY")
NEBIUS_BASE_URL = "https://api.studio.nebius.ai/v1/"
TEXT_MODEL = "meta-llama/Llama-3.3-70B-Instruct-fast"
IMAGE_MODEL = "black-forest-labs/flux-dev"
if not NEBIUS_API_KEY:
print("WARNING: NEBIUS_API_KEY environment variable is not set.")
nebius_client = OpenAI(
api_key=NEBIUS_API_KEY,
base_url=NEBIUS_BASE_URL,
)
# Helper to convert bytes to PIL
def bytes_to_pil(image_bytes: bytes):
return Image.open(io.BytesIO(image_bytes))
# --- 2. MCP TOOL FUNCTIONS ---
def tool_web_search(query: str):
"""Performs a market research search using DuckDuckGo."""
print(f"🔍 Search Tool: {query}...")
try:
results = DDGS().text(query, max_results=4)
if not results:
return "No specific market data found."
formatted_results = "\n".join([f"- {r.get('title')}: {r.get('body')}" for r in results])
return formatted_results
except Exception as e:
return f"Search Error: {str(e)}"
def tool_generate_image(prompt: str):
"""Generates an image and returns the local file path."""
print(f"🎨 Image Tool: {prompt[:40]}...")
try:
response = nebius_client.images.generate(
model=IMAGE_MODEL,
prompt=prompt,
n=1,
size="1024x1024",
response_format="b64_json",
style="flat",
)
b64_data = response.data[0].b64_json
image_bytes = base64.b64decode(b64_data)
img = Image.open(io.BytesIO(image_bytes))
filename = f"gen_{abs(hash(prompt))}.png"
img.save(filename)
return filename
except Exception as e:
print(f"❌ Image Tool Error: {e}")
return None
# --- Text Generation Helper ---
def tool_generate_text(prompt: str, system_message: str = "You are a helpful assistant.", max_tokens: int = 1024) -> str:
try:
response = nebius_client.chat.completions.create(
messages=[
{"role": "system", "content": system_message},
{"role": "user", "content": prompt},
],
model=TEXT_MODEL,
max_tokens=max_tokens,
temperature=0.7,
)
return response.choices[0].message.content
except Exception as e:
return f"Error: {e}"
# --- Market Insights Summarization Tool ---
def tool_summarize_market_insights(text: str):
"""
Summarizes long-form market research into insights, trends, and opportunities.
Exposed to MCP for agent workflows.
"""
print("🧠 Summarization Tool Running...")
try:
prompt = f"""
Summarize the following market research into:
• Key trends
• Industry opportunities
• Consumer behavior signals
• Competitive insights
Make the summary short, actionable, and business-oriented.
TEXT:
{text}
"""
# Increased max_tokens for long summaries
summary = tool_generate_text(
prompt,
system_message="You are an expert market analyst. Provide concise insights only.",
max_tokens=2000
)
return summary
except Exception as e:
return f"Summarization Error: {str(e)}"
# --- 3. AUTONOMOUS BRAND AGENT ---
def run_autonomous_agent(company_name, business_type, style, progress=gr.Progress()):
"""Autonomous branding agent logic with market insights summarization."""
# PHASE 1: COLOR PALETTE
progress(0.1, desc="Step 1: Planning & Palette...")
color_prompt = (
f"Create a distinct, 5-color palette for a {business_type} named '{company_name}' "
f"with a {style} style. Return ONLY a comma-separated list of hex codes."
)
colors_text = tool_generate_text(color_prompt, "You are a design expert. Output only the requested list.").strip().strip('.')
log = f"✅ Brand Plan Started for {company_name}\n"
log += f"🎨 Palette: {colors_text}\n"
# PHASE 2: LOGO
progress(0.3, desc="Step 2: Generating Logo...")
logo_prompt = (
f"A professional minimalist logo for a {business_type} named '{company_name}'. "
f"Use ONLY these colors: {colors_text}. Vector flat style, centered, no text."
)
logo_path = tool_generate_image(logo_prompt)
log += "🖼️ Logo Generated.\n"
# PHASE 3: COLOR PALETTE ASSET
progress(0.5, desc="Step 3: Color Palette Asset...")
asset_prompt = (
f"A professional color palette guide with 5 circular swatches arranged in a row. "
f"Use these colors: {colors_text}. Minimalist white background."
)
asset_path = tool_generate_image(asset_prompt)
log += "🖼️ Palette Asset Generated.\n"
# PHASE 4: RAW MARKET RESEARCH
progress(0.65, desc="Step 4: Raw Market Research...")
search_query = f"marketing trends for {business_type} 2025"
raw_research = tool_web_search(search_query)
log += f"🔍 Market Data Retrieved: {search_query}\n"
# PHASE 4.5: SUMMARIZE MARKET INSIGHTS
progress(0.8, desc="Step 4.5: Summarizing Insights...")
summarized = tool_summarize_market_insights(raw_research)
log += f"🧠 Market Insights Summary: {summarized[:150]}...\n"
# PHASE 5: SOCIAL MEDIA COPY
progress(0.95, desc="Step 5: Writing Social Content...")
copy_prompt = f"""
Write 3 engaging Twitter/X posts for a new {business_type} called '{company_name}'.
Tone: {style}.
Use these insights:
{summarized}
"""
social_copy = tool_generate_text(copy_prompt, "You are a professional social media strategist.", max_tokens=1500)
log += "✍️ Social Copy Generated.\n"
log += "✅ Autonomy Cycle Complete."
return logo_path, asset_path, social_copy, log, summarized
# --- 4. BRAND CONSULTANT CHATBOT ---
def chat_response(message, history):
system_message = "You are a creative brand consultant."
messages = [{"role": "system", "content": system_message}]
for msg in history:
messages.append({"role": msg["role"], "content": msg["content"]})
messages.append({"role": "user", "content": message})
try:
response = nebius_client.chat.completions.create(
messages=messages,
model=TEXT_MODEL,
max_tokens=300,
)
bot_reply = response.choices[0].message.content
history.append({"role": "user", "content": message})
history.append({"role": "assistant", "content": bot_reply})
return history, ""
except Exception as e:
history.append({"role": "assistant", "content": f"Error: {e}"})
return history, ""
# --- 5. GRADIO UI ---
theme = gr.themes.Soft(
primary_hue="indigo",
secondary_hue="blue",
neutral_hue="slate",
).set(
button_primary_background_fill="linear-gradient(90deg, #6366f1 0%, #4338ca 100%)",
button_primary_background_fill_hover="linear-gradient(90deg, #4f46e5 0%, #3730a3 100%)",
button_primary_text_color="white",
block_title_text_weight="600",
block_shadow="0 4px 6px rgba(0,0,0,0.1)",
)
custom_css = """#main-header {text-align: center; margin-bottom: 2rem;}"""
with gr.Blocks(theme=theme, css=custom_css, title="AutoBrand MCP Studio") as demo:
# HEADER
with gr.Column(elem_id="main-header"):
gr.Markdown("# 🖼️ AutoBrand Studio")
gr.Markdown(
"Autonomous Agent powered by AI Models, MCP Tools & Web Search."
)
with gr.Row():
# LEFT PANEL
with gr.Column(scale=1):
gr.Markdown("### 🚀 Brand Configuration")
company_input = gr.Textbox(label="Company Name", value="Lumina")
type_input = gr.Textbox(label="Business Type", value="Organic Candle Shop")
style_input = gr.Textbox(label="Style / Vibe", value="Minimalist, calming")
generate_btn = gr.Button("✨ Generate Brand Kit", variant="primary")
gr.Markdown("### ⚙️ System Logs")
out_log = gr.TextArea(label="Agent Log", lines=15, show_copy_button=True)
# RIGHT PANEL
with gr.Column(scale=2):
with gr.Tabs():
# BRAND IDENTITY TAB
with gr.TabItem("🎨 Brand Identity"):
with gr.Row():
out_logo = gr.Image(label="Logo Concept", height=350, type="filepath")
out_asset = gr.Image(label="Color Palette", height=350, type="filepath")
out_copy = gr.TextArea(label="Generated Social Content", lines=15, show_copy_button=True, interactive=False)
# BRAND CONSULTANT CHATBOT TAB
with gr.TabItem("💬 Brand Consultant"):
chatbot = gr.Chatbot(label="AI Consultant", height=650, type="messages")
chat_input = gr.Textbox(show_label=False, placeholder="Ask something...")
chat_btn = gr.Button("Send")
# MARKET INSIGHT SUMMARY TAB
with gr.TabItem("📊 Market Insight Summary"):
summary_box = gr.TextArea(label="Summarized Market Insights", lines=20, interactive=False, show_copy_button=True)
# HANDLERS
def run_agent_and_extract_summary(company, btype, style, progress=gr.Progress()):
logo, asset, copy, log, summarized = run_autonomous_agent(company, btype, style, progress)
return logo, asset, copy, log, summarized
generate_btn.click(
run_agent_and_extract_summary,
[company_input, type_input, style_input],
[out_logo, out_asset, out_copy, out_log, summary_box],
)
chat_btn.click(chat_response, [chat_input, chatbot], [chatbot, chat_input])
chat_input.submit(chat_response, [chat_input, chatbot], [chatbot, chat_input])
# --- MCP TOOLS (Hidden Row) ---
with gr.Row(visible=False):
search_in = gr.Textbox()
search_out = gr.Textbox()
btn_search = gr.Button("Search Tool")
btn_search.click(tool_web_search, inputs=search_in, outputs=search_out, api_name="web_search")
img_in = gr.Textbox()
img_out = gr.Image(type="filepath")
btn_img = gr.Button("Image Tool")
btn_img.click(tool_generate_image, inputs=img_in, outputs=img_out, api_name="generate_image")
summarize_in = gr.Textbox()
summarize_out = gr.Textbox()
btn_summarize = gr.Button("Summarize Tool")
btn_summarize.click(tool_summarize_market_insights, inputs=summarize_in, outputs=summarize_out, api_name="summarize_market_insights")
if __name__ == "__main__":
demo.launch(ssr_mode=False, mcp_server=True) |