WHG2023 commited on
Commit
137c880
·
1 Parent(s): 4252b44

feat: Implement full agentic workflow with dual image generation

Browse files

This commit introduces a true, stateful agentic negotiation process orchestrated by a Chief Strategist Agent. Key features include Segmind Ideogram API integration for conceptual images, real-time LaTeX compilation for viewable technical figures, and a complete, strategy-aligned patent draft generation.

Files changed (3) hide show
  1. app.py +168 -733
  2. real_ai_agents_implementation.py +282 -513
  3. requirements.txt +7 -6
app.py CHANGED
@@ -2,670 +2,179 @@ import gradio as gr
2
  import os
3
  import requests
4
  import json
5
- from typing import Dict, List
6
  from dotenv import load_dotenv
 
 
 
 
7
 
8
  # Load environment variables from .env file
9
  load_dotenv()
10
 
11
- # Add Gemini integration at the top after existing imports
 
 
 
 
 
 
 
 
12
  try:
13
  from gemini_image_generator import GeminiImageGenerator
14
  GEMINI_IMAGE_AVAILABLE = True
15
  except ImportError:
16
  GEMINI_IMAGE_AVAILABLE = False
17
 
18
- # Add Real AI Agents integration
19
- try:
20
- from real_ai_agents_implementation import (
21
- TechnicalCompletenessAgent,
22
- PriorArtLandscapeAgent,
23
- ClaimArchitectureAgent,
24
- InterAgentCoordinator
25
- )
26
- REAL_AI_AGENTS_AVAILABLE = True
27
- except ImportError:
28
- REAL_AI_AGENTS_AVAILABLE = False
29
-
30
- # Add Nebius integration
31
- try:
32
- from nebius_image_generator import integrate_with_patent_architect
33
- NEBIUS_AVAILABLE = True
34
- except ImportError:
35
- NEBIUS_AVAILABLE = False
36
-
37
- # Configuration for HuggingFace Spaces - no environment variables needed
38
-
39
- # --- Configuration ---
40
- # Using the clean Groq-only backend (reliable, no proxy issues)
41
- MODAL_BACKEND_URL = "https://gebhardt-wolfh--patent-architect-groq-fastapi-app.modal.run"
42
- # Alternative backends:
43
- # - Nebius with images (experimental): "https://gebhardt-wolfh--patent-architect-nebius-clean-fastapi-app.modal.run"
44
- # - Clean backend: "https://gebhardt-wolfh--patent-architect-clean-fastapi-app.modal.run"
45
-
46
- # --- Enhanced Agent Personalities for Strategy Demo ---
47
- AGENT_PERSONALITIES = {
48
- "Technical Analysis Agent": {
49
- "personality": "Technical Deep-Dive Specialist",
50
- "thinking_style": "Analyzing technical mechanisms and specifications",
51
- "catchphrase": "Understanding the physics behind the innovation",
52
- "bias": "Demand detailed technical explanations and identify knowledge gaps",
53
- "negotiation_weight": 0.20,
54
- "expertise": "Technical feasibility, mechanism analysis, specification requirements"
55
- },
56
- "Prior Art Agent": {
57
- "personality": "Patent Detective",
58
- "thinking_style": "Comprehensive patent landscape analysis",
59
- "catchphrase": "Finding every relevant patent and publication",
60
- "bias": "Exhaustive prior art search across multiple technology domains",
61
- "negotiation_weight": 0.25,
62
- "expertise": "Patent databases, academic literature, international filings"
63
- },
64
- "Invention Summary Agent": {
65
- "personality": "Technical Writer",
66
- "thinking_style": "Creating precise technical narratives",
67
- "catchphrase": "Crafting clear and compelling technical stories",
68
- "bias": "Maximize technical clarity while highlighting true innovation",
69
- "negotiation_weight": 0.15,
70
- "expertise": "Technical writing, invention disclosure, differentiation"
71
- },
72
- "Figure Drafter Agent": {
73
- "personality": "Technical Illustrator",
74
- "thinking_style": "Designing patent drawings and diagrams",
75
- "catchphrase": "Visual documentation of technical concepts",
76
- "bias": "Ensure complete visual documentation of invention",
77
- "negotiation_weight": 0.15,
78
- "expertise": "Technical drawings, patent figures, visual communication"
79
- },
80
- "Claims Strategy Agent": {
81
- "personality": "Patent Attorney",
82
- "thinking_style": "Strategic patent claim optimization",
83
- "catchphrase": "Crafting bulletproof patent claims",
84
- "bias": "Balance broad protection with technical accuracy and grantability",
85
- "negotiation_weight": 0.25,
86
- "expertise": "Claim drafting, patent law, prosecution strategy"
87
- }
88
- }
89
-
90
- # Enhanced IP Opportunity Categories with more specificity
91
- IP_OPPORTUNITIES = [
92
- {"type": "Core Technology Patent", "description": "Main invention with detailed technical claims"},
93
- {"type": "Method Patents", "description": "Process and algorithmic innovations"},
94
- {"type": "System Integration Patents", "description": "Combination with other technologies"},
95
- {"type": "Application-Specific Patents", "description": "Industry-specific implementations"},
96
- {"type": "Improvement Patents", "description": "Enhanced versions and optimizations"},
97
- {"type": "Defensive Patents", "description": "Block competitor strategies"}
98
- ]
99
 
100
- def create_agent_negotiation_display(agent_responses: List[Dict], real_ai_results: Dict = None) -> str:
101
- """Creates a detailed display of technical agent negotiation with real AI analysis."""
102
-
103
- # If we have real AI results, use them for enhanced analysis
104
- if real_ai_results and real_ai_results.get("available"):
105
- markdown = f"### 🤖 Real AI Agent Analysis\n\n"
106
-
107
- results = real_ai_results["results"]
108
- readiness_score = real_ai_results["readiness_score"]
109
- assessment = real_ai_results["assessment"]
110
-
111
- # Technical Completeness
112
- tech_analysis = real_ai_results.get("technical_analysis", {})
113
- tech_score = tech_analysis.get("completeness_score", 0) * 100
114
- risk_level = tech_analysis.get("prosecution_risk", "Unknown")
115
- missing_elements = tech_analysis.get("missing_elements", [])
116
-
117
- markdown += f"**🔬 Technical Completeness Agent:** {tech_score:.1f}%\n"
118
- markdown += f"📊 Prosecution Risk: **{risk_level}**\n"
119
- if missing_elements:
120
- markdown += f"⚠️ Missing Critical Elements: {len(missing_elements)}\n"
121
- for element in missing_elements[:2]: # Show first 2
122
- markdown += f" • **{element.get('element_type', 'Unknown')}**: {element.get('suggestion', 'Needs improvement')}\n"
123
- markdown += "\n"
124
-
125
- # Prior Art Analysis
126
- prior_art = real_ai_results.get("prior_art_analysis", {})
127
- risk_assessment = prior_art.get("risk_assessment", {})
128
- competitors = prior_art.get("key_competitors", [])
129
-
130
- markdown += f"**🔍 Prior Art Landscape Agent:**\n"
131
- markdown += f"📊 Risk Level: **{risk_assessment.get('overall_risk', 'Medium')}**\n"
132
- if competitors:
133
- markdown += f"🏢 Key Competitors: {len(competitors)}\n"
134
- for comp in competitors[:2]: # Show first 2
135
- markdown += f" • **{comp.get('company', 'Unknown')}**: {comp.get('patent_count', 0)} patents\n"
136
- markdown += "\n"
137
-
138
- # Claim Architecture
139
- claim_analysis = real_ai_results.get("claim_analysis", {})
140
- claim_strength = claim_analysis.get("claim_strength", {})
141
- overall_strength = claim_strength.get("overall_strength", 0) * 100
142
-
143
- markdown += f"**⚖️ Claim Architecture Agent:** {overall_strength:.1f}%\n"
144
- markdown += f"📊 Grantability: **{claim_strength.get('grantability', 'Unknown')}**\n\n"
145
-
146
- # Overall Assessment
147
- markdown += f"**🎯 OVERALL READINESS ASSESSMENT:**\n"
148
- markdown += f"**Score:** {readiness_score*100:.1f}% - **{assessment}**\n\n"
149
 
150
- # Business Intelligence
151
- timeline = results.get("estimated_timeline", "Unknown")
152
- costs = results.get("estimated_costs", "Unknown")
153
- markdown += f"**📈 Business Planning:**\n"
154
- markdown += f"• **Timeline:** {timeline}\n"
155
- markdown += f"• **Estimated Costs:** {costs}\n\n"
156
 
157
- # Recommendations
158
- recommendations = results.get("development_recommendations", [])
159
- if recommendations:
160
- markdown += f"**💡 Development Recommendations:**\n"
161
- for rec in recommendations[:3]: # Show first 3
162
- markdown += f"• {rec}\n"
163
-
164
- return markdown
165
-
166
- # Fallback to original negotiation display
167
- total_weight = sum(AGENT_PERSONALITIES[agent["name"]]["negotiation_weight"] for agent in agent_responses if agent["name"] in AGENT_PERSONALITIES)
168
-
169
- negotiations = []
170
- for agent in agent_responses:
171
- if agent["name"] in AGENT_PERSONALITIES:
172
- personality = AGENT_PERSONALITIES[agent["name"]]
173
- weight = personality["negotiation_weight"]
174
- influence = (weight / total_weight) * 100 if total_weight > 0 else 0
175
-
176
- # Enhanced negotiation points with technical depth
177
- agent_type = agent["name"].split()[0].lower()
178
- if agent_type == "technical":
179
- position = f"Technical gaps identified: Missing mechanism details, frequency analysis specs, signal processing algorithms"
180
- concern_level = "High"
181
- elif agent_type == "prior":
182
- num_patents = agent.get("num_patents", 1)
183
- if num_patents < 10:
184
- position = f"Shallow search: Only {num_patents} patents found. Missing ultrasonic sensors, acoustic emission, vibration analysis domains"
185
- concern_level = "High"
186
- else:
187
- position = f"Comprehensive analysis: {num_patents} patents analyzed across multiple domains"
188
- concern_level = "Low"
189
- elif agent_type == "invention":
190
- position = f"Technical clarity: Low - needs specific mechanism explanation, frequency ranges, sensor specifications"
191
- concern_level = "Medium"
192
- elif agent_type == "figure":
193
- position = f"Visual documentation: Incomplete - needs actual technical drawings with numbered components"
194
- concern_level = "Medium"
195
- elif agent_type == "claims":
196
- position = f"Claims analysis: Too broad, likely not novel - need specific technical limitations"
197
- concern_level = "High"
198
- else:
199
- position = personality['bias']
200
- concern_level = "Medium"
201
 
202
- # Color coding based on concern level
203
- status_color = "🔴" if concern_level == "High" else "🟡" if concern_level == "Medium" else "🟢"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
204
 
205
- negotiations.append({
206
- "name": agent["name"],
207
- "influence": influence,
208
- "position": position,
209
- "concern_level": concern_level,
210
- "status_color": status_color,
211
- "status": "Reviewing" if len(agent_responses) <= 3 else "Complete"
212
- })
213
-
214
- # Build markdown display with detailed feedback
215
- markdown = f"### Multi-Agent Technical Review (Step {len(agent_responses)}/5)\n\n"
216
-
217
- for neg in negotiations:
218
- status_text = "(Active Review)" if neg["status"] == "Reviewing" else "(Complete)"
219
- markdown += f"**{neg['name']}** {status_text} - {neg['influence']:.0f}% influence {neg['status_color']}\n"
220
- markdown += f"Assessment: {neg['position']}\n"
221
- markdown += f"Concern Level: {neg['concern_level']}\n\n"
222
-
223
- # Calculate realistic consensus based on technical concerns
224
- high_concerns = sum(1 for neg in negotiations if neg['concern_level'] == 'High')
225
- medium_concerns = sum(1 for neg in negotiations if neg['concern_level'] == 'Medium')
226
-
227
- if high_concerns >= 2:
228
- consensus_level = 45
229
- patentability_score = 4.5
230
- outcome = "Major technical gaps identified. Invention needs significant development before patent filing."
231
- elif high_concerns == 1 and medium_concerns >= 1:
232
- consensus_level = 65
233
- patentability_score = 6.5
234
- outcome = "Technical issues identified. Requires expert review and refinement."
235
- elif medium_concerns >= 2:
236
- consensus_level = 75
237
- patentability_score = 7.5
238
- outcome = "Good foundation with areas for improvement. Recommend technical enhancement."
239
- else:
240
- consensus_level = 85
241
- patentability_score = 8.5
242
- outcome = "Strong technical foundation. Ready for expert patent attorney review."
243
-
244
- markdown += f"**Technical Consensus:** {consensus_level}% - **Realistic Patentability Score: {patentability_score:.1f}/10**\n\n"
245
- markdown += f"**Outcome:** {outcome}\n\n"
246
-
247
- # Add specific recommendations based on critique
248
- markdown += "**Expert Recommendations:**\n"
249
- if high_concerns >= 1:
250
- markdown += "• Conduct deeper technical development before patent filing\n"
251
- markdown += "• Engage patent attorney for comprehensive prior art search\n"
252
- markdown += "• Define specific technical mechanism and parameters\n"
253
- markdown += "• Identify true novel contribution vs. existing art\n"
254
- else:
255
- markdown += "• Ready for professional patent attorney review\n"
256
- markdown += "• Consider filing provisional patent for priority\n"
257
-
258
  return markdown
