jmisak commited on
Commit
4858e1f
·
verified ·
1 Parent(s): c6b3c86

Upload 5 files

Browse files
Files changed (3) hide show
  1. CHANGELOG.md +7 -4
  2. README.md +170 -170
  3. survey_generator.py +92 -75
CHANGELOG.md CHANGED
@@ -49,10 +49,13 @@ All notable changes to ConversAI will be documented in this file.
49
  - Better at JSON generation than smaller models
50
  - User can upgrade to xl/xxl or downgrade to base via LLM_MODEL env var
51
 
52
- - **Improved prompts** in `survey_generator.py`:
53
- - Simplified prompts for better T5 model compatibility
54
- - Added fallback survey generation if JSON parsing fails
55
- - More direct instructions with concrete examples
 
 
 
56
 
57
  - **New dependencies added** to requirements.txt:
58
  - transformers>=4.36.0
 
49
  - Better at JSON generation than smaller models
50
  - User can upgrade to xl/xxl or downgrade to base via LLM_MODEL env var
51
 
52
+ - **Complete rewrite of survey generation** in `survey_generator.py`:
53
+ - **Changed approach**: No longer asks model to generate JSON (T5 models struggle with structured output)
54
+ - **New workflow**: Model generates simple numbered list → we parse into JSON
55
+ - **Intelligent type detection**: Automatically detects question types (rating, yes/no, Likert, open-ended) based on keywords
56
+ - **Better reliability**: Plays to T5 strengths (text generation) instead of weaknesses (JSON)
57
+ - **Automatic title generation**: Creates survey title from user's outline
58
+ - Result: Much more reliable survey generation with T5 models
59
 
60
  - **New dependencies added** to requirements.txt:
61
  - transformers>=4.36.0
