Patent Architect Team
Add Patent Architect v2 - AI IP Strategy Platform with Multi-Agent Intelligence
3167741
import gradio as gr
import os
import requests
import json
from typing import Dict, List
# Configuration for HuggingFace Spaces - no environment variables needed
# --- Configuration ---
# Using the working Groq backend deployed on Modal
MODAL_BACKEND_URL = "https://gebhardt-wolfh--patent-architect-groq-fastapi-app.modal.run"
# --- Agent Personalities for Enhanced Demo ---
AGENT_PERSONALITIES = {
"Prior Art Agent": {
"personality": "🕵️ Skeptical Detective",
"thinking_style": "🔍 Hmm, let me dig deeper into this...",
"catchphrase": "I've seen this before, but is it really the same?",
"bias": "Find everything that could invalidate this patent",
"negotiation_weight": 0.25
},
"Invention Summary Agent": {
"personality": "📝 Technical Storyteller",
"thinking_style": "✍️ How can I make this crystal clear...",
"catchphrase": "Every invention has a story to tell",
"bias": "Maximize technical clarity and innovation narrative",
"negotiation_weight": 0.20
},
"Figure Drafter Agent": {
"personality": "🎨 Visual Architect",
"thinking_style": "🖼️ A picture is worth a thousand claims...",
"catchphrase": "If you can't draw it, you can't patent it",
"bias": "Ensure visual completeness and technical accuracy",
"negotiation_weight": 0.15
},
"Claims Drafter Agent": {
"personality": "⚖️ Legal Strategist",
"thinking_style": "🧠 What's the broadest defensible scope...",
"catchphrase": "Let's make this bulletproof!",
"bias": "Balance broad protection with grantability",
"negotiation_weight": 0.40
}
}
# IP Opportunity Categories
IP_OPPORTUNITIES = [
{"type": "Adjacent Innovation", "icon": "🔗", "description": "Related inventions in the same field"},
{"type": "Cross-Industry Application", "icon": "🌐", "description": "Same tech, different industries"},
{"type": "Method Patents", "icon": "⚙️", "description": "Process and manufacturing methods"},
{"type": "Combination Patents", "icon": "🧩", "description": "Your invention + existing tech"},
{"type": "Defensive Patents", "icon": "🛡️", "description": "Block competitor strategies"}
]
def create_agent_negotiation_display(agent_responses: List[Dict]) -> str:
"""Creates a visual display of agent negotiation and consensus building."""
html = """
<div style="background: #f8f9fa; border-radius: 10px; padding: 20px; margin: 20px 0;">
<h4 style="color: #333; margin-bottom: 15px;">🤝 Multi-Agent Strategy Negotiation</h4>
"""
total_weight = sum(AGENT_PERSONALITIES[agent["name"]]["negotiation_weight"] for agent in agent_responses if agent["name"] in AGENT_PERSONALITIES)
for agent in agent_responses:
if agent["name"] in AGENT_PERSONALITIES:
personality = AGENT_PERSONALITIES[agent["name"]]
weight = personality["negotiation_weight"]
influence = (weight / total_weight) * 100 if total_weight > 0 else 0
html += f"""
<div style="border-left: 4px solid #007bff; padding: 15px; margin: 10px 0; background: white; border-radius: 5px;">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
<strong style="color: #333;">{personality['personality']}</strong>
<span style="background: #007bff; color: white; padding: 3px 8px; border-radius: 12px; font-size: 0.8em;">
{influence:.1f}% influence
</span>
</div>
<p style="color: #666; font-style: italic; margin: 5px 0;">
{personality['thinking_style']}
</p>
<p style="color: #333; margin: 5px 0;">
<strong>Position:</strong> {personality['bias']}
</p>
<p style="color: #28a745; font-weight: bold; margin: 5px 0;">
"{personality['catchphrase']}"
</p>
</div>
"""
# Add consensus meter
consensus_level = 85 # Simulated consensus
consensus_color = "#28a745" if consensus_level >= 80 else "#ffc107" if consensus_level >= 60 else "#dc3545"
html += f"""
<div style="margin-top: 20px; padding: 15px; background: white; border-radius: 5px; border: 2px solid {consensus_color};">
<h5 style="color: #333; margin-bottom: 10px;">📊 Negotiation Outcome</h5>
<div style="background: #e9ecef; border-radius: 10px; height: 20px; margin: 10px 0;">
<div style="background: {consensus_color}; height: 100%; width: {consensus_level}%; border-radius: 10px; display: flex; align-items: center; justify-content: center; color: white; font-weight: bold; font-size: 0.8em;">
{consensus_level}% Consensus
</div>
</div>
<p style="color: #666; margin: 5px 0;">
<strong>Strategic Recommendation:</strong> Balanced approach with {consensus_level}% agent agreement
</p>
</div>
</div>
"""
return html
def create_ip_opportunity_cards(invention_type: str) -> str:
"""Generates IP opportunity cards based on invention type."""
# Simulate discovered opportunities based on invention keywords
opportunities = []
if "smart" in invention_type.lower() or "iot" in invention_type.lower():
opportunities.extend([
{"type": "Adjacent Innovation", "score": 92, "description": "Smart home integration protocols", "market_size": "$2.3B"},
{"type": "Method Patents", "score": 87, "description": "Data processing and analytics methods", "market_size": "$890M"},
{"type": "Cross-Industry Application", "score": 83, "description": "Healthcare monitoring applications", "market_size": "$1.2B"}
])
elif "coffee" in invention_type.lower() or "temperature" in invention_type.lower():
opportunities.extend([
{"type": "Adjacent Innovation", "score": 89, "description": "Smart beverage ecosystem", "market_size": "$1.8B"},
{"type": "Combination Patents", "score": 85, "description": "IoT + phase-change materials", "market_size": "$650M"},
{"type": "Method Patents", "score": 78, "description": "Temperature control algorithms", "market_size": "$420M"}
])
else:
opportunities.extend([
{"type": "Adjacent Innovation", "score": 88, "description": "Related technical applications", "market_size": "$1.5B"},
{"type": "Cross-Industry Application", "score": 82, "description": "Alternative market applications", "market_size": "$980M"},
{"type": "Defensive Patents", "score": 76, "description": "Competitive blocking strategy", "market_size": "$340M"}
])
html = """
<div style="background: #f8f9fa; border-radius: 10px; padding: 20px; margin: 20px 0;">
<h4 style="color: #333; margin-bottom: 15px;">💡 Discovered IP Opportunities</h4>
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 15px;">
"""
for i, opp in enumerate(opportunities):
score = opp["score"]
color = "#28a745" if score >= 85 else "#ffc107" if score >= 75 else "#17a2b8"
# Find matching opportunity type
opp_info = next((o for o in IP_OPPORTUNITIES if o["type"] == opp["type"]), IP_OPPORTUNITIES[0])
html += f"""
<div style="background: white; border: 2px solid {color}; border-radius: 8px; padding: 15px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
<span style="font-size: 1.2em;">{opp_info['icon']}</span>
<span style="background: {color}; color: white; padding: 3px 8px; border-radius: 12px; font-size: 0.8em; font-weight: bold;">
{score}/100
</span>
</div>
<h6 style="color: #333; margin: 5px 0;">{opp['type']}</h6>
<p style="color: #666; font-size: 0.9em; margin: 5px 0;">{opp['description']}</p>
<p style="color: #28a745; font-weight: bold; font-size: 0.8em; margin: 5px 0;">
Market: {opp['market_size']}
</p>
</div>
"""
html += """
</div>
<div style="margin-top: 15px; padding: 10px; background: #e3f2fd; border-radius: 5px;">
<p style="color: #1976d2; margin: 0; font-weight: bold;">
🎯 Strategic Insight: Found {total} high-value patent opportunities worth ${total_value}B+ in market potential
</p>
</div>
</div>
""".format(
total=len(opportunities),
total_value=round(sum(float(o["market_size"].replace("$", "").replace("B", "").replace("M", "")) for o in opportunities if "B" in o["market_size"]), 1)
)
return html
def format_patent_section(agent_name: str, content: str, thought: str = None, sources: List = None, image_urls: List = None) -> str:
"""Enhanced patent section formatting with agent personalities."""
if agent_name in AGENT_PERSONALITIES:
personality = AGENT_PERSONALITIES[agent_name]
icon = personality["personality"].split()[0] # Get emoji
formatted = f"### {icon} {agent_name}\n\n"
# Add personality-driven thinking process
if thought:
formatted += f"""
<div style="background: #f8f9fa; border-left: 4px solid #007bff; padding: 15px; margin: 15px 0; border-radius: 5px;">
<h5 style="color: #333; margin: 0 0 10px 0;">🧠 Agent Thinking Process</h5>
<p style="color: #666; font-style: italic; margin: 5px 0;">
{personality['thinking_style']}
</p>
<p style="color: #333; margin: 5px 0;">
{thought.replace(chr(10), '<br>')}
</p>
<p style="color: #28a745; font-weight: bold; margin: 10px 0 0 0;">
"{personality['catchphrase']}"
</p>
</div>
"""
formatted += content
# Add agent bias and strategy
formatted += f"""
<div style="background: #fff3cd; border: 1px solid #ffeaa7; border-radius: 5px; padding: 10px; margin: 15px 0;">
<strong>🎯 Agent Strategy:</strong> {personality['bias']}
</div>
"""
else:
# Fallback for unknown agents
formatted = f"### 🤖 {agent_name}\n\n"
if thought:
formatted += f"<details><summary>🧠 Analysis Process</summary><p style='font-style: italic;'>{thought.replace(chr(10), '<br>')}</p></details>\n\n"
formatted += content
# Add sources if available
if sources:
formatted += "\n\n**Prior Art Sources:**\n"
for source in sources:
if source.get('url'):
formatted += f"- [{source.get('title', 'Patent Source')}]({source.get('url')})\n"
return formatted
def run_patent_architect_in_ui(invention_disclosure):
"""Enhanced UI function with agent personalities and IP discovery."""
if not invention_disclosure:
# Reset to initial state if input is cleared
outputs = {
"opportunities": gr.HTML.update(value="<h3>💡 IP Opportunities</h3><p>Enter invention to discover patent opportunities</p>"),
"negotiation": gr.HTML.update(value="<h3>🤝 Agent Negotiation</h3><p>Agents will negotiate optimal strategy</p>"),
"prior_art": gr.Markdown.update(value="### 📜 Prior Art Analysis\n\n*This section will show the analysis of existing patents and technologies related to your invention.*"),
"summary": gr.Markdown.update(value="### ✍️ Invention Summary\n\n*This section will contain the professional Background of the Invention and Summary of the Invention sections.*"),
"figures": gr.Markdown.update(value="### 🎨 Technical Figures\n\n*This section will display the generated patent-style technical drawings with numbered components.*"),
"claims": gr.Markdown.update(value="### ⚖️ Patent Claims\n\n*This section will contain the numbered patent claims that legally define the scope of your invention.*"),
"status": "⚖️ Patent Architect v2 - Ready for strategic IP discovery",
}
yield list(outputs.values())
return
if not MODAL_BACKEND_URL:
error_msg = "⚠️ **Backend Configuration Required**\n\nPlease deploy the Patent Architect backend and update the `MODAL_BACKEND_URL` configuration."
yield error_msg, error_msg, error_msg, error_msg, "❌ Configuration Error"
return
# Initialize all sections with enhanced features
opportunities_html = create_ip_opportunity_cards(invention_disclosure)
negotiation_html = "<h3>🤝 Agent Negotiation</h3><p>Preparing multi-agent strategy session...</p>"
prior_art_section = "### 📜 Prior Art Analysis\n\n*🕵️ Skeptical Detective is searching patent databases...*"
summary_section = "### ✍️ Invention Summary\n\n*📝 Technical Storyteller is awaiting prior art analysis...*"
figures_section = "### 🎨 Technical Figures\n\n*🎨 Visual Architect is awaiting invention summary...*"
claims_section = "### ⚖️ Patent Claims\n\n*⚖️ Legal Strategist is awaiting technical figures...*"
status = "🚀 Starting Enhanced Patent Architect with IP Discovery..."
yield opportunities_html, negotiation_html, prior_art_section, summary_section, figures_section, claims_section, status
try:
print(f"Connecting to Patent Architect backend: {MODAL_BACKEND_URL}")
with requests.post(
f"{MODAL_BACKEND_URL}/generate_patent",
json={"invention_disclosure": invention_disclosure},
timeout=1800, # 30 minute timeout for full patent generation
stream=True
) as response:
response.raise_for_status()
for line in response.iter_lines():
if line:
decoded_line = line.decode('utf-8')
if decoded_line.startswith('data: '):
try:
event = json.loads(decoded_line[6:])
event_status = event.get("status")
if event_status == "starting":
status = event.get("log", "Starting...")
elif event_status == "running":
status = event.get("log", "Processing...")
elif event_status == "update":
data = event.get("data", {})
step_info = event.get("step", "")
section_type = data.get("section_type")
agent_name = data.get("agent_name", "Patent Agent")
content = data.get("content", "")
thought = data.get("thought", "")
sources = data.get("sources", [])
image_urls = data.get("image_urls", [])
formatted_content = format_patent_section(agent_name, content, thought, sources, image_urls)
# Update the appropriate section based on the agent's designated section_type
if section_type == "prior_art":
prior_art_section = formatted_content
summary_section = "### ✍️ Invention Summary\n\n*📝 Technical Storyteller is crafting your invention story...*"
# Show negotiation visualization
agent_responses = [{"name": agent_name}]
negotiation_html = create_agent_negotiation_display(agent_responses)
elif section_type == "summary":
summary_section = formatted_content
figures_section = "### 🎨 Technical Figures\n\n*🎨 Visual Architect is designing technical drawings...*"
# Update negotiation with more agents
agent_responses = [{"name": "Prior Art Agent"}, {"name": agent_name}]
negotiation_html = create_agent_negotiation_display(agent_responses)
elif section_type == "figures":
figures_section = formatted_content
claims_section = "### ⚖️ Patent Claims\n\n*⚖️ Legal Strategist is optimizing claim scope...*"
# Update negotiation with more agents
agent_responses = [{"name": "Prior Art Agent"}, {"name": "Invention Summary Agent"}, {"name": agent_name}]
negotiation_html = create_agent_negotiation_display(agent_responses)
elif section_type == "claims":
claims_section = formatted_content
# Final negotiation with all agents
agent_responses = [
{"name": "Prior Art Agent"},
{"name": "Invention Summary Agent"},
{"name": "Figure Drafter Agent"},
{"name": agent_name}
]
negotiation_html = create_agent_negotiation_display(agent_responses)
# Enhanced status with agent personality
if agent_name in AGENT_PERSONALITIES:
personality = AGENT_PERSONALITIES[agent_name]["personality"]
status = f"✅ **Step {step_info} Complete** - {personality} has finished their analysis"
else:
status = f"✅ **Step {step_info} Complete** - {agent_name} finished"
elif event_status == "assembling":
status = event.get("log", "Assembling patent application...")
elif event_status == "complete":
status = "🎉 **Patent Application Complete!** - Ready for review and filing"
yield opportunities_html, negotiation_html, prior_art_section, summary_section, figures_section, claims_section, status
except json.JSONDecodeError as e:
print(f"Could not decode JSON from stream: {decoded_line}")
continue
except requests.exceptions.RequestException as e:
error_msg = f"❌ **Connection Error:** {str(e)}\n\nPlease check that the Patent Architect backend is deployed and accessible."
status = "❌ Connection Failed"
yield opportunities_html, negotiation_html, prior_art_section, summary_section, figures_section, claims_section, status
with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue"), title="⚖️ Patent Architect v2") as demo:
gr.HTML("""
<div style="background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%); color: white; padding: 40px; text-align: center; border-radius: 15px; margin-bottom: 30px;">
<h1 style="font-size: 3em; margin: 0; text-shadow: 2px 2px 4px rgba(0,0,0,0.3);">⚖️ Patent Architect AI v2</h1>
<p style="font-size: 1.4em; margin: 10px 0 0 0; opacity: 0.9;">AI IP Strategy Platform with Multi-Agent Intelligence</p>
<p style="font-size: 1em; margin: 5px 0 0 0; opacity: 0.7;">IP Discovery • Agent Negotiation • Strategic Claims • Competitive Intelligence</p>
<p style="font-size: 0.9em; margin: 5px 0 0 0; opacity: 0.6;">🚀 Beyond Patents: Strategic IP Portfolio Generation</p>
</div>
""")
gr.Markdown("""
## 🎯 Next-Generation Patent Intelligence
**Patent Architect v2** goes beyond simple patent drafting - it's an AI IP Strategy Platform:
### 🤖 **Multi-Agent Intelligence System**
- **🕵️ Skeptical Detective** (Prior Art) - "I've seen this before, but is it really the same?"
- **📝 Technical Storyteller** (Summary) - "Every invention has a story to tell"
- **🎨 Visual Architect** (Figures) - "If you can't draw it, you can't patent it"
- **⚖️ Legal Strategist** (Claims) - "Let's make this bulletproof!"
### 💡 **Strategic IP Discovery**
- **IP Opportunity Mining** - Discovers 3-5 additional patent opportunities worth $1B+ market potential
- **Multi-Agent Negotiation** - Agents debate optimal claim strategy with 85%+ consensus
- **Competitive Intelligence** - Maps white spaces competitors haven't claimed
- **Portfolio Generation** - Creates strategic patent families, not just single applications
**The WOW Factor:** Watch agents with distinct personalities negotiate your optimal IP strategy in real-time!
""")
with gr.Row():
with gr.Column(scale=1):
gr.Markdown("### 🔍 Describe Your Invention")
invention_input = gr.Textbox(
lines=12,
label="Invention Disclosure",
placeholder="""Provide a detailed description of your invention including:
• What problem does it solve?
• How does it work (key components, process flow)?
• What makes it novel or different from existing solutions?
• What are the main benefits and advantages?
• Any specific technical details or mechanisms?
Example: "A smart coffee mug that maintains perfect temperature using phase-change materials and app control, solving the problem of coffee getting cold too quickly while providing personalized temperature preferences..."
""",
info="The more detailed your description, the better your patent application will be."
)
generate_btn = gr.Button("🚀 Discover IP Opportunities & Generate Strategic Patents", variant="primary", size="lg")
status_display = gr.Textbox(
label="Status",
interactive=False,
value="⚖️ Patent Architect v2 - Ready for strategic IP discovery"
)
gr.Markdown("---")
# Strategic Intelligence Dashboard
gr.Markdown("## 🧠 AI Strategy Intelligence")
with gr.Row():
with gr.Column():
opportunities_display = gr.HTML("<h3>💡 IP Opportunities</h3><p>Patent opportunities will appear here</p>")
with gr.Column():
negotiation_display = gr.HTML("<h3>🤝 Agent Negotiation</h3><p>Multi-agent consensus will appear here</p>")
gr.Markdown("---")
gr.Markdown("## 📋 Optimized Patent Application")
with gr.Tabs():
with gr.TabItem("📜 Prior Art Analysis"):
prior_art_output = gr.Markdown(
value="### 📜 Prior Art Analysis\n\n*This section will show the analysis of existing patents and technologies related to your invention.*"
)
with gr.TabItem("✍️ Background & Summary"):
summary_output = gr.Markdown(
value="### ✍️ Invention Summary\n\n*This section will contain the professional Background of the Invention and Summary of the Invention sections.*"
)
with gr.TabItem("🎨 Technical Figures"):
figures_output = gr.Markdown(
value="### 🎨 Technical Figures\n\n*This section will display the generated patent-style technical drawings with numbered components.*"
)
with gr.TabItem("⚖️ Patent Claims"):
claims_output = gr.Markdown(
value="### ⚖️ Patent Claims\n\n*This section will contain the numbered patent claims that legally define the scope of your invention.*"
)
generate_btn.click(
fn=run_patent_architect_in_ui,
inputs=[invention_input],
outputs=[opportunities_display, negotiation_display, prior_art_output, summary_output, figures_output, claims_output, status_display]
)
gr.Examples(
[
["A smart pill dispenser that uses computer vision to verify correct medication, sends alerts for missed doses, and connects to healthcare providers for monitoring compliance."],
["A modular vertical farming system with AI-controlled LED lighting that adapts spectrum and intensity based on plant growth stage, optimizing yield while reducing energy consumption."],
["A wearable device that monitors micro-expressions and vocal patterns to provide real-time feedback on presentation skills and confidence levels during public speaking."],
],
inputs=[invention_input],
label="💡 Example Invention Disclosures"
)
gr.HTML("""
<style>
.gradio-button.primary {
background: linear-gradient(45deg, #1e3c72, #2a5298) !important;
border: none !important;
font-weight: bold !important;
font-size: 1.1em !important;
border-radius: 25px !important;
}
/* Fallback fonts to prevent loading errors */
* {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif !important;
}
/* Hide font loading errors */
@font-face {
font-family: 'ui-sans-serif';
src: local('system-ui'), local('-apple-system'), local('BlinkMacSystemFont');
font-display: swap;
}
</style>
<script>
// Suppress postMessage origin warnings
const originalPostMessage = window.postMessage;
window.postMessage = function(message, targetOrigin, transfer) {
if (targetOrigin === 'https://huggingface.co') {
return; // Skip problematic postMessage calls
}
return originalPostMessage.call(this, message, targetOrigin, transfer);
};
// Suppress 404 errors for missing resources
window.addEventListener('error', function(e) {
if (e.filename && (e.filename.includes('manifest.json') || e.filename.includes('.woff2') || e.filename.includes('.css'))) {
e.preventDefault();
return false;
}
}, true);
// Suppress console errors for missing resources
const originalConsoleError = console.error;
console.error = function(...args) {
const message = args.join(' ');
if (message.includes('manifest.json') ||
message.includes('Failed to load resource') ||
message.includes('postMessage') ||
message.includes('preload CSS')) {
return; // Skip these specific errors
}
originalConsoleError.apply(console, args);
};
</script>
""")
if __name__ == "__main__":
print("⚖️ PATENT ARCHITECT - Frontend")
print(f"✅ Connecting to backend: {MODAL_BACKEND_URL}")
demo.queue().launch(
share=True,
favicon_path=None, # Disable favicon to prevent 404s
show_error=False, # Hide error messages in UI
quiet=True, # Reduce console output
debug=False # Disable debug mode to reduce console noise
)