259
 
260
- def create_ip_opportunity_cards(opportunities: List[Dict]) -> str:
261
- """Generates IP opportunity cards from backend data."""
262
- if not opportunities:
263
- return ""
264
-
265
- html = """
266
- <div style="background: #f8f9fa; border-radius: 10px; padding: 20px; margin: 20px 0;">
267
- <h4 style="color: #333; margin-bottom: 15px;">Discovered IP Opportunities</h4>
268
- <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 15px;">
269
  """
270
-
271
- for i, opp in enumerate(opportunities):
272
- score = opp.get("score", 75)
273
- color = "#28a745" if score >= 85 else "#ffc107" if score >= 75 else "#17a2b8"
274
-
275
- opp_info = next((o for o in IP_OPPORTUNITIES if o["type"] == opp.get("type")), IP_OPPORTUNITIES[0])
276
-
277
- html += f"""
278
- <div style="background: white; border: 2px solid {color}; border-radius: 8px; padding: 15px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
279
- <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
280
- <h6 style="color: #333; margin: 0; font-size: 1.1em;">{opp.get('type', 'Opportunity')}</h6>
281
- <span style="background: {color}; color: white; padding: 3px 8px; border-radius: 12px; font-size: 0.8em; font-weight: bold;">
282
- {score}/100
283
- </span>
284
- </div>
285
- <p style="color: #666; font-size: 0.9em; margin: 5px 0;">{opp.get('description', '')}</p>
286
- <p style="color: #28a745; font-weight: bold; font-size: 0.8em; margin: 5px 0;">
287
- Market: {opp.get('market_size', 'N/A')}
288
- </p>
289
- </div>
290
- """
291
-
292
- html += """
293
- </div>
294
- </div>
295
  """
296
- return html
297
-
298
- def run_real_ai_analysis(invention_disclosure: str) -> Dict:
299
- """Run the real AI agent analysis on the invention disclosure."""
300
- if not REAL_AI_AGENTS_AVAILABLE:
301
- return {"available": False, "error": "Real AI agents not available"}
302
-
303
- try:
304
- # Initialize the coordinator
305
- coordinator = InterAgentCoordinator()
306
-
307
- # Run comprehensive analysis
308
- results = coordinator.orchestrate_patent_development(invention_disclosure)
309
-
310
- return {
311
- "available": True,
312
- "results": results,
313
- "readiness_score": results.get("overall_readiness_score", 0),
314
- "assessment": results.get("readiness_assessment", "Unknown"),
315
- "technical_analysis": results.get("technical_completeness", {}),
316
- "prior_art_analysis": results.get("prior_art_landscape", {}),
317
- "claim_analysis": results.get("claim_architecture", {})
318
- }
319
- except Exception as e:
320
- return {"available": False, "error": str(e)}
321
 
322
- def format_patent_section(agent_name: str, content: str, thought: str = None, sources: List = None, image_urls: List = None) -> str:
323
- """Enhanced patent section formatting with technical analysis and image generation."""
324
-
325
- # Enhanced Figure Drafter Agent with Gemini and Nebius integration
326
- if agent_name == "Figure Drafter Agent":
327
- try:
328
- # Try Gemini first (preferred for high-quality patent figures)
329
- if GEMINI_IMAGE_AVAILABLE and os.environ.get("GEMINI_API_KEY"):
330
- try:
331
- print("🎨 Activating Gemini 2.0 Flash for patent figure generation...")
332
- generator = GeminiImageGenerator()
333
-
334
- # Extract invention description from content or use a default
335
- # Look for invention context in the content
336
- if "SUMMARY OF THE INVENTION" in content:
337
- # Extract from summary section
338
- start = content.find("SUMMARY OF THE INVENTION") + len("SUMMARY OF THE INVENTION")
339
- end = content.find("'. This would include", start) if "'. This would include" in content[start:] else len(content)
340
- invention_context = content[start:end].strip()[:800]
341
- # Clean up the context
342
- invention_context = invention_context.replace("The present invention relates to", "").replace("The present invention provides", "").strip()
343
- else:
344
- # Fallback: extract a reasonable description from the available content
345
- invention_context = "Passive acoustic liquid level detection system with machine learning analysis"
346
-
347
- print(f"🔍 Extracted invention context: {invention_context[:100]}...")
348
-
349
- gemini_result = generator.integrate_with_patent_architect(invention_context)
350
-
351
- if gemini_result.get("success"):
352
- # COMPLETELY REPLACE the backend content with Gemini-generated content
353
- content = gemini_result["content"]
354
-
355
- # Check if we have dual output (descriptions + LaTeX)
356
- if gemini_result.get("dual_output"):
357
- # Enhanced dual output available
358
- descriptions_available = gemini_result.get("descriptions_available", 0)
359
- latex_available = gemini_result.get("latex_code_available", 0)
360
- compiled_images = gemini_result.get("compiled_images", 0)
361
-
362
- content += f"\n\n*🚀 Enhanced Dual Output: {descriptions_available} technical descriptions + {latex_available} LaTeX/TikZ code sets generated*\n\n"
363
-
364
- if compiled_images > 0:
365
- content += f"*🖼️ {compiled_images} figures successfully compiled to images - View immediately in output folder*\n\n"
366
-
367
- content += f"*💡 Best Experience: Read descriptions above, then use LaTeX code with Overleaf.com for professional figures*\n\n"
368
-
369
- # Update thought to reflect dual output
370
- thought = f"Generated comprehensive dual output with {descriptions_available} detailed technical descriptions AND {latex_available} professional LaTeX/TikZ code sets. Users can read descriptions immediately and compile LaTeX for USPTO-ready vector graphics."
371
-
372
- elif gemini_result.get("images_generated", 0) > 0:
373
- if gemini_result.get("latex_generated", 0) > 0:
374
- content += "\n\n*🎨 Generated LaTeX/TikZ code using Google Gemini 2.0 Flash - Compile with pdflatex to create professional patent figures*\n\n"
375
- content += f"*💡 To view images: Compile the .tex files in `{os.path.expanduser('~')}/patent_architect_figures/`*\n\n"
376
- thought = "Generated professional LaTeX/TikZ code for patent figures using Google Gemini 2.0 Flash. Code can be compiled to create high-quality technical drawings with numbered components and USPTO-ready formatting."
377
- else:
378
- content += "\n\n*🎨 Generated visual patent figures using Google Gemini 2.0 Flash - Professional images ready for USPTO submission*\n\n"
379
- thought = "Generated high-quality patent figures using Google Gemini 2.0 Flash with professional technical drawings, numbered components, and USPTO-ready formatting."
380
- else:
381
- content += "\n\n*📝 Generated detailed patent figure descriptions using Google Gemini 2.0 Flash - Professional technical specifications*\n\n"
382
- thought = "Generated detailed technical specifications for patent figures using Google Gemini 2.0 Flash with professional patent formatting."
383
-
384
- print("✅ Gemini image generation successful - Backend content replaced")
385
-
386
- else:
387
- print(f"❌ Gemini generation failed: {gemini_result.get('error', 'Unknown error')}")
388
-
389
- except Exception as e:
390
- print(f"❌ Gemini integration error: {e}")
391
-
392
- # Fallback to Nebius if Gemini failed or unavailable
393
- elif NEBIUS_AVAILABLE and not image_urls:
394
- try:
395
- if "figure" in content.lower() or "drawing" in content.lower():
396
- figure_descriptions = [
397
- "Cross-sectional view showing main components",
398
- "System diagram showing connections"
399
- ]
400
-
401
- from dotenv import load_dotenv
402
- load_dotenv()
403
-
404
- if os.environ.get("NEBIUS_API_KEY"):
405
- nebius_result = integrate_with_patent_architect(
406
- invention_description="Technical invention with numbered components",
407
- figure_descriptions=figure_descriptions
408
- )
409
-
410
- if nebius_result.get("success"):
411
- content = nebius_result["content"]
412
- image_urls = nebius_result.get("image_urls", [])
413
- content += "\n\n*🖼️ Generated using Nebius AI - Enhanced with visual diagrams*\n\n"
414
- print("✅ Nebius image generation successful")
415
-
416
- except Exception as e:
417
- print(f"❌ Nebius integration error: {e}")
418
-
419
- # If no image generation available, enhance the text-based content
420
- else:
421
- # Check if this is Groq's "no image generation" content
422
- if "image generation is not available with groq" in content.lower() or "since image generation is not available" in content.lower():
423
- # Replace Groq's limitation message with enhancement message
424
- content = content.replace(
425
- "Generated detailed text descriptions for patent figures since image generation is not available with Groq.",
426
- "Enhanced patent figure descriptions with detailed technical specifications."
427
- )
428
- content = content.replace(
429
- "Since image generation is not available with Groq, here are detailed descriptions",
430
- "Enhanced technical figure descriptions with professional patent formatting"
431
- )
432
- content += f"\n\n*💡 To enable professional image generation: Set GEMINI_API_KEY environment variable and get API key from https://makersuite.google.com/app/apikey*\n\n"
433
-
434
- # Add critique-based improvements to figure descriptions
435
- content += "\n\n### 🎯 Figure Enhancement Recommendations:\n"
436
- content += "• **Missing Elements:** Numbered components, dimension lines, material callouts\n"
437
- content += "• **Technical Precision:** Frequency response curves, signal processing flow\n"
438
- content += "• **Patent Standards:** USPTO figure requirements compliance\n"
439
- content += "• **Professional Quality:** Vector graphics suitable for patent submission\n\n"
440
-
441
- print("✅ Enhanced Groq content with detailed recommendations")
442
-
443
- except Exception as e:
444
- print(f"❌ Figure generation error: {e}")
445
- content += f"\n\n*⚠️ Image generation unavailable. Please check API configuration.*\n\n"
446
-
447
- # Enhanced Prior Art Agent feedback
448
- elif agent_name == "Prior Art Agent":
449
- # Count sources and provide detailed analysis
450
- num_sources = len(sources) if sources else 0
451
-
452
- if num_sources < 10:
453
- content += f"\n\n### ⚠️ Prior Art Search Limitations:\n"
454
- content += f"• **Sources Found:** Only {num_sources} patents/publications\n"
455
- content += f"• **Missing Domains:** Ultrasonic sensors, acoustic emission monitoring, vibration analysis\n"
456
- content += f"• **Incomplete Coverage:** International patents, academic literature, industry standards\n"
457
- content += f"• **Recommendation:** Comprehensive search required before filing\n\n"
458
-
459
- content += f"### 🔍 Suggested Additional Search Terms:\n"
460
- content += f"• Ultrasonic level detection patents\n"
461
- content += f"• Acoustic emission sensors\n"
462
- content += f"• Passive vibration monitoring\n"
463
- content += f"• Machine learning signal processing\n"
464
- content += f"• Non-invasive liquid measurement\n\n"
465
-
466
- # Enhanced Claims Strategy Agent feedback
467
- elif agent_name == "Claims Drafter Agent": # Fixed: Backend sends "Claims Drafter Agent"
468
- # Analyze claims for common issues
469
- if "acoustic sensor" in content.lower() and "passive" in content.lower():
470
- content += f"\n\n### ⚠️ Claims Analysis - Critical Issues:\n"
471
- content += f"• **Overly Broad:** Claims 1 likely lacks novelty (passive acoustic sensors exist)\n"
472
- content += f"• **Missing Specificity:** No technical limitations on frequency analysis method\n"
473
- content += f"• **Weak Differentiation:** Doesn't capture unique ML training approach\n"
474
- content += f"• **Patent Risk:** Current claims may be rejected for obviousness\n\n"
475
-
476
- content += f"### 🎯 Recommended Claim Improvements:\n"
477
- content += f"• Focus on specific frequency change detection method\n"
478
- content += f"• Add ML model architecture and training claims\n"
479
- content += f"• Include anomaly detection for bubbles/splashes\n"
480
- content += f"• Define technical parameters (frequency ranges, sensitivity)\n\n"
481
-
482
- # Format agent response with enhanced personality
483
- if agent_name in AGENT_PERSONALITIES:
484
- personality = AGENT_PERSONALITIES[agent_name]
485
-
486
- formatted = f"### {agent_name}\n\n"
487
-
488
- # Add thinking process if available
489
- if thought:
490
- formatted += f"**Agent Analysis:**\n{thought}\n\n"
491
-
492
- formatted += content
493
-
494
- # Add enhanced strategy note with expertise
495
- formatted += f"\n\n*Strategy: {personality['bias']}*\n"
496
- formatted += f"*Expertise: {personality.get('expertise', 'General patent analysis')}*\n\n"
497
-
498
- else:
499
- # Fallback for unknown agents
500
- formatted = f"### {agent_name}\n\n"
501
- if thought:
502
- formatted += f"**Analysis:** {thought}\n\n"
503
- formatted += content
504
-
505
- # Add sources if available with enhanced formatting
506
- if sources and len(sources) > 0:
507
- formatted += "\n\n**📚 Prior Art Sources:**\n"
508
- for i, source in enumerate(sources, 1):
509
- if source.get('url'):
510
- formatted += f"{i}. [{source.get('title', 'Patent Source')}]({source.get('url')})\n"
511
-
512
- # Add search quality assessment
513
- if len(sources) < 10:
514
- formatted += f"\n*⚠️ Limited search results ({len(sources)} sources). Comprehensive search recommended.*\n"
515
-
516
- return formatted
517
 