README.md CHANGED
@@ -1,170 +1,170 @@
1
- ---
2
- title: ProjectEcho - Qualitative Research Assistant
3
- emoji: 🔬
4
- colorFrom: blue
5
- colorTo: purple
6
- sdk: gradio
7
- sdk_version: 5.45.0
8
- app_file: app.py
9
- pinned: false
10
- license: mit
11
- ---
12
-
13
- # ConversAI - AI-Powered Qualitative Research Assistant
14
-
15
- Battle the blank page, reach global audiences, and uncover insights with AI assistance.
16
-
17
- ---
18
-
19
- > **✨ UPDATED (Nov 2025):** Now uses **local transformers** with **Google Flan-T5** models - Fast, reliable, and **completely FREE**! No API dependencies, runs directly on HuggingFace Spaces.
20
-
21
- ---
22
-
23
- ## 🌟 Features
24
-
25
- ### 📝 Survey Generation
26
- - Generate professional surveys from simple outlines
27
- - Follow industry best practices automatically
28
- - Choose from qualitative, quantitative, or mixed methods
29
- - Customize number of questions and target audience
30
-
31
- ### 🌍 Survey Translation
32
- - Translate surveys to 18+ languages
33
- - Maintain cultural appropriateness and meaning
34
- - Reach global audiences effortlessly
35
- - Batch translation support
36
-
37
- ### 📊 Data Analysis
38
- - AI-assisted thematic analysis
39
- - Sentiment analysis and emotional insights
40
- - Automatic pattern and trend detection
41
- - Generate actionable insights and recommendations
42
- - Export detailed analysis reports
43
-
44
- ## 🚀 Quick Start
45
-
46
- **On HuggingFace Spaces:** Works immediately with zero configuration! Uses the free HF Inference API.
47
-
48
- **Workflow:**
49
- 1. **Generate a Survey**: Start with an outline or topic description
50
- 2. **Translate**: Select target languages to reach global audiences
51
- 3. **Collect Responses**: Use the generated survey with your participants
52
- 4. **Analyze**: Upload responses to uncover key findings and trends
53
-
54
- ## 🔧 Configuration
55
-
56
- ### Default: Local Transformers (Completely FREE!)
57
-
58
- **✨ Zero configuration needed!** ConversAI works out-of-the-box on HuggingFace Spaces using local model loading.
59
-
60
- **Default Model:** google/flan-t5-large
61
- - ✅ **100% Free** - No API keys, no costs, ever
62
- - ✅ **Good quality** - 1.2GB model, excellent at following instructions
63
- - ✅ **Fast after loading** - Typically 3-8 seconds per request after initial load
64
- - ✅ **No API dependencies** - Runs entirely on your Space's compute
65
- - ✅ **Private** - All processing happens locally, nothing sent to external APIs
66
- - ✅ **Reliable** - Google's instruction-tuned model, battle-tested
67
-
68
- **Setup for HuggingFace Spaces:**
69
- - Just deploy - models download automatically on first run
70
- - **No API keys or tokens required!**
71
- - Models are cached after first download for faster subsequent loads
72
-
73
- ### Alternative Free Models
74
-
75
- You can try different free models by setting the `LLM_MODEL` environment variable:
76
-
77
- **Recommended Free Models (Local Transformers):**
78
-
79
- | Model | Best For | Speed | Quality | Model Size |
80
- |-------|----------|-------|---------|------------|
81
- | **google/flan-t5-base** | Testing - fastest | ⚡⚡⚡ Very Fast | ⭐⭐ Basic | 250MB |
82
- | **google/flan-t5-large** (default) | **Recommended** - balanced | ⚡⚡ Fast | ⭐⭐⭐ Good | 1.2GB |
83
- | **google/flan-t5-xl** | Better quality | ⚡ Medium | ⭐⭐⭐⭐ Excellent | 3GB |
84
- | **google/flan-t5-xxl** | Maximum quality | ⚡ Slower | ⭐⭐⭐⭐⭐ Best | 11GB |
85
-
86
- **Note:** Flan-T5 models are Google's instruction-tuned models, specifically designed for following instructions. They run locally with transformers library.
87
-
88
- **To change model:**
89
- ```bash
90
- # In Space Settings → Variables
91
- LLM_MODEL=google/flan-t5-large # Better quality
92
-
93
- # Or for maximum quality (requires more memory)
94
- LLM_MODEL=google/flan-t5-xl
95
- ```
96
-
97
- **Why Local Transformers?**
98
- - ✅ **No API dependencies** - runs entirely on your Space
99
- - ✅ **No 404 errors** - no network issues
100
- - ✅ **Fast after loading** - models cached in memory
101
- - ✅ **Instruction-tuned** - designed for following prompts
102
- - ✅ **Privacy** - all processing happens locally
103
-
104
- ### Tips for Best Performance with Local Models
105
-
106
- 1. **Default model (flan-t5-large) is recommended** - Good balance of quality and speed
107
- 2. **First load takes time** - Model downloads and loads (~2-3 minutes for large)
108
- 3. **Subsequent requests are fast** - Model stays in memory (3-8 seconds)
109
- 4. **For simple testing** - Use flan-t5-base (faster loading)
110
- 5. **For best quality** - Use flan-t5-xl or xxl (requires more memory)
111
- 6. **Keep prompts clear** - Simpler outlines work better with smaller models
112
-
113
- ## 📦 Installation
114
-
115
- ```bash
116
- # Install dependencies
117
- pip install -r requirements.txt
118
-
119
- # Check environment setup (optional but recommended)
120
- python check_env.py
121
-
122
- # Run the app
123
- python app.py
124
- ```
125
-
126
- ## 🏗️ Architecture
127
-
128
- ConversAI is built with a modular architecture:
129
-
130
- - **llm_backend.py** - Unified LLM interface supporting multiple providers
131
- - **survey_generator.py** - AI-powered survey generation
132
- - **survey_translator.py** - Multi-language translation engine
133
- - **data_analyzer.py** - Qualitative data analysis and insights
134
- - **app.py** - Gradio-based web interface
135
- - **export_utils.py** - Export to JSON, CSV, Markdown
136
-
137
- ## 📄 Data Privacy
138
-
139
- - All processing is done through your configured LLM provider
140
- - No data is stored permanently by this application
141
- - Survey data and responses remain in your control
142
- - Suitable for sensitive research projects
143
-
144
- ## 🤝 Contributing
145
-
146
- Contributions are welcome! This is a production-grade application designed for real-world qualitative research.
147
-
148
- ## 📝 License
149
-
150
- MIT License - Feel free to use for research and commercial purposes.
151
-
152
- ---
153
-
154
- ## 📚 Documentation
155
-
156
- **New to ConversAI?** Start with **[USER_GUIDE.md](USER_GUIDE.md)** for a complete walkthrough.
157
-
158
- **Quick Links:**
159
- - 📖 [Complete User Guide](USER_GUIDE.md) - How to use ConversAI (START HERE)
160
- - ⚡ [Quick Start for HF Spaces](QUICK_START_HF_SPACES.md) - 5-minute deployment
161
- - 🔧 [Troubleshooting](TROUBLESHOOTING.md) - Common issues and solutions
162
- - 🆓 [Free Models Guide](FREE_MODELS.md) - Best free models to use
163
-
164
- **Diagnostic Tools:**
165
- - Run `python check_env.py` - Check your environment setup
166
- - Run `python test_hf_backend.py` - Test HuggingFace connection
167
-
168
- ---
169
-
170
- Built with ❤️ using Gradio and state-of-the-art open-source LLMs
 
