Spaces:
Sleeping
Sleeping
File size: 9,050 Bytes
e68bfbf 42d7d97 e68bfbf 42d7d97 | 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 | 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("<br>", 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", "<h1>Generated Landing Page</h1>"), 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. π₯") |