518
- def run_patent_architect_in_ui(invention_disclosure):
519
- """Enhanced UI function with agent personalities and IP discovery."""
520
  if not invention_disclosure:
521
- # Reset to initial state if input is cleared
522
- outputs = {
523
- "opportunities": gr.HTML.update(value="<h3>IP Opportunities</h3><p>Enter invention to discover patent opportunities</p>"),
524
- "negotiation": gr.Markdown.update(value="### Agent Negotiation\n\nAgents will negotiate optimal strategy"),
525
- "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.*"),
526
- "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.*"),
527
- "figures": gr.Markdown.update(value="### Technical Figures\n\n*This section will display the generated patent-style technical drawings with numbered components.*"),
528
- "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.*"),
529
- "status": "Enhanced Patent Architect v2 - Ready for rigorous technical analysis",
530
- }
531
- yield list(outputs.values())
532
  return
533
 
534
- if not MODAL_BACKEND_URL:
535
- error_msg = "**Backend Configuration Required**\n\nPlease deploy the Patent Architect backend and update the `MODAL_BACKEND_URL` configuration."
536
- yield error_msg, error_msg, error_msg, error_msg, "Configuration Error"
 
537
  return
538
-
539
- # Initialize all sections with clean interface
540
- opportunities_html = create_ip_opportunity_cards([])
541
-
542
- # Run real AI analysis if available
543
- real_ai_results = None
544
- if REAL_AI_AGENTS_AVAILABLE:
545
- status = "🤖 Running Real AI Agent Analysis..."
546
- yield opportunities_html, "### Real AI Analysis\n\nRunning comprehensive technical analysis...", "### Prior Art Analysis\n\n*Waiting for technical analysis...*", "### Invention Summary\n\n*Waiting for analysis...*", "### Technical Figures\n\n*Waiting for analysis...*", "### Patent Claims\n\n*Waiting for analysis...*", status
547
 
548
- real_ai_results = run_real_ai_analysis(invention_disclosure)
549
-
550
- if real_ai_results.get("available"):
551
- status = f"✅ Real AI Analysis Complete - Readiness: {real_ai_results['readiness_score']*100:.1f}%"
552
- else:
553
- status = f"⚠️ Real AI Analysis Failed: {real_ai_results.get('error', 'Unknown error')}"
554
 
555
- negotiation_display = create_agent_negotiation_display([], real_ai_results)
556
- prior_art_section = "### Prior Art Analysis\n\n*Prior Art Specialist is searching patent databases...*"
557
- summary_section = "### Invention Summary\n\n*Technical Writer is awaiting prior art analysis...*"
558
- figures_section = "### Technical Figures\n\n*Technical Illustrator is awaiting invention summary...*"
559
- claims_section = "### Patent Claims\n\n*Patent Attorney is awaiting technical figures...*"
560
- status = "Starting Patent Architect with Strategic Analysis..."
561
-
562
- yield opportunities_html, negotiation_display, prior_art_section, summary_section, figures_section, claims_section, status
563
-
564
- try:
565
- print(f"Connecting to Patent Architect backend: {MODAL_BACKEND_URL}")
566
 
567
- # Initialize agent response tracker
568
- agent_responses = []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
569
 
570
- with requests.post(
571
- f"{MODAL_BACKEND_URL}/generate_patent",
572
- json={"invention_disclosure": invention_disclosure},
573
- timeout=1800, # 30 minute timeout for full patent generation
574
- stream=True
575
- ) as response:
576
- response.raise_for_status()
577
 
578
- for line in response.iter_lines():
579
- if line:
580
- decoded_line = line.decode('utf-8')
581
- if decoded_line.startswith('data: '):
582
- try:
583
- event = json.loads(decoded_line[6:])
584
- print(f"DEBUG: Received event from backend: {event}") # Print event for debugging
585
- event_status = event.get("status")
586
-
587
- if event_status == "starting":
588
- status = event.get("log", "Starting...")
589
-
590
- elif event_status == "running":
591
- status = event.get("log", "Processing...")
592
-
593
- elif event_status == "update":
594
- data = event.get("data", {})
595
- step_info = event.get("step", "")
596
- section_type = data.get("section_type")
597
-
598
- # This block handles the new IP Opportunities data
599
- if section_type == "ip_opportunities":
600
- opportunities = data.get("data", {}).get("opportunities", [])
601
- opportunities_html = create_ip_opportunity_cards(opportunities)
602
- prior_art_section = "### Prior Art Analysis\n\n*Prior Art Specialist is searching patent databases...*"
603
- status = f"Step {step_info} Complete: IP Opportunity Agent found {len(opportunities)} new avenues"
604
- yield opportunities_html, negotiation_display, prior_art_section, summary_section, figures_section, claims_section, status
605
- continue
606
-
607
- agent_name = data.get("agent_name", "Patent Agent")
608
- content = data.get("content", "")
609
- thought = data.get("thought", "")
610
- sources = data.get("sources", [])
611
- image_urls = data.get("image_urls", [])
612
-
613
- formatted_content = format_patent_section(agent_name, content, thought, sources, image_urls)
614
-
615
- # Update the appropriate section based on the agent's designated section_type
616
- if section_type == "prior_art":
617
- prior_art_section = formatted_content
618
- summary_section = "### Invention Summary\n\n*Technical Writer is crafting your invention story...*"
619
-
620
- # Update negotiation based on real patent count
621
- num_patents = len(sources)
622
- agent_responses = [{"name": agent_name, "num_patents": num_patents}]
623
- negotiation_display = create_agent_negotiation_display(agent_responses, real_ai_results)
624
-
625
- elif section_type == "summary":
626
- summary_section = formatted_content
627
- figures_section = "### Technical Figures\n\n*Technical Illustrator is designing patent drawings...*"
628
-
629
- # This assumes prior_art ran first and initialized agent_responses
630
- agent_responses.append({"name": agent_name})
631
- negotiation_display = create_agent_negotiation_display(agent_responses, real_ai_results)
632
-
633
- elif section_type == "figures":
634
- figures_section = formatted_content
635
- claims_section = "### Patent Claims\n\n*Patent Attorney is optimizing claim scope...*"
636
-
637
- agent_responses.append({"name": agent_name})
638
- negotiation_display = create_agent_negotiation_display(agent_responses, real_ai_results)
639
-
640
- elif section_type == "claims":
641
- claims_section = formatted_content
642
-
643
- agent_responses.append({"name": agent_name})
644
- negotiation_display = create_agent_negotiation_display(agent_responses, real_ai_results)
645
-
646
- # Enhanced status with agent personality
647
- if agent_name in AGENT_PERSONALITIES:
648
- personality = AGENT_PERSONALITIES[agent_name]["personality"]
649
- status = f"Step {step_info} Complete: {personality} has finished their analysis"
650
- else:
651
- status = f"Step {step_info} Complete: {agent_name} finished"
652
-
653
- elif event_status == "assembling":
654
- status = event.get("log", "Assembling patent application...")
655
-
656
- elif event_status == "complete":
657
- status = "Patent Application Complete - Ready for review and filing"
658
-
659
- yield opportunities_html, negotiation_display, prior_art_section, summary_section, figures_section, claims_section, status
660
-
661
- except json.JSONDecodeError as e:
662
- print(f"Could not decode JSON from stream: {decoded_line}")
663
- continue
664
 
665
- except requests.exceptions.RequestException as e:
666
- error_msg = f"Connection Error: {str(e)}\n\nPlease check that the Patent Architect backend is deployed and accessible."
667
- status = "Connection Failed"
668
- yield opportunities_html, negotiation_display, prior_art_section, summary_section, figures_section, claims_section, status
669
 
670
  with gr.Blocks(theme=gr.themes.Base(primary_hue="green", neutral_hue="slate"), title="Patent Architect v2") as demo:
671
  gr.HTML("""
@@ -709,7 +218,7 @@ with gr.Blocks(theme=gr.themes.Base(primary_hue="green", neutral_hue="slate"), t
709
  color: #00ff41;
710
  opacity: 0.8;
711
  position: relative;
712
- z-index: 1;">POWERED BY GEMINI NEURAL NETWORKS + AUTONOMOUS AI AGENTS</p>
713
  </div>
714
  """)
715
 
@@ -795,25 +304,17 @@ with gr.Blocks(theme=gr.themes.Base(primary_hue="green", neutral_hue="slate"), t
795
  invention_input = gr.Textbox(
796
  lines=12,
797
  label="Neural Disclosure Interface",
798
- placeholder="""Initialize invention parameters:
799
-
800
- Problem identification and solution matrix
801
- ▶ Technical architecture and component flow
802
- ▶ Novelty differentiators vs existing systems
803
- ▶ Advantage metrics and performance data
804
- ▶ Technical specifications and parameters
805
-
806
- EXAMPLE NEURAL INPUT: "Autonomous beverage temperature regulation system utilizing phase-change material matrices with neural app integration, eliminating thermal degradation issues through adaptive preference algorithms..."
807
- """,
808
- info="Enhanced neural processing requires detailed technical specifications"
809
  )
810
 
811
- generate_btn = gr.Button("INITIATE PATENT SYNTHESIS", variant="primary", size="lg")
812
 
813
  status_display = gr.Textbox(
814
  label="System Status",
815
  interactive=False,
816
- value="PATENT ARCHITECT v2 - Neural Networks Online - Agents Ready"
817
  )
818
 
819
  gr.HTML("""
@@ -824,7 +325,6 @@ EXAMPLE NEURAL INPUT: "Autonomous beverage temperature regulation system utilizi
824
  </div>
825
  """)
826
 
827
- # Enhanced Technical Intelligence Dashboard
828
  gr.HTML("""
829
  <div style="background: linear-gradient(45deg, #0a0a0a, #1a1a1a);
830
  border: 1px solid #ff8c00;
@@ -836,25 +336,14 @@ EXAMPLE NEURAL INPUT: "Autonomous beverage temperature regulation system utilizi
836
  text-shadow: 0 0 5px #ff8c00;
837
  font-size: 1.6em;
838
  margin: 0;
839
- text-transform: uppercase;">NEURAL ANALYSIS & IP STRATEGY MATRIX</h2>
840
  </div>
841
  """)
842
 
843
  with gr.Row():
844
- with gr.Column():
845
- opportunities_display = gr.HTML("""
846
- <div style="background: linear-gradient(45deg, #0a0a0a, #1a1a1a);
847
- border: 1px solid #00ff41;
848
- padding: 15px;
849
- color: #00ff41;
850
- font-family: 'Courier New', monospace;">
851
- <h3 style="color: #00ff41; margin: 0;">IP OPPORTUNITY MATRIX</h3>
852
- <p style="color: #ff8c00;">Patent vectors will materialize here</p>
853
- </div>
854
- """)
855
- with gr.Column():
856
- negotiation_display = gr.Markdown("### AGENT NEGOTIATION PROTOCOL\n\nMulti-agent consensus algorithm initializing...")
857
-
858
  gr.HTML("""
859
  <div style="height: 2px;
860
  background: linear-gradient(90deg, #ff8c00, #ffff00, #00ff41, #ff8c00);
@@ -874,47 +363,46 @@ EXAMPLE NEURAL INPUT: "Autonomous beverage temperature regulation system utilizi
874
  text-shadow: 0 0 5px #00ff41;
875
  font-size: 1.6em;
876
  margin: 0;
877
- text-transform: uppercase;">GENERATED PATENT APPLICATION</h2>
878
  </div>
879
  """)
880
 
881
  with gr.Tabs():
882
- with gr.TabItem("PRIOR ART ANALYSIS"):
883
  prior_art_output = gr.Markdown(
884
- value="### Prior Art Analysis\n\nNeural Prior Art Detective scanning patent databases..."
885
  )
886
  with gr.TabItem("TECHNICAL SUMMARY"):
887
  summary_output = gr.Markdown(
888
- value="### Invention Summary\n\nTechnical Writer synthesizing narrative structure..."
889
  )
890
  with gr.TabItem("TECHNICAL FIGURES"):
891
  figures_output = gr.Markdown(
892
- value="### Technical Figures\n\nFigure Synthesizer generating visual documentation matrix..."
893
  )
894
  with gr.TabItem("PATENT CLAIMS"):
895
  claims_output = gr.Markdown(
896
- value="### Patent Claims\n\nClaims Architect optimizing legal protection boundaries..."
897
  )
898
 
899
  generate_btn.click(
900
  fn=run_patent_architect_in_ui,
901
  inputs=[invention_input],
902
- outputs=[opportunities_display, negotiation_display, prior_art_output, summary_output, figures_output, claims_output, status_display]
903
  )
904
 
905
  gr.Examples(
906
  [
907
- ["A smart medication adherence system with computer vision verification using a 5MP CMOS sensor and YOLOv8 object detection model. The system analyzes pill shape, color, and size against a trained database of 2000+ medications with 99.2% accuracy. Real-time alerts are sent via LoRaWAN to healthcare providers when missed doses exceed 12-hour thresholds. The system includes tamper detection through RFID tags and integrates with EMR systems via FHIR protocol for comprehensive compliance monitoring."],
908
- ["A modular vertical farming system with adaptive LED lighting using full-spectrum arrays (400-700nm) controlled by neural network analysis of plant reflectance spectra. The system employs RGB+NIR sensors to monitor chlorophyll content and adjusts light intensity (50-1000 μmol/m²/s) and spectrum ratios based on growth stage detection. Machine learning models trained on 500+ crop cycles optimize photosynthetic photon flux density while reducing energy consumption by 35% compared to static lighting systems."],
909
- ["A real-time presentation skills assessment device using micro-expression analysis with 60fps facial recognition and voice stress analysis at 16kHz sampling. The system employs convolutional neural networks trained on 10,000+ presentation recordings to detect confidence indicators including facial micro-movements, vocal pitch variations (±50Hz accuracy), and gesture patterns. Feedback is provided through bone conduction audio and haptic vibration patterns calibrated to individual baseline metrics."],
910
  ],
911
  inputs=[invention_input],
912
- label="NEURAL TRAINING EXAMPLES | High-Specification Technical Inputs"
913
  )
914
 
915
  gr.HTML("""
916
  <style>
917
- /* Neon Noir 80s Button Styling */
918
  .gradio-button.primary {
919
  background: linear-gradient(45deg, #00ff41, #ffff00) !important;
920
  border: 2px solid #00ff41 !important;
@@ -935,13 +423,11 @@ EXAMPLE NEURAL INPUT: "Autonomous beverage temperature regulation system utilizi
935
  border-color: #ffff00 !important;
936
  }
937
 
938
- /* Dark theme for the overall interface */
939
  .gradio-container {
940
  background: #0a0a0a !important;
941
  font-family: 'Courier New', monospace !important;
942
  }
943
 
944
- /* Tab styling */
945
  .tab-nav button {
946
  background: linear-gradient(45deg, #1a1a1a, #0a0a0a) !important;
947
  border: 1px solid #00ff41 !important;
@@ -957,7 +443,6 @@ EXAMPLE NEURAL INPUT: "Autonomous beverage temperature regulation system utilizi
957
  box-shadow: 0 0 10px #00ff41 !important;
958
  }
959
 
960
- /* Input field styling */
961
  .gr-textbox {
962
  background: linear-gradient(45deg, #0a0a0a, #1a1a1a) !important;
963
  border: 1px solid #00ff41 !important;
@@ -970,69 +455,19 @@ EXAMPLE NEURAL INPUT: "Autonomous beverage temperature regulation system utilizi
970
  box-shadow: 0 0 10px #ffff00 !important;
971
  }
972
 
973
- /* Remove default fonts and prevent loading errors */
974
  * {
975
  font-family: 'Courier New', monospace !important;
976
  }
977
-
978
- /* Scanline effect overlay */
979
- body::before {
980
- content: '';
981
- position: fixed;
982
- top: 0;
983
- left: 0;
984
- width: 100%;
985
- height: 100%;
986
- background: repeating-linear-gradient(
987
- 0deg,
988
- transparent,
989
- transparent 2px,
990
- rgba(0,255,65,0.03) 2px,
991
- rgba(0,255,65,0.03) 4px
992
- );
993
- pointer-events: none;
994
- z-index: 1000;
995
- }
996
  </style>
997
-
998
- <script>
999
- // Suppress browser errors and warnings
1000
- const originalConsoleError = console.error;
1001
- console.error = function(...args) {
1002
- const message = args.join(' ');
1003
- if (message.includes('manifest.json') ||
1004
- message.includes('Failed to load resource') ||
1005
- message.includes('postMessage') ||
1006
- message.includes('preload CSS') ||
1007
- message.includes('.woff2')) {
1008
- return; // Skip these specific errors
1009
- }
1010
- originalConsoleError.apply(console, args);
1011
- };
1012
-
1013
- // Add glitch effect to title
1014
- document.addEventListener('DOMContentLoaded', function() {
1015
- const title = document.querySelector('h1');
1016
- if (title) {
1017
- setInterval(() => {
1018
- if (Math.random() < 0.1) {
1019
- title.style.textShadow = '2px 0 #ff8c00, -2px 0 #00ff41';
1020
- setTimeout(() => {
1021
- title.style.textShadow = '0 0 10px #00ff41, 0 0 20px #00ff41, 0 0 30px #00ff41';
1022
- }, 100);
1023
- }
1024
- }, 2000);
1025
- }
1026
- });
1027
- </script>
1028
  """)
1029
 
1030
  if __name__ == "__main__":
1031
- print("PATENT ARCHITECT v2 - Enhanced with Google Gemini 2.0 Flash + Real AI Agents")
1032
- print(f"Backend: {MODAL_BACKEND_URL}")
1033
- print(f"Gemini Image Generation: {'ONLINE' if GEMINI_IMAGE_AVAILABLE else 'OFFLINE'}")
1034
- print(f"Real AI Agents: {'ONLINE' if REAL_AI_AGENTS_AVAILABLE else 'OFFLINE'}")
1035
- print(f"Nebius Fallback: {'ONLINE' if NEBIUS_AVAILABLE else 'OFFLINE'}")
 
1036
  demo.queue().launch(
1037
  share=False,
1038
  show_error=True
 
2
  import os
3
  import requests
4
  import json
5
+ from typing import Dict, List, Generator, Optional
6
  from dotenv import load_dotenv
7
+ import base64
8
+ import tempfile
9
+ import re
10
+ import urllib.parse
11
 
12
  # Load environment variables from .env file
13
  load_dotenv()
14
 
15
+ # --- New Agentic Backend Integration ---
16
+ try:
17
+ from real_ai_agents_implementation import AgenticNegotiator, NegotiationState
18
+ AGENTIC_BACKEND_AVAILABLE = True
19
+ except ImportError as e:
20
+ print(f"Failed to import agentic backend: {e}")
21
+ AGENTIC_BACKEND_AVAILABLE = False
22
+
23
+ # Keep Gemini Image Generator for LaTeX compilation
24
  try:
25
  from gemini_image_generator import GeminiImageGenerator
26
  GEMINI_IMAGE_AVAILABLE = True
27
  except ImportError:
28
  GEMINI_IMAGE_AVAILABLE = False
29
 
30
+ def compile_latex_to_image(latex_code: str) -> Optional[str]:
31
+ """Try to compile LaTeX code to an image using a web service."""
32
+ if not latex_code:
33
+ return None
34
+ try:
35
+ # Prepare the LaTeX code by finding the relevant part
36
+ # A more robust regex to find either a full document or just a tikzpicture
37
+ match = re.search(r'(\\documentclass.*?\\end{document})|(\\begin{tikzpicture}.*?\\end{tikzpicture})', latex_code, re.DOTALL)
38
+ if match:
39
+ # Prioritize the full document if both are somehow present, otherwise take what was found
40
+ content_to_render = match.group(1) if match.group(1) else match.group(2)
41
+ else:
42
+ # Fallback if no standard block is found
43
+ content_to_render = latex_code
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
 
45
+ # URL encode the LaTeX content for the API
46
+ encoded_latex = urllib.parse.quote(content_to_render)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
 
48
+ # Use a reliable web service for compilation
49
+ api_url = f"https://latex.codecogs.com/png.latex?{encoded_latex}"
 
 
 
 
50
 
51
+ response = requests.get(api_url, timeout=20)
52
+ if response.status_code == 200 and response.headers.get('content-type', '').startswith('image/'):
53
+ # Convert the successful image response to a base64 data URI
54
+ image_b64 = base64.b64encode(response.content).decode('utf-8')
55
+ return f"data:image/png;base64,{image_b64}"
56
+ else:
57
+ print(f"LaTeX compilation failed with status: {response.status_code}")
58
+ return None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
 
60
+ except Exception as e:
61
+ print(f"An error occurred during LaTeX compilation: {e}")
62
+ return None
63
+
64
+ def create_negotiation_transcript_display(transcript: List[Dict]) -> str:
65
+ """Creates a markdown display for the agent negotiation transcript."""
66
+ if not transcript:
67
+ return "### Agent Negotiation Log\n\n*Awaiting instructions...*"
68
+
69
+ markdown = "### Agent Negotiation Log\n\n---\n\n"
70
+ for entry in transcript:
71
+ agent = entry.get('agent', 'System')
72
+ message = entry.get('message', '')
73
+
74
+ # Make the agent name bold and add color
75
+ if agent == "Chief Strategist":
76
+ color = "#ff8c00" # Orange
77
+ elif agent == "Conceptual Artist":
78
+ color = "#da70d6" # Orchid
79
+ elif agent == "System":
80
+ color = "#ff4d4d" # Red
81
+ else:
82
+ color = "#00ff41" # Green
83
 
84
+ markdown += f"<p style='color: {color}; margin-bottom: 5px;'><strong>🤖 {agent}:</strong></p>\n"
85
+ markdown += f"<p style='margin-left: 20px; margin-top: 0px;'>{message}</p>\n\n"
86
+ markdown += "---\n\n"
87
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  return markdown
89
 
90
+ def run_patent_architect_in_ui(invention_disclosure: str) -> Generator[List, None, None]:
 
 
 
 
 
 
 
 
91
  """
92
+ This is the new main UI function that runs the true agentic workflow.
93
+ It no longer calls an external backend.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  """
95
+ # Initial state for all output fields
96
+ negotiation_html = create_negotiation_transcript_display([])
97
+ prior_art_section = "### Prior Art Analysis\n\n*Awaiting agent analysis...*"
98
+ summary_section = "### Invention Summary\n\n*Awaiting agent analysis...*"
99
+ figures_section = "### Technical Figures\n\n*Awaiting agent analysis...*"
100
+ claims_section = "### Patent Claims\n\n*Awaiting agent analysis...*"
101
+ status = "System Initialized."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
 
103
+ yield [negotiation_html, prior_art_section, summary_section, figures_section, claims_section, status]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
 
 
105
  if not invention_disclosure:
106
+ status = "Please provide an invention disclosure."
107
+ yield [negotiation_html, prior_art_section, summary_section, figures_section, claims_section, status]
 
 
 
 
 
 
 
 
 
108
  return
109
 
110
+ if not AGENTIC_BACKEND_AVAILABLE:
111
+ status = "ERROR: The agentic backend is not available. Check server logs."
112
+ negotiation_html = create_negotiation_transcript_display([{"agent": "System", "message": "CRITICAL ERROR: Could not import `AgenticNegotiator`. The application cannot run."}])
113
+ yield [negotiation_html, prior_art_section, summary_section, figures_section, claims_section, status]
114
  return
 
 
 
 
 
 
 
 
 
115
 
116
+ # --- Start the Real Agentic Workflow ---
117
+ negotiator = AgenticNegotiator(invention_disclosure)
 
 
 
 
118
 
119
+ final_state = None
120
+ for state in negotiator.run_negotiation():
121
+ final_state = state
122
+
123
+ # Update negotiation transcript
124
+ negotiation_html = create_negotiation_transcript_display(state.negotiation_transcript)
 
 
 
 
 
125
 
126
+ # Update status from the last message
127
+ if state.negotiation_transcript:
128
+ last_entry = state.negotiation_transcript[-1]
129
+ status = f"Active Agent: {last_entry['agent']}"
130
+
131
+ # As prior art becomes available, display it
132
+ if state.prior_art_analysis:
133
+ pa_data = state.prior_art_analysis
134
+ prior_art_section = f"### Prior Art & Strategy\n\n"
135
+ if state.strategic_mandate:
136
+ prior_art_section += f"**Strategic Mandate:**\n> {state.strategic_mandate}\n\n---\n\n"
137
+ prior_art_section += f"**Landscape Summary:** {pa_data.get('landscape_summary', 'N/A')}\n\n"
138
+ prior_art_section += f"**Key Concepts Identified:**\n"
139
+ for concept in pa_data.get('key_concepts', []):
140
+ prior_art_section += f"- {concept}\n"
141
+ prior_art_section += "\n**Simulated Representative Prior Art:**\n"
142
+ for art in pa_data.get('simulated_prior_art', []):
143
+ prior_art_section += f"- {art}\n"
144
+
145
+ # As sections get generated, display them
146
+ if state.technical_summary:
147
+ summary_section = f"### Invention Summary\n\n{state.technical_summary}"
148
 
149
+ if state.patent_claims:
150
+ claims_section = f"### Patent Claims\n\n{state.patent_claims}"
 
 
 
 
 
151
 
152
+ # Handle both Ideogram image and LaTeX figure description
153
+ if state.ideogram_image_b64 or state.figure_description:
154
+ figures_section = "### Technical Figures\n\n"
155
+
156
+ # Display the Ideogram image if it exists
157
+ if state.ideogram_image_b64:
158
+ figures_section += "### Conceptual Image (from Ideogram API)\n"
159
+ image_html = f"<img src='data:image/jpeg;base64,{state.ideogram_image_b64}' alt='Generated Conceptual Image' style='max-width: 100%; height: auto; border: 2px solid #ff8c00;'>"
160
+ figures_section += image_html + "\n\n---\n\n"
161
+
162
+ # Display the LaTeX figure description and compiled image if it exists
163
+ if state.figure_description:
164
+ figures_section += "### Technical Figure (from LaTeX)\n"
165
+ compiled_latex_image_uri = compile_latex_to_image(state.figure_description)
166
+ if compiled_latex_image_uri:
167
+ figures_section += f"<img src='{compiled_latex_image_uri}' alt='Compiled LaTeX Figure' style='max-width: 100%; height: auto; border: 2px solid #00ff41; background: white; padding: 10px;'>\n\n"
168
+ else:
169
+ figures_section += "*LaTeX compilation failed. Displaying raw code.*\n\n"
170
+
171
+ figures_section += "#### Raw LaTeX/TikZ Code:\n"
172
+ figures_section += state.figure_description
173
+
174
+ yield [negotiation_html, prior_art_section, summary_section, figures_section, claims_section, status]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
 
176
+ status = "Agentic Negotiation Complete."
177
+ yield [negotiation_html, prior_art_section, summary_section, figures_section, claims_section, status]
 
 
178
 
179
  with gr.Blocks(theme=gr.themes.Base(primary_hue="green", neutral_hue="slate"), title="Patent Architect v2") as demo:
180
  gr.HTML("""
 
218
  color: #00ff41;
219
  opacity: 0.8;
220
  position: relative;
221
+ z-index: 1;">POWERED BY GEMINI & IDEOGRAM 3.0 + AUTONOMOUS AI AGENTS</p>
222
  </div>
223
  """)
224
 
 
304
  invention_input = gr.Textbox(
305
  lines=12,
306
  label="Neural Disclosure Interface",
307
+ placeholder="""Enter your invention disclosure here. Be as detailed as possible.
308
+ The agentic system will analyze your input, formulate a patent strategy, and generate a draft application based on that strategy.""",
309
+ info="The new agentic backend requires a detailed technical disclosure to function effectively."
 
 
 
 
 
 
 
 
310
  )
311
 
312
+ generate_btn = gr.Button("INITIATE AGENTIC NEGOTIATION", variant="primary", size="lg")
313
 
314
  status_display = gr.Textbox(
315
  label="System Status",
316
  interactive=False,
317
+ value="AGENTIC WORKFLOW READY"
318
  )
319
 
320
  gr.HTML("""
 
325
  </div>
326
  """)
327
 
 
328
  gr.HTML("""
329
  <div style="background: linear-gradient(45deg, #0a0a0a, #1a1a1a);
330
  border: 1px solid #ff8c00;
 
336
  text-shadow: 0 0 5px #ff8c00;
337
  font-size: 1.6em;
338
  margin: 0;
339
+ text-transform: uppercase;">LIVE AGENT NEGOTIATION & STRATEGY</h2>
340
  </div>
341
  """)
342
 
343
  with gr.Row():
344
+ with gr.Column(scale=2):
345
+ negotiation_display = gr.HTML("...")
346
+
 
 
 
 
 
 
 
 
 
 
 
347
  gr.HTML("""
348
  <div style="height: 2px;
349
  background: linear-gradient(90deg, #ff8c00, #ffff00, #00ff41, #ff8c00);
 
363
  text-shadow: 0 0 5px #00ff41;
364
  font-size: 1.6em;
365
  margin: 0;
366
+ text-transform: uppercase;">STRATEGY-ALIGNED PATENT DRAFT</h2>
367
  </div>
368
  """)
369
 
370
  with gr.Tabs():
371
+ with gr.TabItem("PRIOR ART & STRATEGY"):
372
  prior_art_output = gr.Markdown(
373
+ value="### Prior Art Analysis\n\n*Results of the Prior Art Detective's investigation will appear here.*"
374
  )
375
  with gr.TabItem("TECHNICAL SUMMARY"):
376
  summary_output = gr.Markdown(
377
+ value="### Invention Summary\n\n*The Technical Writer's summary, aligned with the final strategy, will appear here.*"
378
  )
379
  with gr.TabItem("TECHNICAL FIGURES"):
380
  figures_output = gr.Markdown(
381
+ value="### Technical Figures\n\n*The Figure Drafter's output, illustrating the core strategic concept, will appear here.*"
382
  )
383
  with gr.TabItem("PATENT CLAIMS"):
384
  claims_output = gr.Markdown(
385
+ value="### Patent Claims\n\n*The Claims Drafter's claims, focused on the strategic mandate, will appear here.*"
386
  )
387
 
388
  generate_btn.click(
389
  fn=run_patent_architect_in_ui,
390
  inputs=[invention_input],
391
+ outputs=[negotiation_display, prior_art_output, summary_output, figures_output, claims_output, status_display]
392
  )
393
 
394
  gr.Examples(
395
  [
396
+ ["My invention is a smart coffee mug that uses a novel phase-change material to keep coffee at a perfect temperature. It also has a mobile app that connects via Bluetooth to let the user set their preferred temperature. The key innovation is a machine learning algorithm that learns the user's drinking habits to pre-warm or cool the mug, optimizing energy use."],
397
+ ["A modular vertical farming system with adaptive LED lighting using full-spectrum arrays (400-700nm) controlled by neural network analysis of plant reflectance spectra. The system employs RGB+NIR sensors to monitor chlorophyll content and adjusts light intensity (50-1000 μmol/m²/s) and spectrum ratios based on growth stage detection. Machine learning models trained on 500+ crop cycles optimize photosynthetic photon flux density while reducing energy consumption by 35% compared to static lighting systems."],
 
398
  ],
399
  inputs=[invention_input],
400
+ label="HIGH-SPECIFICATION TECHNICAL INPUT EXAMPLES"
401
  )
402
 
403
  gr.HTML("""
404
  <style>
405
+ /* Style remains the same */
406
  .gradio-button.primary {
407
  background: linear-gradient(45deg, #00ff41, #ffff00) !important;
408
  border: 2px solid #00ff41 !important;
 
423
  border-color: #ffff00 !important;
424
  }
425
 
 
426
  .gradio-container {
427
  background: #0a0a0a !important;
428
  font-family: 'Courier New', monospace !important;
429
  }
430
 
 
431
  .tab-nav button {
432
  background: linear-gradient(45deg, #1a1a1a, #0a0a0a) !important;
433
  border: 1px solid #00ff41 !important;
 
443
  box-shadow: 0 0 10px #00ff41 !important;
444
  }
445
 
 
446
  .gr-textbox {
447
  background: linear-gradient(45deg, #0a0a0a, #1a1a1a) !important;
448
  border: 1px solid #00ff41 !important;
 
455
  box-shadow: 0 0 10px #ffff00 !important;
456
  }
457
 
 
458
  * {
459
  font-family: 'Courier New', monospace !important;
460
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
461
  </style>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
462
  """)
463
 
464
  if __name__ == "__main__":
465
+ print("PATENT ARCHITECT v2 - True Agentic Negotiation Workflow")
466
+ print(f"Agentic Backend: {'ONLINE' if AGENTIC_BACKEND_AVAILABLE else 'OFFLINE'}")
467
+ if not os.getenv("GEMINI_API_KEY"):
468
+ print("⚠️ WARNING: GEMINI_API_KEY environment variable not set. Gemini-powered agents will not function.")
469
+ if not os.getenv("SEGMIND_API_KEY"):
470
+ print("⚠️ WARNING: SEGMIND_API_KEY environment variable not set. Ideogram image generation will not function.")
471
  demo.queue().launch(
472
  share=False,
473
  show_error=True
real_ai_agents_implementation.py CHANGED
@@ -1,551 +1,320 @@
1
  #!/usr/bin/env python3
2
  """
3
- Real AI Agent Implementation for Patent Architect AI v2
4
- Designed by thinking like both an IP expert and AI agent expert.
5
-
6
- These agents address actual patent attorney pain points with measurable business value.
7
  """
8
 
9
- import re
10
  import json
11
- from typing import Dict, List, Optional, Tuple
12
- from dataclasses import dataclass
13
- from enum import Enum
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
 
15
- # Core Data Structures
16
  @dataclass
17
- class TechnicalElement:
18
- element_type: str
19
- importance: str # 'critical', 'important', 'optional'
20
- present: bool
21
- suggestion: str
22
- examples: List[str]
23
-
24
- class InventionType(Enum):
25
- MECHANICAL = "mechanical"
26
- ELECTRICAL = "electrical"
27
- SOFTWARE = "software"
28
- CHEMICAL = "chemical"
29
-
30
- # ============================================================================
31
- # AGENT 1: Technical Completeness Validator
32
- # ============================================================================
33
-
34
- class TechnicalCompletenessAgent:
35
- """
36
- Real AI agent that ensures patent applications meet technical disclosure requirements.
37
-
38
- Addresses: 35 U.S.C. §112 rejections for inadequate disclosure ($5K-15K prosecution costs)
39
- """
40
-
41
- def __init__(self):
42
- self.required_elements = {
43
- InventionType.MECHANICAL: {
44
- 'materials': {
45
- 'importance': 'critical',
46
- 'examples': ['steel, aluminum, carbon fiber', 'specific alloy compositions'],
47
- 'suggestion': 'Specify materials used in each component with properties'
48
- },
49
- 'dimensions': {
50
- 'importance': 'important',
51
- 'examples': ['length: 10-50cm', 'thickness: 2-5mm'],
52
- 'suggestion': 'Provide dimensional ranges that enable reproduction'
53
- }
54
- },
55
- InventionType.ELECTRICAL: {
56
- 'voltages': {
57
- 'importance': 'critical',
58
- 'examples': ['5V DC', '120-240V AC', '3.3V logic levels'],
59
- 'suggestion': 'Specify all operating voltages and power requirements'
60
- },
61
- 'frequencies': {
62
- 'importance': 'critical',
63
- 'examples': ['2.4GHz WiFi', '60Hz AC', '100MHz-1GHz'],
64
- 'suggestion': 'Define frequency ranges for all signals'
65
- }
66
- },
67
- InventionType.SOFTWARE: {
68
- 'algorithms': {
69
- 'importance': 'critical',
70
- 'examples': ['machine learning (CNN)', 'sorting algorithm', 'encryption (AES-256)'],
71
- 'suggestion': 'Describe core algorithms with sufficient detail for implementation'
72
- },
73
- 'performance_metrics': {
74
- 'importance': 'important',
75
- 'examples': ['response time: <100ms', 'accuracy: >95%', 'throughput: 1000 requests/sec'],
76
- 'suggestion': 'Provide quantitative performance specifications'
77
- }
78
- }
79
- }
80
-
81
- def classify_invention_type(self, invention_text: str) -> InventionType:
82
- """Classify invention type based on description content."""
83
- text_lower = invention_text.lower()
84
-
85
- if any(term in text_lower for term in ['algorithm', 'software', 'app', 'machine learning', 'ai']):
86
- return InventionType.SOFTWARE
87
- elif any(term in text_lower for term in ['electrical', 'electronic', 'circuit', 'voltage', 'sensor']):
88
- return InventionType.ELECTRICAL
89
- elif any(term in text_lower for term in ['chemical', 'composition', 'reaction', 'compound']):
90
- return InventionType.CHEMICAL
91
- else:
92
- return InventionType.MECHANICAL
93
-
94
- def detect_element_presence(self, invention_text: str, element_type: str) -> bool:
95
- """Detect if a technical element is adequately described."""
96
- text_lower = invention_text.lower()
97
-
98
- element_patterns = {
99
- 'materials': [r'\b\w+\s*(?:steel|aluminum|plastic|carbon|alloy|material)\b'],
100
- 'dimensions': [r'\b\d+\s*(?:mm|cm|m|inch|ft)\b'],
101
- 'voltages': [r'\b\d+\.?\d*\s*[vV]\b'],
102
- 'frequencies': [r'\b\d+\.?\d*\s*(?:Hz|khz|mhz|ghz)\b'],
103
- 'algorithms': [r'\b(?:algorithm|method|process|neural|cnn|lstm)\b'],
104
- 'performance_metrics': [r'\b\d+\.?\d*\s*(?:%|percent|accuracy|ms|seconds)\b']
105
- }
106
-
107
- patterns = element_patterns.get(element_type, [])
108
- return any(re.search(pattern, text_lower) for pattern in patterns)
109
-
110
- def analyze_disclosure(self, invention_text: str) -> Dict:
111
- """
112
- Analyze invention disclosure for technical completeness.
113
-
114
- Returns:
115
- Dict with completeness analysis, missing elements, and recommendations
116
- """
117
- invention_type = self.classify_invention_type(invention_text)
118
- required_elements = self.required_elements.get(invention_type, {})
119
-
120
- analysis_results = []
121
- missing_critical = 0
122
- missing_important = 0
123
-
124
- for element_name, element_config in required_elements.items():
125
- is_present = self.detect_element_presence(invention_text, element_name)
126
-
127
- element_analysis = TechnicalElement(
128
- element_type=element_name,
129
- importance=element_config['importance'],
130
- present=is_present,
131
- suggestion=element_config['suggestion'],
132
- examples=element_config['examples']
133
- )
134
-
135
- analysis_results.append(element_analysis)
136
-
137
- if not is_present:
138
- if element_config['importance'] == 'critical':
139
- missing_critical += 1
140
- elif element_config['importance'] == 'important':
141
- missing_important += 1
142
-
143
- # Calculate completeness score
144
- total_elements = len(required_elements)
145
- present_elements = sum(1 for el in analysis_results if el.present)
146
- completeness_score = (present_elements / total_elements * 100) if total_elements > 0 else 0
147
-
148
- # Determine prosecution risk
149
- if missing_critical > 0:
150
- prosecution_risk = "HIGH - Critical elements missing, likely §112 rejection"
151
- elif missing_important > 1:
152
- prosecution_risk = "MEDIUM - Important elements missing, possible objections"
153
- else:
154
- prosecution_risk = "LOW - Technical disclosure appears adequate"
155
-
156
- return {
157
- 'invention_type': invention_type.value,
158
- 'completeness_score': completeness_score,
159
- 'prosecution_risk': prosecution_risk,
160
- 'missing_critical': missing_critical,
161
- 'missing_important': missing_important,
162
- 'missing_elements': [
163
- {
164
- 'element': el.element_type,
165
- 'importance': el.importance,
166
- 'suggestion': el.suggestion,
167
- 'examples': el.examples
168
- }
169
- for el in analysis_results if not el.present
170
- ]
171
- }
172
 
173
- # ============================================================================
174
- # AGENT 2: Prior Art Landscape Analyzer
175
- # ============================================================================
 
 
 
 
176
 
177
- class PriorArtLandscapeAgent:
178
- """
179
- Real AI agent that performs competitive landscape analysis.
180
-
181
- Addresses: Surprise prior art during prosecution ($10K-25K additional costs)
182
- """
183
-
184
- def analyze_landscape(self, invention_description: str) -> Dict:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
185
  """
186
- Perform competitive landscape analysis.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
187
 
188
- Returns:
189
- Dict with competitive landscape, risks, and opportunities
 
 
 
 
 
 
 
 
 
 
 
 
 
 
190
  """
191
- # Mock competitive analysis based on invention content
192
- key_competitors = self._identify_key_competitors(invention_description)
193
- prosecution_risks = self._assess_prosecution_risks(invention_description)
194
- whitespace_opportunities = self._find_whitespace_opportunities(invention_description)
 
 
195
 
196
- return {
197
- 'key_competitors': key_competitors,
198
- 'prosecution_risks': prosecution_risks,
199
- 'whitespace_opportunities': whitespace_opportunities,
200
- 'landscape_summary': self._create_landscape_summary(key_competitors, prosecution_risks)
201
- }
202
-
203
- def _identify_key_competitors(self, invention_text: str) -> List[Dict]:
204
- """Identify key competitors based on invention description."""
205
- if 'coffee' in invention_text.lower():
206
- return [
207
- {'company': 'Ember Technologies', 'patents': 45, 'focus': 'Temperature control'},
208
- {'company': 'YETI Holdings', 'patents': 23, 'focus': 'Insulation technology'}
209
- ]
210
- elif 'sensor' in invention_text.lower():
211
- return [
212
- {'company': 'Honeywell', 'patents': 1200, 'focus': 'Industrial sensors'},
213
- {'company': 'Bosch', 'patents': 890, 'focus': 'Automotive sensors'}
214
- ]
215
- else:
216
- return [
217
- {'company': 'Generic Tech Corp', 'patents': 150, 'focus': 'Related technology'}
218
- ]
219
-
220
- def _assess_prosecution_risks(self, invention_text: str) -> Dict:
221
- """Assess risks for patent prosecution."""
222
- text_lower = invention_text.lower()
223
 
224
- # Assess risk based on technology maturity
225
- if any(term in text_lower for term in ['smart', 'app', 'bluetooth', 'iot']):
226
- risk_level = 'MEDIUM'
227
- risk_factors = ['Crowded IoT field', 'Many smartphone integration patents']
228
- elif any(term in text_lower for term in ['sensor', 'temperature', 'monitoring']):
229
- risk_level = 'HIGH'
230
- risk_factors = ['Mature sensor technology field', 'Extensive prior art']
231
- else:
232
- risk_level = 'LOW'
233
- risk_factors = ['Novel technology area']
 
234
 
235
- return {
236
- 'overall_risk': risk_level,
237
- 'risk_factors': risk_factors,
238
- 'mitigation_strategies': [
239
- 'Focus on specific technical improvements',
240
- 'Emphasize novel combination of features'
241
- ]
242
- }
243
-
244
- def _find_whitespace_opportunities(self, invention_text: str) -> List[Dict]:
245
- """Find whitespace opportunities in the patent landscape."""
246
- return [
247
- {
248
- 'opportunity': 'Mobile app integration',
249
- 'description': 'Limited patents on smartphone-controlled devices in this space',
250
- 'potential_value': 'High - growing IoT market'
251
- },
252
- {
253
- 'opportunity': 'Machine learning optimization',
254
- 'description': 'Few patents combine your core technology with ML algorithms',
255
- 'potential_value': 'Medium - emerging technology trend'
256
- }
257
- ]
258
-
259
- def _create_landscape_summary(self, competitors: List[Dict], risks: Dict) -> str:
260
- """Create a summary of the competitive landscape."""
261
- total_competitors = len(competitors)
262
- total_patents = sum(comp.get('patents', 0) for comp in competitors)
263
 
264
- return f"""
265
- Competitive Landscape Summary:
266
- • {total_competitors} key competitors identified
267
- {total_patents} total patents in competitive analysis
268
- Risk level: {risks['overall_risk']}
269
- Recommendation: Focus on specific technical differentiation
 
270
  """
 
 
 
 
 
 
271
 
272
- # ============================================================================
273
- # AGENT 3: Claim Architecture Strategist
274
- # ============================================================================
275
 
276
- class ClaimArchitectureAgent:
277
- """
278
- Real AI agent that optimizes claim structure for maximum protection.
279
-
280
- Addresses: Poor claim strategy leading to weak patents
281
- """
282
-
283
- def design_claim_architecture(self, invention_details: Dict, prior_art_analysis: Dict) -> Dict:
284
  """
285
- Design strategic claim architecture for maximum protection.
286
-
287
- Returns:
288
- Dict with claim pyramid, prosecution strategy, and strength analysis
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
289
  """
290
- prosecution_risks = prior_art_analysis.get('prosecution_risks', {})
291
-
292
- # Design claim pyramid based on risk assessment
293
- claim_pyramid = self._design_claim_pyramid(prosecution_risks)
294
 
295
- # Analyze claim strength
296
- claim_strength = self._analyze_claim_strength(claim_pyramid, prosecution_risks)
297
-
298
- return {
299
- 'claim_pyramid': claim_pyramid,
300
- 'claim_strength_analysis': claim_strength,
301
- 'recommendation_summary': self._create_recommendation_summary(claim_strength)
302
  }
303
-
304
- def _design_claim_pyramid(self, prosecution_risks: Dict) -> Dict:
305
- """Design strategic claim pyramid."""
306
- risk_level = prosecution_risks.get('overall_risk', 'MEDIUM')
307
-
308
- if risk_level == 'HIGH':
309
- # Conservative approach for high-risk fields
310
- independent_claims = [
311
- {'claim_number': 1, 'type': 'apparatus', 'scope': 'narrow', 'strategy': 'Specific implementation'}
312
- ]
313
- else:
314
- # More aggressive approach for lower-risk fields
315
- independent_claims = [
316
- {'claim_number': 1, 'type': 'apparatus', 'scope': 'broad', 'strategy': 'Cover core invention'},
317
- {'claim_number': 8, 'type': 'method', 'scope': 'broad', 'strategy': 'Protect process aspects'}
318
- ]
319
-
320
- return {
321
- 'independent_claims': independent_claims,
322
- 'dependent_claims': [
323
- {'claim_number': 2, 'depends_on': 1, 'strategy': 'Narrow fallback position'},
324
- {'claim_number': 3, 'depends_on': 1, 'strategy': 'Alternative limitation'}
325
- ]
326
- }
327
-
328
- def _analyze_claim_strength(self, claim_pyramid: Dict, prosecution_risks: Dict) -> Dict:
329
- """Analyze strength of proposed claims."""
330
- risk_level = prosecution_risks.get('overall_risk', 'MEDIUM')
331
-
332
- # Calculate strength based on risk level and claim scope
333
- if risk_level == 'HIGH':
334
- overall_strength = 60 # Conservative claims in crowded field
335
- elif risk_level == 'MEDIUM':
336
- overall_strength = 75 # Balanced approach
337
- else:
338
- overall_strength = 85 # Aggressive claims in open field
339
-
340
- return {
341
- 'overall_strength': overall_strength,
342
- 'grantability': 'Good' if overall_strength > 70 else 'Moderate',
343
- 'recommendations': self._generate_strength_recommendations(overall_strength)
344
- }
345
-
346
- def _generate_strength_recommendations(self, strength: float) -> List[str]:
347
- """Generate recommendations for improving claim strength."""
348
- recommendations = []
349
-
350
- if strength < 70:
351
- recommendations.append("Consider narrowing independent claims to improve grantability")
352
- recommendations.append("Add more specific technical limitations")
353
-
354
- recommendations.append("Ensure all claims are fully supported by specification")
355
- recommendations.append("Consider adding method claims if not present")
356
-
357
- return recommendations
358
-
359
- def _create_recommendation_summary(self, claim_strength: Dict) -> str:
360
- """Create summary of claim architecture recommendations."""
361
- overall_strength = claim_strength.get('overall_strength', 0)
362
-
363
- if overall_strength >= 80:
364
- assessment = "STRONG - Claims appear well-positioned for prosecution"
365
- elif overall_strength >= 65:
366
- assessment = "GOOD - Claims have solid foundation with room for improvement"
367
- else:
368
- assessment = "NEEDS WORK - Claims require significant refinement"
369
-
370
- return f"""
371
- Claim Architecture Assessment: {assessment}
372
- Overall Strength: {overall_strength:.0f}/100
373
-
374
- Key Recommendations:
375
- • Focus on specific technical differentiation
376
- • Prepare multiple claim strategies for prosecution
377
- • Ensure strong specification support
378
- """
379
 
380
- # ============================================================================
381
- # AGENT COORDINATOR
382
- # ============================================================================
 
 
 
 
 
 
 
383
 
384
- class InterAgentCoordinator:
385
- """
386
- Orchestrates collaboration between specialized patent agents.
387
- """
388
-
389
- def __init__(self):
390
  self.agents = {
391
- 'technical_completeness': TechnicalCompletenessAgent(),
392
- 'prior_art_landscape': PriorArtLandscapeAgent(),
393
- 'claim_architecture': ClaimArchitectureAgent()
 
 
 
394
  }
395
-
396
- def orchestrate_patent_development(self, invention_disclosure: str) -> Dict:
397
- """
398
- Orchestrate complete patent development process with agent collaboration.
399
- """
400
- results = {}
401
-
402
- # Phase 1: Technical Completeness Analysis
403
- print("🔬 Phase 1: Analyzing technical completeness...")
404
- technical_analysis = self.agents['technical_completeness'].analyze_disclosure(invention_disclosure)
405
- results['technical_analysis'] = technical_analysis
406
-
407
- # Phase 2: Prior Art Landscape Analysis
408
- print("🔍 Phase 2: Analyzing prior art landscape...")
409
- prior_art_analysis = self.agents['prior_art_landscape'].analyze_landscape(invention_disclosure)
410
- results['prior_art_analysis'] = prior_art_analysis
411
-
412
- # Phase 3: Claim Architecture Design
413
- print("⚖️ Phase 3: Designing claim architecture...")
414
- invention_details = {'description': invention_disclosure}
415
- claims_analysis = self.agents['claim_architecture'].design_claim_architecture(
416
- invention_details,
417
- prior_art_analysis
418
- )
419
- results['claims_analysis'] = claims_analysis
420
-
421
- # Phase 4: Integration and Quality Assessment
422
- print("🔄 Phase 4: Integrating analysis and assessing quality...")
423
- integrated_analysis = self._integrate_agent_outputs(results)
424
- results['integrated_analysis'] = integrated_analysis
425
-
426
- return results
427
-
428
- def _integrate_agent_outputs(self, agent_results: Dict) -> Dict:
429
- """Integrate outputs from all agents into cohesive analysis."""
430
- technical = agent_results.get('technical_analysis', {})
431
- prior_art = agent_results.get('prior_art_analysis', {})
432
- claims = agent_results.get('claims_analysis', {})
433
-
434
- # Calculate overall patent readiness score
435
- technical_score = technical.get('completeness_score', 0)
436
- prior_art_risk = prior_art.get('prosecution_risks', {}).get('overall_risk', 'HIGH')
437
- claims_strength = claims.get('claim_strength_analysis', {}).get('overall_strength', 0)
438
-
439
- # Convert prior art risk to score
440
- risk_score_map = {'LOW': 85, 'MEDIUM': 70, 'HIGH': 50}
441
- prior_art_score = risk_score_map.get(prior_art_risk, 50)
442
-
443
- overall_readiness = (technical_score + prior_art_score + claims_strength) / 3
444
-
445
- return {
446
- 'overall_readiness_score': overall_readiness,
447
- 'readiness_assessment': self._get_readiness_assessment(overall_readiness),
448
- 'estimated_prosecution_timeline': self._estimate_timeline(overall_readiness),
449
- 'estimated_costs': self._estimate_costs(overall_readiness)
450
- }
451
-
452
- def _get_readiness_assessment(self, score: float) -> str:
453
- """Get overall readiness assessment."""
454
- if score >= 85:
455
- return "EXCELLENT - Ready for immediate filing"
456
- elif score >= 75:
457
- return "GOOD - Minor refinements recommended"
458
- elif score >= 65:
459
- return "FAIR - Address key issues before filing"
460
- else:
461
- return "POOR - Significant development needed"
462
-
463
- def _estimate_timeline(self, readiness_score: float) -> str:
464
- """Estimate prosecution timeline based on readiness."""
465
- if readiness_score >= 80:
466
- return "12-18 months to allowance (well-prepared application)"
467
- elif readiness_score >= 65:
468
- return "18-24 months to allowance (likely 1-2 office actions)"
469
- else:
470
- return "24-36 months to allowance (multiple office actions expected)"
471
-
472
- def _estimate_costs(self, readiness_score: float) -> str:
473
- """Estimate prosecution costs based on readiness."""
474
- if readiness_score >= 80:
475
- return "$8,000-12,000 (minimal prosecution required)"
476
- elif readiness_score >= 65:
477
- return "$12,000-18,000 (moderate prosecution complexity)"
478
  else:
479
- return "$18,000-30,000 (extensive prosecution likely)"
 
480
 
481
- # ============================================================================
482
- # TESTING AND VALIDATION
483
- # ============================================================================
484
 
485
- def test_real_ai_agents():
486
- """Test the real AI agent implementation with a sample invention."""
487
- print("🤖 Testing Real AI Agent Implementation")
 
 
 
488
  print("=" * 60)
489
 
490
- # Sample invention for testing
 
 
 
491
  test_invention = """
492
- A smart coffee mug that maintains perfect temperature using phase-change materials
493
- and smartphone app control. The mug includes a double-wall design with PCM chambers
494
- that store and release thermal energy. A temperature sensor monitors the coffee
495
- temperature and communicates with a mobile app via Bluetooth. The app allows users
496
- to set preferred temperatures and receive notifications when coffee is ready.
497
-
498
- The system uses a microcontroller to manage thermal regulation and wireless
499
- communication. Machine learning algorithms analyze user preferences to optimize
500
- heating patterns over time.
501
  """
502
 
503
- # Initialize coordinator and run analysis
504
- coordinator = InterAgentCoordinator()
505
- results = coordinator.orchestrate_patent_development(test_invention)
506
-
507
- # Display results
508
- print("\n📊 ANALYSIS RESULTS:")
509
- print("=" * 40)
510
-
511
- # Technical Analysis Results
512
- technical = results['technical_analysis']
513
- print(f"\n🔬 Technical Completeness: {technical['completeness_score']:.1f}%")
514
- print(f" Prosecution Risk: {technical['prosecution_risk']}")
515
- print(f" Missing Critical Elements: {technical['missing_critical']}")
516
- if technical['missing_elements']:
517
- print(" Missing Elements:")
518
- for element in technical['missing_elements'][:3]:
519
- print(f" • {element['element']}: {element['suggestion']}")
520
-
521
- # Prior Art Results
522
- prior_art = results['prior_art_analysis']
523
- print(f"\n🔍 Prior Art Analysis:")
524
- print(f" Risk Level: {prior_art['prosecution_risks']['overall_risk']}")
525
- print(f" Key Competitors: {len(prior_art['key_competitors'])}")
526
- for competitor in prior_art['key_competitors'][:2]:
527
- print(f" • {competitor['company']}: {competitor['patents']} patents")
528
 
529
- # Claims Analysis Results
530
- claims = results['claims_analysis']
531
- print(f"\n⚖️ Claim Architecture:")
532
- print(f" Overall Strength: {claims['claim_strength_analysis']['overall_strength']:.1f}%")
533
- print(f" Grantability: {claims['claim_strength_analysis']['grantability']}")
534
-
535
- # Overall Assessment
536
- integrated = results['integrated_analysis']
537
- print(f"\n🎯 OVERALL ASSESSMENT:")
538
- print(f" Readiness Score: {integrated['overall_readiness_score']:.1f}%")
539
- print(f" Assessment: {integrated['readiness_assessment']}")
540
- print(f" Timeline: {integrated['estimated_prosecution_timeline']}")
541
- print(f" Costs: {integrated['estimated_costs']}")
542
-
543
- print(f"\n✅ Real AI Agents Successfully Implemented!")
544
- print("These agents provide genuine value for patent professionals:")
545
- print("• Technical completeness validation prevents §112 rejections")
546
- print("• Prior art landscape analysis reduces prosecution surprises")
547
- print("• Claim architecture optimization maximizes patent value")
548
- print("• Integrated assessment provides realistic business planning")
549
 
550
  if __name__ == "__main__":
551
- test_real_ai_agents()
 
1
  #!/usr/bin/env python3
2
  """
3
+ True Agentic Implementation for Patent Architect AI v2
4
+ This version implements a genuine, stateful, multi-agent negotiation workflow
5
+ where agent outputs dynamically influence subsequent agent actions.
 
6
  """
7
 
8
+ import os
9
  import json
10
+ import re
11
+ import base64
12
+ import requests
13
+ from typing import Dict, List, Optional, Tuple, Generator
14
+ from dataclasses import dataclass, field
15
+ import google.generativeai as genai
16
+ from dotenv import load_dotenv
17
+
18
+ # --- Configuration ---
19
+ load_dotenv()
20
+ # Configure Gemini
21
+ try:
22
+ genai.configure(api_key=os.getenv("GEMINI_API_KEY"))
23
+ GEMINI_AVAILABLE = True
24
+ except (ValueError, TypeError) as e:
25
+ print(f"Gemini API key not found or invalid: {e}")
26
+ GEMINI_AVAILABLE = False
27
+
28
 
29
+ # --- Data Structures ---
30
  @dataclass
31
+ class NegotiationState:
32
+ invention_disclosure: str
33
+ key_concepts: List[str] = field(default_factory=list)
34
+ prior_art_analysis: Dict = field(default_factory=dict)
35
+ strategic_mandate: str = ""
36
+ technical_summary: str = ""
37
+ patent_claims: str = ""
38
+ figure_description: str = ""
39
+ ideogram_image_b64: str = ""
40
+ negotiation_transcript: List[Dict] = field(default_factory=list)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
+ # --- Base Agent Class ---
43
+ class BaseAgent:
44
+ def __init__(self, model_name='gemini-1.5-flash'):
45
+ if not GEMINI_AVAILABLE:
46
+ self.model = None
47
+ return
48
+ self.model = genai.GenerativeModel(model_name)
49
 
50
+ def _execute_prompt(self, prompt: str) -> str:
51
+ if not self.model:
52
+ return f"Error: The '{self.__class__.__name__}' agent could not run because the Gemini API is not configured. Please set the GEMINI_API_KEY."
53
+ try:
54
+ response = self.model.generate_content(prompt)
55
+ return response.text
56
+ except Exception as e:
57
+ print(f"Error executing prompt for {self.__class__.__name__}: {e}")
58
+ return f"Error: Could not get a response from the model. Details: {e}"
59
+
60
+ # --- Specialized Agents ---
61
+ class PriorArtDetective(BaseAgent):
62
+ def analyze(self, invention_disclosure: str) -> Dict:
63
+ prompt = f"""
64
+ Analyze the following invention disclosure to identify the key technical concepts and potential areas of prior art.
65
+ Invention: "{invention_disclosure}"
66
+
67
+ 1. List the 3-5 most important technical keywords or concepts.
68
+ 2. For each concept, generate a list of 2-3 realistic-sounding, representative prior art titles that likely exist.
69
+ 3. Based on these, write a brief, 2-3 sentence summary of the prior art landscape, assessing how crowded it might be.
70
+
71
+ Return the response as a JSON object with keys: "key_concepts", "simulated_prior_art", and "landscape_summary".
72
  """
73
+ response_text = self._execute_prompt(prompt)
74
+ try:
75
+ # Clean the response text before parsing
76
+ clean_response = response_text.strip().replace("```json", "").replace("```", "")
77
+ return json.loads(clean_response)
78
+ except json.JSONDecodeError:
79
+ return {
80
+ "key_concepts": [],
81
+ "simulated_prior_art": [],
82
+ "landscape_summary": "Error parsing prior art analysis from LLM response.",
83
+ }
84
+
85
+ class ChiefStrategistAgent(BaseAgent):
86
+ def formulate_strategy(self, invention_disclosure: str, prior_art_analysis: Dict) -> str:
87
+ prompt = f"""
88
+ You are a Chief Patent Strategist. Your job is to determine the strongest angle for a successful patent application.
89
 
90
+ Invention Disclosure:
91
+ "{invention_disclosure}"
92
+
93
+ Prior Art Analysis:
94
+ - Key Concepts: {prior_art_analysis.get('key_concepts', [])}
95
+ - Simulated Prior Art: {prior_art_analysis.get('simulated_prior_art', [])}
96
+ - Landscape Summary: {prior_art_analysis.get('landscape_summary', '')}
97
+
98
+ Based on the above, formulate a clear, one-sentence "Strategic Mandate". This mandate will direct all other agents. It must identify the single most patentable aspect of the invention to focus on.
99
+
100
+ Example Mandates:
101
+ - "The strategic focus shall be on the novel method for data encryption, not the hardware implementation."
102
+ - "The patentability of this invention rests on the unique chemical composition of the coating material."
103
+ - "We will patent the specific algorithm for adaptive lighting control, as the general hardware is well-known."
104
+
105
+ Formulate the Strategic Mandate for the provided invention.
106
  """
107
+ return self._execute_prompt(prompt)
108
+
109
+ class TechnicalWriterAgent(BaseAgent):
110
+ def write_summary(self, invention_disclosure: str, strategic_mandate: str) -> str:
111
+ prompt = f"""
112
+ You are a professional patent writer. Your task is to write a "Summary of the Invention" section for a patent application.
113
 
114
+ Invention Disclosure: "{invention_disclosure}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
 
116
+ **CRITICAL INSTRUCTION:** You must follow this Strategic Mandate provided by the Chief Strategist:
117
+ **Strategic Mandate: "{strategic_mandate}"**
118
+
119
+ Write a concise, professional summary (2-3 paragraphs). Ensure that the summary heavily emphasizes the aspect highlighted in the Strategic Mandate as the core of the invention.
120
+ """
121
+ return self._execute_prompt(prompt)
122
+
123
+ class ClaimsDrafterAgent(BaseAgent):
124
+ def draft_claims(self, invention_disclosure: str, strategic_mandate: str) -> str:
125
+ prompt = f"""
126
+ You are a patent attorney specializing in claim drafting.
127
 
128
+ Invention Disclosure: "{invention_disclosure}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
 
130
+ **CRITICAL INSTRUCTION:** Your claim set MUST be aligned with the following mandate:
131
+ **Strategic Mandate: "{strategic_mandate}"**
132
+
133
+ Draft a set of 5-7 patent claims.
134
+ - The independent claim (Claim 1) must be directly focused on the feature identified in the Strategic Mandate.
135
+ - Dependent claims should add further specifics and variations.
136
+ - Ensure the claims are clear, concise, and properly formatted.
137
  """
138
+ return self._execute_prompt(prompt)
139
+
140
+ class FigureDrafterAgent(BaseAgent):
141
+ def describe_figure(self, invention_disclosure: str, strategic_mandate: str) -> str:
142
+ prompt = f"""
143
+ You are a patent illustrator's assistant. You need to describe a key technical figure for a patent application.
144
 
145
+ Invention Disclosure: "{invention_disclosure}"
 
 
146
 
147
+ **CRITICAL INSTRUCTION:** The figure must visually represent the core idea from the mandate:
148
+ **Strategic Mandate: "{strategic_mandate}"**
149
+
150
+ 1. Decide on the best type of figure to illustrate the mandate (e.g., flowchart, system diagram, cross-section).
151
+ 2. Write a brief description of this figure.
152
+ 3. Generate the LaTeX/TikZ code to create this figure.
153
+
154
+ Return a single response containing both the description and the LaTeX code block.
155
  """
156
+ return self._execute_prompt(prompt)
157
+
158
+ class SegmindIdeogramAgent:
159
+ def __init__(self):
160
+ self.api_key = os.getenv("SEGMIND_API_KEY", "SG_f5de4e5bf40aa615") # Use user's key as default
161
+ self.url = "https://api.segmind.com/v1/ideogram-3"
162
+
163
+ def generate_image(self, technical_summary: str, strategic_mandate: str) -> Optional[str]:
164
+ if not self.api_key:
165
+ return None
166
+
167
+ # Create a more cinematic prompt for image generation
168
+ image_prompt = f"""
169
+ Create a photorealistic, cinematic photograph representing the following invention.
170
+ The image should focus on the core concept defined by the strategic mandate.
171
+
172
+ Invention Summary: "{technical_summary}"
173
+ Core Concept (Strategic Mandate): "{strategic_mandate}"
174
+
175
+ Translate this technical concept into a visually stunning and professional marketing image.
176
+ Emphasize the most innovative aspect. For example, if it's an algorithm, show a sleek user interface or an abstract representation of data flow, not just the hardware.
177
  """
 
 
 
 
178
 
179
+ data = {
180
+ "prompt": image_prompt,
181
+ "resolution": "1024x1024",
182
+ "style_type": "REALISTIC"
 
 
 
183
  }
184
+ headers = {'x-api-key': self.api_key}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
185
 
186
+ try:
187
+ response = requests.post(self.url, json=data, headers=headers)
188
+ if response.status_code == 200:
189
+ return base64.b64encode(response.content).decode('utf-8')
190
+ else:
191
+ print(f"Segmind API Error: {response.status_code} - {response.text}")
192
+ return None
193
+ except Exception as e:
194
+ print(f"Error calling Segmind API: {e}")
195
+ return None
196
 
197
+
198
+ # --- The Orchestrator ---
199
+ class AgenticNegotiator:
200
+ def __init__(self, invention_disclosure: str):
201
+ self.state = NegotiationState(invention_disclosure=invention_disclosure)
 
202
  self.agents = {
203
+ "Prior Art Detective": PriorArtDetective(),
204
+ "Chief Strategist": ChiefStrategistAgent(),
205
+ "Technical Writer": TechnicalWriterAgent(),
206
+ "Claims Drafter": ClaimsDrafterAgent(),
207
+ "Figure Drafter": FigureDrafterAgent(),
208
+ "Conceptual Artist": SegmindIdeogramAgent(),
209
  }
210
+
211
+ def _update_transcript(self, agent_name: str, message: str, data: Optional[Dict] = None):
212
+ entry = {"agent": agent_name, "message": message, "data": data or {}}
213
+ self.state.negotiation_transcript.append(entry)
214
+
215
+ def run_negotiation(self) -> Generator[NegotiationState, None, None]:
216
+ # Step 0: Check for Gemini API Key
217
+ if not GEMINI_AVAILABLE:
218
+ self._update_transcript("System", "CRITICAL ERROR: `GEMINI_API_KEY` is not set. The agentic workflow cannot proceed. Please configure the environment variable.")
219
+ yield self.state
220
+ return
221
+
222
+ # Step 1: Prior Art Detective
223
+ agent_name = "Prior Art Detective"
224
+ self._update_transcript(agent_name, "Analyzing the invention to understand the technical landscape...")
225
+ yield self.state
226
+
227
+ prior_art_result = self.agents[agent_name].analyze(self.state.invention_disclosure)
228
+ self.state.prior_art_analysis = prior_art_result
229
+ self.state.key_concepts = prior_art_result.get("key_concepts", [])
230
+ self._update_transcript(agent_name, f"Analysis complete. The landscape appears to be: {prior_art_result.get('landscape_summary', 'N/A')}", prior_art_result)
231
+ yield self.state
232
+
233
+ # Step 2: Chief Strategist
234
+ agent_name = "Chief Strategist"
235
+ self._update_transcript(agent_name, "Reviewing prior art to determine the most defensible patenting strategy...")
236
+ yield self.state
237
+
238
+ mandate = self.agents[agent_name].formulate_strategy(self.state.invention_disclosure, self.state.prior_art_analysis)
239
+ self.state.strategic_mandate = mandate
240
+ self._update_transcript(agent_name, f"Strategy formulated. All agents will now adhere to the following mandate: **{mandate}**")
241
+ yield self.state
242
+
243
+ # Step 3: Guided Content Generation
244
+ # Technical Summary
245
+ agent_name = "Technical Writer"
246
+ self._update_transcript(agent_name, "Acknowledged. Drafting the technical summary to align with the strategic mandate.")
247
+ yield self.state
248
+ summary = self.agents[agent_name].write_summary(self.state.invention_disclosure, self.state.strategic_mandate)
249
+ self.state.technical_summary = summary
250
+ self._update_transcript(agent_name, "Technical summary drafted.")
251
+ yield self.state
252
+
253
+ # Patent Claims
254
+ agent_name = "Claims Drafter"
255
+ self._update_transcript(agent_name, "Understood. Drafting patent claims focused on the mandated novel aspect.")
256
+ yield self.state
257
+ claims = self.agents[agent_name].draft_claims(self.state.invention_disclosure, self.state.strategic_mandate)
258
+ self.state.patent_claims = claims
259
+ self._update_transcript(agent_name, "Patent claims drafted.")
260
+ yield self.state
261
+
262
+ # Figure Description (LaTeX)
263
+ agent_name = "Figure Drafter"
264
+ self._update_transcript(agent_name, "Affirmative. Designing a technical figure that visually represents the core strategic mandate.")
265
+ yield self.state
266
+ figure_desc = self.agents[agent_name].describe_figure(self.state.invention_disclosure, self.state.strategic_mandate)
267
+ self.state.figure_description = figure_desc
268
+ self._update_transcript(agent_name, "Technical figure description and LaTeX code generated.")
269
+ yield self.state
270
+
271
+ # Conceptual Image (Ideogram)
272
+ agent_name = "Conceptual Artist"
273
+ self._update_transcript(agent_name, "Now generating a high-fidelity conceptual image based on the strategy...")
274
+ yield self.state
275
+ image_b64 = self.agents[agent_name].generate_image(self.state.technical_summary, self.state.strategic_mandate)
276
+ if image_b64:
277
+ self.state.ideogram_image_b64 = image_b64
278
+ self._update_transcript(agent_name, "Conceptual image generated successfully.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
279
  else:
280
+ self._update_transcript(agent_name, "Failed to generate conceptual image. The API may be unavailable or the key may be invalid.")
281
+ yield self.state
282
 
 
 
 
283
 
284
+ self._update_transcript("AgenticNegotiator", "All tasks complete. The patent application is ready for assembly.")
285
+ yield self.state
286
+
287
+ def test_agentic_negotiation():
288
+ """Test the new agentic negotiation workflow."""
289
+ print("🤖 Testing True Agentic Workflow")
290
  print("=" * 60)
291
 
292
+ if not GEMINI_AVAILABLE:
293
+ print("\n❌ Cannot run test: GEMINI_API_KEY is not configured.")
294
+ return
295
+
296
  test_invention = """
297
+ My invention is a smart coffee mug that uses a novel phase-change material to keep coffee at a perfect temperature. It also has a mobile app that connects via Bluetooth to let the user set their preferred temperature. The key innovation is a machine learning algorithm that learns the user's drinking habits to pre-warm or cool the mug, optimizing energy use.
 
 
 
 
 
 
 
 
298
  """
299
 
300
+ negotiator = AgenticNegotiator(invention_disclosure=test_invention)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
301
 
302
+ final_state = None
303
+ for i, state in enumerate(negotiator.run_negotiation()):
304
+ print(f"\n--- Turn {i+1} ---")
305
+ last_message = state.negotiation_transcript[-1]
306
+ print(f"**{last_message['agent']}:** {last_message['message']}")
307
+ final_state = state
308
+
309
+ print("\n\n✅ Negotiation Complete!")
310
+ print("=" * 60)
311
+ print(f"\n**Final Strategic Mandate:**\n{final_state.strategic_mandate}")
312
+ print(f"\n**Generated Claims Preview:**\n{final_state.patent_claims[:300]}...")
313
+ print(f"\n**Generated Figure Description Preview:**\n{final_state.figure_description[:300]}...")
314
+ if final_state.ideogram_image_b64:
315
+ print(f"\n**Ideogram Image:** Generated successfully (Base64 data)")
316
+ else:
317
+ print(f"\n**Ideogram Image:** Failed to generate.")
 
 
 
 
318
 
319
  if __name__ == "__main__":
320
+ test_agentic_negotiation()
requirements.txt CHANGED
@@ -1,6 +1,7 @@
1
- gradio==4.44.0
2
- requests==2.31.0
3
- openai==1.51.0
4
- pillow==10.0.0
5
- python-dotenv==1.0.0
6
- google-generativeai==0.8.3
 
 
1
+ gradio>=4.44.0
2
+ requests>=2.31.0
3
+ openai>=1.51.0
4
+ pillow>=10.0.0
5
+ python-dotenv>=1.0.0
6
+ google-generativeai>=0.8.3
7
+ segmind>=0.2.2