1
+ ---
2
+ title: ConversAI - Qualitative Research Assistant
3
+ emoji: 🔬
4
+ colorFrom: blue
5
+ colorTo: purple
6
+ sdk: gradio
7
+ sdk_version: 5.45.0
8
+ app_file: app.py
9
+ pinned: false
10
+ license: mit
11
+ ---
12
+
13
+ # ConversAI - AI-Powered Qualitative Research Assistant
14
+
15
+ Battle the blank page, reach global audiences, and uncover insights with AI assistance.
16
+
17
+ ---
18
+
19
+ > **✨ UPDATED (Nov 2025):** Now uses **local transformers** with **Google Flan-T5** models - Fast, reliable, and **completely FREE**! No API dependencies, runs directly on HuggingFace Spaces.
20
+
21
+ ---
22
+
23
+ ## 🌟 Features
24
+
25
+ ### 📝 Survey Generation
26
+ - Generate professional surveys from simple outlines
27
+ - Follow industry best practices automatically
28
+ - Choose from qualitative, quantitative, or mixed methods
29
+ - Customize number of questions and target audience
30
+
31
+ ### 🌍 Survey Translation
32
+ - Translate surveys to 18+ languages
33
+ - Maintain cultural appropriateness and meaning
34
+ - Reach global audiences effortlessly
35
+ - Batch translation support
36
+
37
+ ### 📊 Data Analysis
38
+ - AI-assisted thematic analysis
39
+ - Sentiment analysis and emotional insights
40
+ - Automatic pattern and trend detection
41
+ - Generate actionable insights and recommendations
42
+ - Export detailed analysis reports
43
+
44
+ ## 🚀 Quick Start
45
+
46
+ **On HuggingFace Spaces:** Works immediately with zero configuration! Uses the free HF Inference API.
47
+
48
+ **Workflow:**
49
+ 1. **Generate a Survey**: Start with an outline or topic description
50
+ 2. **Translate**: Select target languages to reach global audiences
51
+ 3. **Collect Responses**: Use the generated survey with your participants
52
+ 4. **Analyze**: Upload responses to uncover key findings and trends
53
+
54
+ ## 🔧 Configuration
55
+
56
+ ### Default: Local Transformers (Completely FREE!)
57
+
58
+ **✨ Zero configuration needed!** ConversAI works out-of-the-box on HuggingFace Spaces using local model loading.
59
+
60
+ **Default Model:** google/flan-t5-large
61
+ - ✅ **100% Free** - No API keys, no costs, ever
62
+ - ✅ **Good quality** - 1.2GB model, excellent at following instructions
63
+ - ✅ **Fast after loading** - Typically 3-8 seconds per request after initial load
64
+ - ✅ **No API dependencies** - Runs entirely on your Space's compute
65
+ - ✅ **Private** - All processing happens locally, nothing sent to external APIs
66
+ - ✅ **Reliable** - Google's instruction-tuned model, battle-tested
67
+
68
+ **Setup for HuggingFace Spaces:**
69
+ - Just deploy - models download automatically on first run
70
+ - **No API keys or tokens required!**
71
+ - Models are cached after first download for faster subsequent loads
72
+
73
+ ### Alternative Free Models
74
+
75
+ You can try different free models by setting the `LLM_MODEL` environment variable:
76
+
77
+ **Recommended Free Models (Local Transformers):**
78
+
79
+ | Model | Best For | Speed | Quality | Model Size |
80
+ |-------|----------|-------|---------|------------|
81
+ | **google/flan-t5-base** | Testing - fastest | ⚡⚡⚡ Very Fast | ⭐⭐ Basic | 250MB |
82
+ | **google/flan-t5-large** (default) | **Recommended** - balanced | ⚡⚡ Fast | ⭐⭐⭐ Good | 1.2GB |
83
+ | **google/flan-t5-xl** | Better quality | ⚡ Medium | ⭐⭐⭐⭐ Excellent | 3GB |
84
+ | **google/flan-t5-xxl** | Maximum quality | ⚡ Slower | ⭐⭐⭐⭐⭐ Best | 11GB |
85
+
86
+ **Note:** Flan-T5 models are Google's instruction-tuned models, specifically designed for following instructions. They run locally with transformers library.
87
+
88
+ **To change model:**
89
+ ```bash
90
+ # In Space Settings → Variables
91
+ LLM_MODEL=google/flan-t5-large # Better quality
92
+
93
+ # Or for maximum quality (requires more memory)
94
+ LLM_MODEL=google/flan-t5-xl
95
+ ```
96
+
97
+ **Why Local Transformers?**
98
+ - ✅ **No API dependencies** - runs entirely on your Space
99
+ - ✅ **No 404 errors** - no network issues
100
+ - ✅ **Fast after loading** - models cached in memory
101
+ - ✅ **Instruction-tuned** - designed for following prompts
102
+ - ✅ **Privacy** - all processing happens locally
103
+
104
+ ### Tips for Best Performance with Local Models
105
+
106
+ 1. **Default model (flan-t5-large) is recommended** - Good balance of quality and speed
107
+ 2. **First load takes time** - Model downloads and loads (~2-3 minutes for large)
108
+ 3. **Subsequent requests are fast** - Model stays in memory (3-8 seconds)
109
+ 4. **For simple testing** - Use flan-t5-base (faster loading)
110
+ 5. **For best quality** - Use flan-t5-xl or xxl (requires more memory)
111
+ 6. **Keep prompts clear** - Simpler outlines work better with smaller models
112
+
113
+ ## 📦 Installation
114
+
115
+ ```bash
116
+ # Install dependencies
117
+ pip install -r requirements.txt
118
+
119
+ # Check environment setup (optional but recommended)
120
+ python check_env.py
121
+
122
+ # Run the app
123
+ python app.py
124
+ ```
125
+
126
+ ## 🏗️ Architecture
127
+
128
+ ConversAI is built with a modular architecture:
129
+
130
+ - **llm_backend.py** - Unified LLM interface supporting multiple providers
131
+ - **survey_generator.py** - AI-powered survey generation
132
+ - **survey_translator.py** - Multi-language translation engine
133
+ - **data_analyzer.py** - Qualitative data analysis and insights
134
+ - **app.py** - Gradio-based web interface
135
+ - **export_utils.py** - Export to JSON, CSV, Markdown
136
+
137
+ ## 📄 Data Privacy
138
+
139
+ - All processing is done through your configured LLM provider
140
+ - No data is stored permanently by this application
141
+ - Survey data and responses remain in your control
142
+ - Suitable for sensitive research projects
143
+
144
+ ## 🤝 Contributing
145
+
146
+ Contributions are welcome! This is a production-grade application designed for real-world qualitative research.
147
+
148
+ ## 📝 License
149
+
150
+ MIT License - Feel free to use for research and commercial purposes.
151
+
152
+ ---
153
+
154
+ ## 📚 Documentation
155
+
156
+ **New to ConversAI?** Start with **[USER_GUIDE.md](USER_GUIDE.md)** for a complete walkthrough.
157
+
158
+ **Quick Links:**
159
+ - 📖 [Complete User Guide](USER_GUIDE.md) - How to use ConversAI (START HERE)
160
+ - ⚡ [Quick Start for HF Spaces](QUICK_START_HF_SPACES.md) - 5-minute deployment
161
+ - 🔧 [Troubleshooting](TROUBLESHOOTING.md) - Common issues and solutions
162
+ - 🆓 [Free Models Guide](FREE_MODELS.md) - Best free models to use
163
+
164
+ **Diagnostic Tools:**
165
+ - Run `python check_env.py` - Check your environment setup
166
+ - Run `python test_hf_backend.py` - Test HuggingFace connection
167
+
168
+ ---
169
+
170
+ Built with ❤️ using Gradio and state-of-the-art open-source LLMs
survey_generator.py CHANGED
@@ -43,6 +43,9 @@ class SurveyGenerator:
43
  response = self.llm.generate(messages, max_tokens=2000, temperature=0.7)
