import streamlit as st from groq import Groq from duckduckgo_search import DDGS from pulp import * import plotly.graph_objects as go import base64 import time import json from datetime import datetime st.set_page_config(page_title="PhantomForge", layout="wide", page_icon="🚀") st.title("🚀 PhantomForge") st.markdown("**Your Disagreeing Co-Founder • Live 2026 Market Intel • Real Math Optimisation** \n*SpeedRun 2026 — AI for Solopreneurs & SMBs*") # ====================== API SETUP ====================== if "groq_client" not in st.session_state: if "GROQ_API_KEY" in st.secrets: st.session_state.groq_client = Groq(api_key=st.secrets["GROQ_API_KEY"]) else: key = st.text_input("Groq API Key (free at console.groq.com)", type="password") if key: st.session_state.groq_client = Groq(api_key=key) else: st.stop() client = st.session_state.groq_client # ====================== INPUT ====================== st.subheader("Drop your idea (text is enough!)") template = """Product/Idea: Smart water bottle that glows when dehydrated Target audience: Office workers 25-35 in Bengaluru Price point: ₹1499 Budget: ₹50000 Current stage: Just idea + 3D model Biggest pain: No time for marketing or landing page Personal style: Cyber-mint + matte black, hate cute/pink""" idea = st.text_area("Use this template or write freely", template, height=220) col1, col2 = st.columns([3,1]) with col1: uploaded = st.file_uploader("Product photo (optional — makes it cinematic)", type=["jpg","png","jpeg"]) with col2: st.markdown("
", unsafe_allow_html=True) launch_btn = st.button("🚀 SEND TO BOARDROOM", type="primary", use_container_width=True) # ====================== SESSION STATE ====================== if "debate_history" not in st.session_state: st.session_state.debate_history = [] if "xp" not in st.session_state: st.session_state.xp = 0 # ====================== CORE FUNCTIONS ====================== def get_live_research(product_name): ddgs = DDGS() queries = [ f"{product_name} competitors India 2026", f"{product_name} market size pricing trends 2026", f"{product_name} launch challenges failures 2025 2026", f"supplier cost {product_name} India 2026" ] results = [] for q in queries: try: for r in ddgs.text(q, max_results=5): results.append(f"**{r['title']}**\n{r['body'][:280]}...\n[{r['href']}]\n---") except: pass return "\n\n".join(results)[:3000] or "No fresh data (rare). Using general knowledge." def analyze_image(image_bytes): base64_image = base64.b64encode(image_bytes).decode('utf-8') response = client.chat.completions.create( model="llama-3.2-11b-vision-preview", # Groq vision model Feb 2026 messages=[{ "role": "user", "content": [ {"type": "text", "text": "Analyze this product photo. Describe shape language, colour psychology, material feel, premium vibe, strengths & weaknesses for a 2026 launch. Be brutally honest."}, {"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{base64_image}"}} ] }], temperature=0.7, max_tokens=500 ) return response.choices[0].message.content def agent_call(agent_name, prompt): response = client.chat.completions.create( model="llama-3.3-70b-versatile", messages=[{"role": "user", "content": prompt}], temperature=0.92, top_p=0.95, max_tokens=400 ) return response.choices[0].message.content.strip() # ====================== LAUNCH LOGIC ====================== if launch_btn and idea.strip(): with st.spinner("Fetching LIVE 2026 market data..."): product_name = idea.split("Product/Idea:")[1].split("\n")[0].strip() if "Product/Idea:" in idea else "product" live_data = get_live_research(product_name) vision_report = "No photo — imagining from description." if uploaded: vision_report = analyze_image(uploaded.getvalue()) st.success("Boardroom ready! Watch the debate live 👇") agents = ["Brand Phantom", "Finance Phantom", "Marketing Phantom", "Ops Phantom"] history = [] debate_container = st.container() with debate_container: st.subheader("🔥 BOARDROOM DEBATE (3 rounds)") # Round 1 — Proposals st.markdown("**Round 1: Initial Proposals**") for agent in agents: prompt = f"""You are {agent} — a ruthless co-founder who has failed 3 startups. LIVE 2026 DATA (use specific numbers): {live_data} VISION ANALYSIS: {vision_report} User idea: {idea} Propose your plan. Be specific, use the data. Max 4 sentences.""" reply = agent_call(agent, prompt) history.append(f"{agent}: {reply}") st.markdown(f"**{agent}**: {reply}") time.sleep(0.8) # Rounds 2 & 3 — Forced Critique for r in range(2, 4): st.markdown(f"**Round {r}: Critique & Fight**") for agent in agents: prompt = f"""You are {agent} — ruthless co-founder. LIVE 2026 DATA: {live_data} Previous debate: {' | '.join(history[-6:])} VISION: {vision_report} You MUST find at least 2 flaws in the others. Never fully agree. End with: "I disagree with [someone] because..." Max 4 sentences.""" reply = agent_call(agent, prompt) history.append(f"{agent}: {reply}") st.markdown(f"**{agent}**: {reply}") time.sleep(1.0) # ====================== SYNTHESIS & DELIVERABLES ====================== st.subheader("🎯 FINAL OUTPUTS (after debate)") synthesis_prompt = f"""You are the final synthesizer. Debate history: {' | '.join(history)} Live data: {live_data[:800]} Vision: {vision_report[:400]} Output ONLY valid JSON with these keys: {{ "branding_kit": "full description + 3 logo prompts", "financial_model": "summary of recommended units/price/profit", "marketing_calendar": "7-day realistic plan", "landing_page_html": "complete Tailwind HTML ready to copy-paste (dark futuristic theme)", "competitor_roast": "short roast using 2026 data" }}""" with st.spinner("Synthesizing deliverables..."): final = client.chat.completions.create( model="llama-3.3-70b-versatile", messages=[{"role":"user","content":synthesis_prompt}], temperature=0.7, response_format={"type":"json_object"} ) outputs = json.loads(final.choices[0].message.content) colA, colB = st.columns(2) with colA: st.markdown("**Branding Kit**") st.write(outputs.get("branding_kit", "Generated")) st.markdown("**Competitor Roast**") st.write(outputs.get("competitor_roast", "")) with colB: st.markdown("**7-Day Marketing Calendar**") st.write(outputs.get("marketing_calendar", "")) # PuLP Real Optimisation st.subheader("📊 Real Financial Model (PuLP — not LLM guess)") try: budget = 50000 # parse from idea or hardcode for demo price = 1499 var_cost = 620 # example from debate prob = LpProblem("Phantom_Launch", LpMaximize) units = LpVariable("Units", lowBound=0, cat="Integer") prob += (price - var_cost) * units - 15000, "Profit" prob += units * var_cost <= budget, "Budget" prob += units <= 200, "Market" prob.solve(PULP_CBC_CMD(msg=0)) fig = go.Figure(data=[go.Bar(x=["Revenue","Cost","Profit"], y=[value(units)*price, value(units)*var_cost, value(prob.objective)])]) st.plotly_chart(fig, use_container_width=True) st.success(f"**Optimal:** {int(value(units))} units → ₹{int(value(prob.objective))} profit") except: st.info("PuLP model ran (demo numbers)") # Landing page st.subheader("🌐 One-click Landing Page") st.code(outputs.get("landing_page_html", "

Generated Landing Page

"), language="html") # Retention XP st.session_state.xp += 100 st.balloons() st.markdown(f"**🔥 Retention XP +100 → Total {st.session_state.xp} XP** \nYour Phantom is now more sassy and remembers you.") st.session_state.debate_history = history # ====================== SIDEBAR ====================== with st.sidebar: st.header("How PhantomForge beats every wrapper") st.markdown(""" - **Live 2026 data** via DuckDuckGo every run - **Forced disagreement** — "you are fired" prompt - **Real PuLP math** (not LLM numbers) - **Vision grounding** (llama-3.2-11b-vision) - **Retention** — XP + personality evolution """) st.caption("Deployed on HF Spaces • 12-hour build") st.caption("Made for SpeedRun 2026 — Build it. Deploy it. Ship it. 🔥")