Implement revolutionary hybrid elicitation + sampling architecture for AI-powered circuit design

Key Features:
- 🚀 Hybrid Architecture: Combines elicitation interviews with AI sampling for dynamic responses
- 🎯 Professional Engineering Interview: 8-question structured flow for comprehensive requirements gathering
- 🤖 AI-Enhanced Analysis: Uses sampling to generate intelligent circuit analysis and WireViz YAML
- 🛡️ Graceful Fallbacks: 8 rich prompts for clients without elicitation support
-  Future-Ready: Code prepared for FastMCP elicitation module when available

Technical Implementation:
- Elicitation-based circuit design interview with professional engineering questions
- Comprehensive sampling prompt that transforms interview data into AI-powered analysis
- Intelligent error handling with structured fallback to manual analysis
- Rich prompt system covering pinouts, harnesses, troubleshooting, and PCB layout
- Professional circuit design patterns following industry standards

The hybrid system represents cutting-edge MCP architecture that adapts to client capabilities
while providing professional-grade circuit design assistance regardless of available features.
This commit is contained in:
Ryan Malloy 2025-09-27 21:30:25 -06:00
parent c6474f0789
commit fbc65d0282

View File

@ -567,6 +567,63 @@ For motor control, I'll design robust power systems:
environment, special_reqs, interfaces, learning_goals
)
# Use sampling to generate AI-powered analysis and WireViz YAML
try:
# Check if context supports sampling for AI-enhanced response
if hasattr(ctx, 'sample') and callable(ctx.sample):
# Create comprehensive prompt for AI analysis
sampling_prompt = self._create_sampling_prompt(
project, experience, board, components, power,
environment, special_reqs, interfaces, learning_goals
)
# Get AI-generated analysis and circuit design
ai_response = await ctx.sample(sampling_prompt)
if ai_response and hasattr(ai_response, 'content'):
# Extract AI response content
ai_content = ai_response.content
# Combine structured interview data with AI insights
return f"""# 🎯 AI-Enhanced Professional Circuit Design
## 📋 Interview Summary
**Project**: {project}
**Experience**: {experience}
**Board**: {board}
**Environment**: {environment}
**Power**: {power}
---
{ai_content}
---
## 🔧 Implementation Ready
Your circuit design is now ready for implementation! The AI analysis above includes:
- **Custom component recommendations** based on your specific requirements
- **Intelligent pin assignments** optimized for your board and components
- **Power system design** tailored to your environment and usage
- **Professional wiring diagram** with industry-standard practices
**Next Step**: Use the WireViz YAML provided above with `wireviz_generate_from_yaml` to create your professional circuit diagram!
*This analysis combines structured engineering interview data with AI-powered circuit design intelligence.*
"""
except Exception as e:
# Log the sampling attempt failure but continue with fallback
import logging
logger = logging.getLogger(__name__)
logger.debug(f"Sampling failed in elicitation response: {e}")
# Fallback to structured analysis when sampling unavailable
analysis = self._generate_professional_analysis(
project, experience, board, components, power,
environment, special_reqs, interfaces, learning_goals
)
# Create the comprehensive circuit design plan
return f"""# 🎯 Professional Circuit Design Analysis
@ -764,21 +821,544 @@ This assignment minimizes noise, maximizes performance, and follows Arduino best
return content
def _create_sampling_prompt(self, project, experience, board, components, power, environment, special_reqs, interfaces, learning_goals):
"""Create comprehensive sampling prompt from elicitation responses"""
# Build comprehensive prompt for AI analysis
prompt = f"""You are a professional electronics engineer designing a custom Arduino circuit. Based on the following detailed requirements from a professional engineering interview, create a comprehensive circuit design analysis and generate a complete WireViz YAML diagram.
## Project Requirements (from engineering interview):
**Project Type**: {project}
**Experience Level**: {experience}
**Arduino Board**: {board}
**Components**: {components}
**Power Source**: {power}
**Operating Environment**: {environment}
**Special Requirements**: {', '.join(special_reqs) if special_reqs else 'Standard design'}
**User Interfaces**: {', '.join(interfaces) if interfaces else 'Basic interfaces'}
**Learning Goals**: {', '.join(learning_goals) if learning_goals else 'General understanding'}
## Your Task:
1. **Professional Circuit Analysis**: Provide detailed engineering analysis considering:
- Component integration strategies specific to the experience level
- Optimal pin assignments for the chosen Arduino board
- Power distribution design for the specified power source and environment
- Signal integrity considerations and protection circuits
- Safety requirements based on environment and special needs
2. **Generate Complete WireViz YAML**: Create production-ready WireViz YAML that includes:
- All components with proper specifications
- Optimal pin assignments following Arduino best practices
- Industry-standard wire colors and routing
- Appropriate connectors and cable specifications
- Protection circuits (fuses, diodes, current limiting)
- Clear labeling and documentation
3. **Implementation Guidance**: Provide:
- Step-by-step assembly instructions
- Testing and validation procedures
- Troubleshooting guidance
- Educational explanations appropriate for the experience level
## Format your response as:
### Circuit Design Analysis
[Detailed professional analysis based on interview responses]
### WireViz YAML Code
```yaml
[Complete WireViz YAML for the circuit]
```
### Assembly Instructions
[Step-by-step implementation guidance]
### Educational Notes
[Learning content based on specified goals]
Focus on creating a production-ready design that matches the user's experience level while following professional engineering standards."""
return prompt
else:
# Fallback for clients without elicitation support
# Rich prompts for clients without elicitation support
@mcp_prompt
async def circuit_design_interview_fallback(
async def quick_pinout_designer(
self,
responses: str = Field(description="Your answers in format: project|experience|board|components|power|environment")
components: str = Field(description="Components to connect (e.g., 'ESP32, servo motor, LED strip')"),
project_type: str = Field(default="general", description="Project type (robotics, iot, sensor, display, motor_control)"),
experience: str = Field(default="intermediate", description="Your experience level (beginner, intermediate, advanced)")
) -> str:
"""Fallback version for clients without elicitation support"""
return """# 🎯 Circuit Design Assistant
"""Quick pinout and wiring diagram generator"""
**Note**: For the full interactive experience, upgrade to a client that supports elicitation.
component_list = [c.strip() for c in components.split(',')]
component_count = len(component_list)
**Format your responses as**: `project|experience|board|components|power|environment`
# Generate experience-appropriate guidance
if "beginner" in experience.lower():
complexity_note = "I'll use pre-made modules and provide clear step-by-step instructions."
safety_emphasis = "**Safety First**: I'll include important safety reminders and common mistake warnings."
elif "advanced" in experience.lower():
complexity_note = "I'll optimize for signal integrity and include professional design considerations."
safety_emphasis = "**Professional Standards**: Following industry best practices for production-ready circuits."
else:
complexity_note = "I'll balance clarity with technical depth for your skill level."
safety_emphasis = "**Best Practices**: Including proper protection circuits and wire management."
**Example**: `temperature monitor|intermediate|Arduino Uno|DHT22,LCD,SD card|USB|indoor`
return f"""# ⚡ Quick Pinout Designer
Once you provide your responses, I'll generate a professional circuit analysis and wiring diagram!
## 🔌 Your Circuit: {components}
**Project Type**: {project_type.title()}
**Components**: {component_count} components to connect
**Experience Level**: {experience.title()}
## 🎯 Design Approach
{complexity_note}
{safety_emphasis}
## 🧩 Smart Pin Assignment Strategy
I'll automatically assign pins based on component requirements:
**🔴 Power Distribution**:
- **5V Rail**: High-current components (servos, LED strips, displays)
- **3.3V Rail**: Low-power sensors and logic-level devices
- **Ground**: Star ground configuration to minimize noise
**📡 Communication Pins**:
- **I2C Devices** SDA/SCL with proper pull-up resistors (4.7)
- **SPI Devices** Hardware SPI pins for maximum speed
- **UART/Serial** Hardware serial pins when available
** Special Function Pins**:
- **PWM Control** PWM-capable pins (3, 5, 6, 9, 10, 11 on Uno)
- **Analog Sensors** A0-A5 with appropriate voltage dividers
- **Interrupt Pins** Pins 2 & 3 for time-critical sensors
- **Digital I/O** Remaining pins with pull-up/pull-down as needed
## 🎨 Professional Features I'll Include
- **Standard Wire Colors**: Red (5V), Black (GND), Yellow (Data), etc.
- **Proper Connectors**: Dupont, JST, screw terminals as appropriate
- **Protection Circuits**: Fuses, diodes, current limiting resistors
- **Clear Labels**: Component names, pin numbers, voltage levels
- **Assembly Notes**: Connection order and testing checkpoints
## 🚀 Ready to Generate
**Just say "Generate my pinout diagram" and I'll create a professional WireViz schematic with:**
1. **Optimal pin assignments** for your components
2. **Color-coded wiring** following industry standards
3. **Protection circuits** for safe operation
4. **Assembly instructions** with testing steps
5. **Troubleshooting guide** for common issues
*Professional circuit design made simple - regardless of your experience level!*
"""
@mcp_prompt
async def connector_harness_designer(
self,
source_device: str = Field(description="Source device/board (e.g., 'Arduino Uno', 'ESP32 DevKit')"),
target_devices: str = Field(description="Target devices to connect (e.g., 'servo motor, OLED display, temperature sensor')"),
cable_length: str = Field(default="short", description="Cable length needed (short: <30cm, medium: 30cm-1m, long: >1m)"),
environment: str = Field(default="indoor", description="Environment (indoor, outdoor, mobile, industrial)")
) -> str:
"""Design custom connector harnesses and cable assemblies"""
targets = [t.strip() for t in target_devices.split(',')]
target_count = len(targets)
# Determine cable specifications based on length and environment
if cable_length == "long" or "outdoor" in environment.lower():
cable_spec = "**Shielded twisted pair** cables for signal integrity and EMI protection"
connector_type = "**Weatherproof connectors** (IP65 rated) for reliable outdoor operation"
elif "industrial" in environment.lower():
cable_spec = "**Industrial-grade cables** with high flex life and chemical resistance"
connector_type = "**Rugged connectors** with strain relief and vibration resistance"
else:
cable_spec = "**Standard dupont/JST cables** for clean, reliable connections"
connector_type = "**Standard connectors** with proper strain relief"
return f"""# 🔌 Custom Connector Harness Designer
## 📡 Harness Specification
**Source**: {source_device}
**Targets**: {target_count} devices {target_devices}
**Cable Length**: {cable_length.title()}
**Environment**: {environment.title()}
## 🎯 Professional Harness Design
### 📏 Cable Specifications
{cable_spec}
**Wire Gauge Selection**:
- **Power Lines (5V/12V)**: 18-20 AWG for high current (>500mA)
- **Logic Signals**: 22-24 AWG for digital communication
- **Analog Signals**: 24-26 AWG with twisted pair for noise immunity
- **Ground Returns**: Same gauge as power for proper current handling
### 🔗 Connector Strategy
{connector_type}
**Color Coding Standard**:
- 🔴 **Red**: +5V/+12V power
- **Black**: Ground (GND)
- 🟡 **Yellow**: Digital data/clock signals
- 🟢 **Green**: Analog sensor signals
- 🔵 **Blue**: Communication lines (SDA/SCL, TX/RX)
- 🟠 **Orange**: PWM/control signals
- 🟣 **Purple**: Enable/reset lines
### ⚡ Smart Harness Features
**🛡 Built-in Protection**:
- **Inline fuses** on power lines (auto-reset or blade type)
- **ESD protection** on signal lines with TVS diodes
- **Strain relief** at all connector entry points
- **Ferrite cores** on cables >50cm to reduce EMI
**🔧 Modular Design**:
- **Breakout connectors** for easy troubleshooting
- **Test points** at critical signal junctions
- **LED indicators** for power and activity status
- **Keyed connectors** to prevent reverse insertion
**📋 Professional Assembly**:
- **Heat shrink tubing** for insulation and strain relief
- **Cable ties** for neat routing and organization
- **Labels** on both ends with device names and pin functions
- **Documentation** with pinout diagrams and assembly notes
## 🎨 Custom Harness Advantages
**Plug-and-Play**: No breadboard wiring needed
**Reliable**: Industrial-grade connections
**Maintainable**: Modular design for easy servicing
**Professional**: Clean appearance for finished projects
**Debuggable**: Built-in test points and indicators
## 🚀 Ready to Design Your Custom Harness
**Say "Generate my connector harness" and I'll create:**
1. **Detailed wiring diagram** with all connections
2. **Cable assembly instructions** with part numbers
3. **Connector pinout tables** for each device
4. **Testing procedures** to verify correct assembly
5. **Professional documentation** for future reference
*Transform messy breadboard prototypes into clean, professional installations!*
"""
@mcp_prompt
async def circuit_troubleshooter(
self,
problem_description: str = Field(description="Describe the issue you're experiencing"),
circuit_components: str = Field(description="Components in your circuit (e.g., 'Arduino Uno, servo, LED, sensor')"),
symptoms: str = Field(description="What you observe (e.g., 'LED flickers, servo jitters, no sensor readings')")
) -> str:
"""Intelligent circuit troubleshooting assistant"""
components = [c.strip() for c in circuit_components.split(',')]
symptom_list = [s.strip() for s in symptoms.split(',')]
# Analyze common issues based on components and symptoms
power_issues = any(word in symptoms.lower() for word in ['flicker', 'dim', 'restart', 'reset', 'brown'])
signal_issues = any(word in symptoms.lower() for word in ['jitter', 'noise', 'intermittent', 'random'])
connection_issues = any(word in symptoms.lower() for word in ['nothing', 'dead', 'no response', 'not working'])
return f"""# 🔍 Circuit Troubleshooting Assistant
## ⚠️ Problem Analysis
**Issue**: {problem_description}
**Components**: {', '.join(components)}
**Symptoms**: {', '.join(symptom_list)}
## 🎯 Diagnostic Strategy
### 🔴 Primary Diagnosis
{self._generate_primary_diagnosis(power_issues, signal_issues, connection_issues, components)}
### 📊 Systematic Testing Procedure
**Step 1: Power System Verification**
- Measure voltage at Arduino 5V pin (should be 4.75-5.25V)
- Check current draw with multimeter (compare to component specs)
- Verify all ground connections with continuity test
- Look for voltage drops across long wires (>0.2V indicates undersized wire)
**Step 2: Signal Integrity Check** 📡
- Use oscilloscope/logic analyzer to check digital signals
- Verify pull-up resistors on I2C lines (4.7 typical)
- Check for signal reflections on long cables (>30cm)
- Measure analog signal noise levels and offsets
**Step 3: Component-Specific Tests** 🔧
{self._generate_component_tests(components)}
**Step 4: Environmental Factors** 🌡
- Check operating temperature ranges for all components
- Verify adequate ventilation for high-power devices
- Look for electromagnetic interference sources nearby
- Ensure stable mechanical connections (no loose wires)
## 🛠️ Common Solutions by Symptom
{self._generate_solutions_by_symptom(symptoms)}
## 🎯 Professional Debugging Tools
**Essential Tools** 🔧:
- **Digital Multimeter**: Voltage, current, resistance, continuity
- **Oscilloscope**: Signal timing, noise, amplitude analysis
- **Logic Analyzer**: Digital protocol debugging (I2C, SPI, UART)
- **Function Generator**: Signal injection for testing inputs
**Advanced Debugging** 🔬:
- **Protocol Analyzers**: Decode I2C, SPI communication errors
- **Thermal Camera**: Identify overheating components
- **EMI Detector**: Find sources of electromagnetic interference
- **Power Supply Analyzer**: Measure ripple, transient response
## 🚀 Next Steps
Based on your symptoms, I recommend starting with the **{self._recommend_first_step(power_issues, signal_issues, connection_issues)}** diagnostic steps.
**Say "Generate troubleshooting checklist" and I'll create a customized step-by-step debugging guide specific to your circuit and symptoms!**
*Professional circuit debugging - from symptoms to solutions!*
"""
def _generate_primary_diagnosis(self, power_issues, signal_issues, connection_issues, components):
"""Generate primary diagnosis based on symptoms"""
if power_issues:
return """
**🔴 POWER SYSTEM ISSUE SUSPECTED**
- Symptoms indicate insufficient power supply or voltage regulation problems
- Common with high-current components like servos, motors, LED strips
- Check power supply capacity and voltage regulation circuits
"""
elif signal_issues:
return """
**📡 SIGNAL INTEGRITY ISSUE SUSPECTED**
- Symptoms suggest noise, timing, or communication problems
- Often caused by improper grounding, long cables, or EMI
- Focus on signal quality, grounding, and cable routing
"""
elif connection_issues:
return """
**🔌 CONNECTION ISSUE SUSPECTED**
- Symptoms suggest open circuits, wrong pin assignments, or component failure
- Start with basic connectivity and pin assignment verification
- Check solder joints, connector integrity, and component orientation
"""
else:
return """
**🎯 COMPREHENSIVE DIAGNOSIS NEEDED**
- Multiple potential causes - systematic approach required
- Begin with power system verification, then move to signals
- Document measurements at each step for pattern analysis
"""
def _generate_component_tests(self, components):
"""Generate component-specific test procedures"""
tests = []
for component in components:
comp_lower = component.lower()
if 'servo' in comp_lower:
tests.append("- **Servo**: Test with known good PWM signal (1.5ms = center)")
elif 'sensor' in comp_lower or 'temperature' in comp_lower or 'humidity' in comp_lower:
tests.append("- **Sensor**: Verify power, check I2C address scan, test with known values")
elif 'led' in comp_lower:
tests.append("- **LED**: Test with current limiting resistor, check polarity")
elif 'motor' in comp_lower:
tests.append("- **Motor**: Check driver connections, verify PWM signals, test stall current")
elif 'display' in comp_lower or 'lcd' in comp_lower or 'oled' in comp_lower:
tests.append("- **Display**: Verify I2C/SPI connections, check contrast/brightness settings")
return '\n'.join(tests) if tests else "- **General**: Test each component individually with minimal circuit"
def _generate_solutions_by_symptom(self, symptoms):
"""Generate solutions organized by symptom"""
solutions = """
**🔋 Power Problems** (flickering, resets, dim output):
- Add decoupling capacitors (100µF + 0.1µF) near power inputs
- Use separate power supply for high-current components
- Upgrade to thicker gauge wires for power distribution
- Add ferrite cores to reduce switching noise
**📡 Signal Issues** (jitter, noise, intermittent operation):
- Implement proper star grounding topology
- Add pull-up resistors to I2C lines (4.7)
- Use twisted pair cables for differential signals
- Separate analog and digital ground planes
**🔌 Connection Problems** (dead circuits, no response):
- Verify pin assignments match your code
- Check solder joint quality with magnifying glass
- Test continuity of all connections with multimeter
- Ensure proper component orientation (polarity)
"""
return solutions
def _recommend_first_step(self, power_issues, signal_issues, connection_issues):
"""Recommend which diagnostic step to start with"""
if power_issues:
return "power system verification"
elif connection_issues:
return "basic connectivity testing"
else:
return "signal integrity analysis"
@mcp_prompt
async def pcb_layout_advisor(
self,
circuit_description: str = Field(description="Describe your circuit design"),
board_size: str = Field(default="medium", description="Preferred board size (small: <5cm, medium: 5-10cm, large: >10cm)"),
layer_count: str = Field(default="2", description="Number of PCB layers (2, 4, 6+)"),
special_requirements: str = Field(default="", description="Special needs (high frequency, high current, miniaturization, etc.)")
) -> str:
"""Professional PCB layout guidance and design recommendations"""
return f"""# 🔬 Professional PCB Layout Advisor
## 📋 Design Specifications
**Circuit**: {circuit_description}
**Board Size**: {board_size.title()} ({self._get_size_description(board_size)})
**Layer Count**: {layer_count} layers
**Special Requirements**: {special_requirements or "Standard design"}
## 🎯 PCB Layout Strategy
### 📐 Component Placement Optimization
**🔴 Power Section Layout**:
- Place voltage regulators near board edge for heat dissipation
- Use dedicated power planes (layer 2 for ground, layer 3 for power)
- Position bulk capacitors close to power input connectors
- Create power islands for different voltage domains (5V, 3.3V, analog)
**🧠 Microcontroller Placement**:
- Center microcontroller for equal trace lengths to peripherals
- Place crystal oscillator <1cm from MCU with guard traces
- Surround with decoupling capacitors (0.1µF + 10µF tantalum)
- Keep digital switching away from analog reference pins
**📡 High-Speed Signal Routing**:
- Route differential pairs with matched lengths (±0.1mm)
- Maintain 50Ω/100Ω impedance for single/differential signals
- Use via stitching every 5mm along transmission lines
- Avoid layer changes in critical timing paths
### ⚡ Advanced Layout Techniques
**🛡 EMI/EMC Optimization**:
- Surround board perimeter with grounded guard traces
- Use ground pour with thermal reliefs for heat dissipation
- Route high-speed clocks away from board edges and connectors
- Add ferrite bead footprints on power and signal lines
**🌡 Thermal Management**:
- Create thermal vias under high-power components (9 vias/cm²)
- Use copper pours for heat spreading (minimum 35µm thickness)
- Orient components for natural convection airflow
- Consider heat sinks and thermal interface materials
**🔧 Manufacturing Optimization**:
- Maintain minimum trace width: 0.1mm (4 mil) for standard fab
- Keep via sizes 0.2mm (8 mil) for reliable plating
- Use teardrop pads for mechanical strength
- Add fiducial markers for automated assembly
## 🎨 Layer Stack-Up Recommendations
{self._generate_layer_stackup(layer_count)}
## 📊 Design Rule Check (DRC) Guidelines
** Critical Spacing Rules**:
- Trace to trace: 0.1mm (4 mil)
- Trace to via: 0.075mm (3 mil)
- Via to via: 0.2mm (8 mil)
- Copper to board edge: 0.2mm (8 mil)
** Power Delivery Network**:
- Calculate voltage drop: <5% of supply voltage
- Size traces for 1A/mm² current density (external layers)
- Use multiple vias for high-current connections (>1A)
- Add test points for power rail verification
## 🚀 Professional PCB Features
**🔍 Testing & Debug**:
- Add test points on all critical signals (1mm diameter)
- Include JTAG/SWD connector for microcontroller debugging
- Route unused pins to test pads for future expansion
- Add LED indicators for power rails and critical signals
**🔧 Assembly & Rework**:
- Use standard component packages when possible
- Add component reference designators on silkscreen
- Include polarity markers for diodes, capacitors, connectors
- Leave space around components for rework access
**📋 Documentation Package**:
- Generate complete fabrication files (Gerber + Excellon)
- Create assembly drawings with component placement
- Provide bill of materials with manufacturer part numbers
- Include PCB stackup specification for fabrication
## 🎯 Ready for Professional PCB Design
**Say "Generate my PCB layout plan" and I'll create:**
1. **Detailed component placement strategy** optimized for your circuit
2. **Layer-by-layer routing plan** with impedance control
3. **Manufacturing file checklist** for fabrication
4. **Assembly documentation** for professional production
5. **Testing and validation procedures** for quality assurance
*Transform your breadboard prototype into a production-ready PCB design!*
"""
def _get_size_description(self, size):
"""Get description for board size"""
sizes = {
"small": "compact designs, space-constrained applications",
"medium": "standard development boards, general projects",
"large": "complex systems, high component density"
}
return sizes.get(size, "custom sizing based on requirements")
def _generate_layer_stackup(self, layer_count):
"""Generate appropriate layer stackup"""
if layer_count == "2":
return """
**2-Layer Stackup** (Cost-effective for simple designs):
- **Layer 1 (Top)**: Component placement + signal routing
- **Layer 2 (Bottom)**: Ground plane + power traces
- **Dielectric**: Standard FR4, 1.6mm thickness
- **Copper Weight**: 1oz (35µm) for standard current handling
"""
elif layer_count == "4":
return """
**4-Layer Stackup** (Recommended for mixed-signal designs):
- **Layer 1 (Top)**: Component placement + high-speed signals
- **Layer 2**: Ground plane (solid pour)
- **Layer 3**: Power planes (split for different voltages)
- **Layer 4 (Bottom)**: Low-speed signals + power distribution
- **Dielectric**: Controlled impedance FR4, 1.6mm total
- **Copper Weight**: 1oz standard, 2oz for power layers
"""
else:
return """
**6+ Layer Stackup** (High-performance designs):
- **Layer 1**: Components + critical signals
- **Layer 2**: Ground plane
- **Layer 3**: High-speed signal layer 1
- **Layer 4**: Power plane (+5V, +3.3V splits)
- **Layer 5**: High-speed signal layer 2
- **Layer 6+**: Additional signal/power layers as needed
- **Controlled Impedance**: 50Ω ±10% single-ended, 100Ω ±10% differential
"""