44
  survey_data = self._parse_survey_response(response)
45
 
 
 
 
46
  # Add metadata
47
  survey_data["metadata"] = {
48
  "outline": outline,
@@ -56,103 +59,117 @@ class SurveyGenerator:
56
  except Exception as e:
57
  raise Exception(f"Survey generation failed: {str(e)}")
58
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  def _get_system_prompt(self) -> str:
60
  """System prompt for survey generation"""
61
- return """You are a professional survey designer. Create surveys in valid JSON format only."""
62
 
63
  def _build_generation_prompt(self, outline, survey_type, num_questions, target_audience) -> str:
64
  """Build the user prompt for survey generation"""
65
- # For T5 models, we need a very simple, direct instruction
66
- return f"""Task: Generate a JSON survey.
67
 
68
- Topic: {outline}
69
- Questions needed: {num_questions}
70
- Audience: {target_audience}
71
- Type: {survey_type}
72
 
73
- Required JSON format:
74
- {{"title": "Survey Title Here", "introduction": "Welcome message here", "questions": [{{"id": 1, "question_text": "Your first question?", "question_type": "open_ended", "required": true}}, {{"id": 2, "question_text": "Your second question?", "question_type": "open_ended", "required": true}}], "closing": "Thank you message here"}}
75
 
76
- Generate the complete survey JSON now:"""
 
 
 
 
 
77
 
78
  def _parse_survey_response(self, response: str) -> Dict:
79
  """Parse LLM response into survey structure"""
80
- # Try to extract JSON from response
81
- response = response.strip()
82
-
83
- # Handle code blocks
84
- if "```json" in response:
85
- start = response.find("```json") + 7
86
- end = response.find("```", start)
87
- response = response[start:end].strip()
88
- elif "```" in response:
89
- start = response.find("```") + 3
90
- end = response.find("```", start)
91
- response = response[start:end].strip()
92
-
93
- # Try to find JSON object in response
94
- if "{" in response and "}" in response:
95
- start = response.find("{")
96
- end = response.rfind("}") + 1
97
- response = response[start:end]
98
-
99
- try:
100
- survey_data = json.loads(response)
101
-
102
- # Validate required fields
103
- required_fields = ["title", "introduction", "questions", "closing"]
104
- for field in required_fields:
105
- if field not in survey_data:
106
- raise ValueError(f"Missing required field: {field}")
107
 
108
- # Validate questions
109
- if not isinstance(survey_data["questions"], list) or len(survey_data["questions"]) == 0:
110
- raise ValueError("Survey must contain at least one question")
111
-
112
- return survey_data
113
-
114
- except (json.JSONDecodeError, ValueError) as e:
115
- # Fallback: Try to create a simple survey from the response
116
- print(f"Warning: JSON parsing failed, attempting fallback. Error: {e}")
117
- return self._create_fallback_survey(response)
118
-
119
- def _create_fallback_survey(self, response: str) -> Dict:
120
- """Create a basic survey structure from non-JSON response"""
121
- # Extract potential questions from numbered list
122
  lines = [line.strip() for line in response.split('\n') if line.strip()]
123
 
124
- # Look for numbered items or lines with question marks
125
  questions = []
126
  question_id = 1
127
 
128
  for line in lines:
129
- # Remove leading numbers, bullets, etc.
130
- clean_line = line.lstrip('0123456789.-) ')
131
-
132
- # Check if it looks like a question
133
- if len(clean_line) > 10 and (clean_line.endswith('?') or
134
- any(word in clean_line.lower() for word in ['what', 'how', 'why', 'when', 'where', 'which', 'would', 'could', 'should', 'do you'])):
135
- questions.append({
136
- "id": question_id,
137
- "question_text": clean_line,
138
- "question_type": "open_ended",
139
- "required": True
140
- })
141
- question_id += 1
142
-
143
- # If we didn't find enough questions, create generic ones
144
- if len(questions) < 3:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
  questions = [
146
- {"id": 1, "question_text": "What are your thoughts on this topic?", "question_type": "open_ended", "required": True},
147
- {"id": 2, "question_text": "Can you describe your experience?", "question_type": "open_ended", "required": True},
148
- {"id": 3, "question_text": "What suggestions do you have for improvement?", "question_type": "open_ended", "required": True}
149
  ]
150
 
151
  return {
152
- "title": "Survey",
153
- "introduction": "Thank you for participating in this survey. Please answer the following questions.",
154
- "questions": questions[:10], # Limit to 10 questions
155
- "closing": "Thank you for your time and feedback!"
156
  }
157
 
158
  def refine_question(self, question: str, improvement_type: str = "clarity") -> str:
 
43
  response = self.llm.generate(messages, max_tokens=2000, temperature=0.7)
44
  survey_data = self._parse_survey_response(response)
45
 
46
+ # Generate better title based on outline
47
+ survey_data["title"] = self._generate_title(outline, survey_type)
48
+
49
  # Add metadata
50
  survey_data["metadata"] = {
51
  "outline": outline,
 
59
  except Exception as e:
60
  raise Exception(f"Survey generation failed: {str(e)}")
61
 
62
+ def _generate_title(self, outline: str, survey_type: str) -> str:
63
+ """Generate a survey title from the outline"""
64
+ # Extract key topic from outline (first sentence or first 50 chars)
65
+ first_sentence = outline.split('.')[0].strip()
66
+ if len(first_sentence) > 60:
67
+ first_sentence = first_sentence[:60] + "..."
68
+
69
+ # Capitalize first letter
70
+ topic = first_sentence[0].upper() + first_sentence[1:] if first_sentence else "Research"
71
+
72
+ # Create title based on survey type
73
+ if survey_type.lower() == "qualitative":
74
+ return f"{topic} - Qualitative Survey"
75
+ elif survey_type.lower() == "quantitative":
76
+ return f"{topic} - Quantitative Survey"
77
+ else:
78
+ return f"{topic} Survey"
79
+
80
  def _get_system_prompt(self) -> str:
81
  """System prompt for survey generation"""
82
+ return """You are a professional survey designer. Generate clear, professional survey questions."""
83
 
84
  def _build_generation_prompt(self, outline, survey_type, num_questions, target_audience) -> str:
85
  """Build the user prompt for survey generation"""
86
+ # For T5 models, ask for simple numbered list instead of JSON
87
+ return f"""Generate {num_questions} survey questions about: {outline}
88
 
89
+ Target audience: {target_audience}
90
+ Survey type: {survey_type}
 
 
91
 
92
+ Create {num_questions} clear, professional questions. Write each question on a new line starting with a number.
 
93
 
94
+ Example format:
95
+ 1. What is your overall experience with [topic]?
96
+ 2. How would you rate [specific aspect]?
97
+ 3. What improvements would you suggest?
98
+
99
+ Now generate {num_questions} questions:"""
100
 
101
  def _parse_survey_response(self, response: str) -> Dict:
102
  """Parse LLM response into survey structure"""
103
+ # Parse numbered list format (not JSON)
104
+ return self._parse_numbered_list(response)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
 
106
+ def _parse_numbered_list(self, response: str) -> Dict:
107
+ """Parse numbered list of questions into survey structure"""
 
 
 
 
 
 
 
 
 
 
 
 
108
  lines = [line.strip() for line in response.split('\n') if line.strip()]
109
 
 
110
  questions = []
111
  question_id = 1
112
 
113
  for line in lines:
114
+ # Skip empty lines or lines that are too short
115
+ if len(line) < 5:
116
+ continue
117
+
118
+ # Remove leading numbers, bullets, dashes, etc.
119
+ clean_line = line.lstrip('0123456789.-) \t')
120
+
121
+ # Skip lines that don't look like questions
122
+ if len(clean_line) < 10:
123
+ continue
124
+
125
+ # Determine question type based on content
126
+ question_type = "open_ended"
127
+ options = None
128
+
129
+ lower_line = clean_line.lower()
130
+
131
+ # Check for rating/scale questions
132
+ if any(word in lower_line for word in ['rate', 'scale', 'rating', 'score']):
133
+ question_type = "rating"
134
+ options = ["1 - Poor", "2 - Fair", "3 - Good", "4 - Very Good", "5 - Excellent"]
135
+
136
+ # Check for yes/no questions
137
+ elif clean_line.endswith('?') and any(word in lower_line for word in ['do you', 'have you', 'would you', 'can you', 'should', 'is it', 'are you']):
138
+ if 'how much' not in lower_line and 'how many' not in lower_line:
139
+ question_type = "yes_no"
140
+ options = ["Yes", "No"]
141
+
142
+ # Check for satisfaction questions
143
+ elif any(word in lower_line for word in ['satisfy', 'satisfaction', 'satisfied']):
144
+ question_type = "likert_scale"
145
+ options = ["Very Satisfied", "Satisfied", "Neutral", "Dissatisfied", "Very Dissatisfied"]
146
+
147
+ question = {
148
+ "id": question_id,
149
+ "question_text": clean_line,
150
+ "question_type": question_type,
151
+ "required": True
152
+ }
153
+
154
+ if options:
155
+ question["options"] = options
156
+
157
+ questions.append(question)
158
+ question_id += 1
159
+
160
+ # If we didn't find any questions, create generic ones
161
+ if len(questions) == 0:
162
  questions = [
163
+ {"id": 1, "question_text": "What are your overall thoughts on this topic?", "question_type": "open_ended", "required": True},
164
+ {"id": 2, "question_text": "Can you describe your experience in detail?", "question_type": "open_ended", "required": True},
165
+ {"id": 3, "question_text": "What specific suggestions do you have for improvement?", "question_type": "open_ended", "required": True}
166
  ]
167
 
168
  return {
169
+ "title": "Research Survey",
170
+ "introduction": "Thank you for taking the time to participate in this survey. Your responses will help us better understand your experiences and perspectives. Please answer all questions honestly and thoroughly.",
171
+ "questions": questions[:20], # Limit to 20 questions
172
+ "closing": "Thank you for your valuable time and feedback! Your responses are greatly appreciated and will be used to improve our understanding of this topic."
173
  }
174
 
175
  def refine_question(self, question: str, improvement_type: str = "clarity") -> str: