Severian commited on
Commit
bb2512f
1 Parent(s): 0b8d5f8

Upload 7 files

Browse files
Files changed (7) hide show
  1. Blueprint.md +409 -0
  2. chatbot.py +165 -0
  3. config.py +49 -0
  4. data_models.py +61 -0
  5. main.py +194 -0
  6. requirements.txt +6 -0
  7. utils.py +456 -0
Blueprint.md ADDED
@@ -0,0 +1,409 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Technical Blueprint for Innovative Idea Generator Chatbot (Updated)
2
+
3
+ ## Table of Contents
4
+
5
+ 1. [Introduction](#introduction)
6
+ 2. [High-Level Overview](#high-level-overview)
7
+ - [Purpose and Goals](#purpose-and-goals)
8
+ - [Key Functionalities](#key-functionalities)
9
+ 3. [System Architecture](#system-architecture)
10
+ - [Components](#components)
11
+ - [Data Flow](#data-flow)
12
+ 4. [Detailed Module Design](#detailed-module-design)
13
+ - [Chatbot Interaction Module](#chatbot-interaction-module)
14
+ - [Stage-Based Interaction](#stage-based-interaction)
15
+ - [Dynamic Follow-ups](#dynamic-follow-ups)
16
+ - [Context Preservation](#context-preservation)
17
+ - [Data Collection and Refinement Module](#data-collection-and-refinement-module)
18
+ - [Input Parsing](#input-parsing)
19
+ - [Data Storage](#data-storage)
20
+ - [Data Refinement](#data-refinement)
21
+ - [Stage Management Module](#stage-management-module)
22
+ - [Stage Buttons Interface](#stage-buttons-interface)
23
+ - [Function Modularity](#function-modularity)
24
+ - [Web Search Integration Module](#web-search-integration-module)
25
+ - [LLM-Triggered Web Searches](#llm-triggered-web-searches)
26
+ - [User-Triggered Web Searches](#user-triggered-web-searches)
27
+ - [Database Management Module](#database-management-module)
28
+ - [Data Storage Format](#data-storage-format)
29
+ - [Dynamic Editing](#dynamic-editing)
30
+ 5. [Implementation Details](#implementation-details)
31
+ - [Python and Gradio Usage](#python-and-gradio-usage)
32
+ - [Module and Function Organization](#module-and-function-organization)
33
+ - [Error Handling and Validation](#error-handling-and-validation)
34
+ - [LLM Context and Memory Management](#llm-context-and-memory-management)
35
+ - [User Interface Enhancements](#user-interface-enhancements)
36
+ 6. [Additional Considerations](#additional-considerations)
37
+ - [Scalability and Extensibility](#scalability-and-extensibility)
38
+ - [Security and Privacy](#security-and-privacy)
39
+ - [Testing and Validation](#testing-and-validation)
40
+ 7. [Conclusion](#conclusion)
41
+
42
+ ---
43
+
44
+ ## Introduction
45
+
46
+ This blueprint outlines the technical design for the **Innovative Idea Generator Chatbot**, an application aimed at transforming user ideas into well-defined project proposals ready for prototyping. The chatbot guides users through a structured, stage-based workflow, refining their inputs, and dynamically storing data for further editing and retrieval. The application is developed using **Python** and **Gradio**, adhering strictly to Python-based frameworks without the use of JavaScript, Next.js, or similar technologies.
47
+
48
+ ---
49
+
50
+ ## High-Level Overview
51
+
52
+ ### Purpose and Goals
53
+
54
+ - **Objective**: Assist users in refining raw ideas into structured project proposals.
55
+ - **Outcome**: Generate a comprehensive proposal by collecting, refining, and storing user inputs through guided, stage-by-stage interactions.
56
+
57
+ ### Key Functionalities
58
+
59
+ 1. **Stage-Based Interaction**: Users navigate through the idea development process using individual stage buttons.
60
+ 2. **Dynamic Follow-ups**: Trigger additional questions based on user responses for clarification.
61
+ 3. **Data Refinement**: Rewrite user inputs for clarity and store them dynamically.
62
+ 4. **Context Preservation**: Maintain conversation history for seamless interactions.
63
+ 5. **Web Search Integration**: Allow both LLM and users to perform web searches during the interaction.
64
+ 6. **Data Storage and Editing**: Store all collected data in a dynamic database accessible for modifications.
65
+ 7. **Stage Navigation with Buttons**: Replace progress tracking bar with a checklist of clickable stage buttons.
66
+ 8. **Stage-Specific Processing**: LLM processes one stage at a time based on user-activated buttons.
67
+ 9. **Customizable AI Settings**: Allow users to select models and adjust generation parameters.
68
+ 10. **API Key Management**: Enable users to securely input their Hugging Face API keys for model interactions.
69
+
70
+ ---
71
+
72
+ ## System Architecture
73
+
74
+ ### Components
75
+
76
+ 1. **User Interface (UI)**: Built with Gradio, providing a stage-based button interface and corresponding text fields.
77
+ 2. **Chatbot Engine**: Manages conversations, including stage-specific prompts and response handling.
78
+ 3. **Language Model (LLM) Interaction**: Utilizes an LLM for generating responses and processing inputs.
79
+ 4. **Data Storage**: A database (SQL or CSV) for storing refined user inputs and conversation history.
80
+ 5. **Web Search Module**: Integrates web search capabilities using APIs (e.g., DuckDuckGo Search).
81
+ 6. **API Management Module**: Handles secure input and storage of user-provided API keys.
82
+ 7. **Stage Management Interface**: Manages the display and interaction of stage buttons and corresponding text fields.
83
+
84
+ ### Data Flow
85
+
86
+ 1. **User Activation**: User clicks a stage button to initiate a specific stage.
87
+ 2. **LLM Processing**: Chatbot focuses on the selected stage, prompting the user for relevant information.
88
+ 3. **User Input**: User provides input for the stage.
89
+ 4. **Data Refinement**: LLM refines the input for clarity and coherence.
90
+ 5. **Form Population**: User presses the 'Fill Out Form' button to populate the corresponding text field with refined data.
91
+ 6. **Data Storage**: Refined inputs are stored in the database.
92
+ 7. **Web Search**: Triggered by the LLM or user, with results incorporated into the conversation.
93
+ 8. **Stage Completion**: User marks the stage as complete before moving to the next stage.
94
+ 9. **Feedback Loop**: Process repeats until all stages are completed.
95
+
96
+ ---
97
+
98
+ ## Detailed Module Design
99
+
100
+ ### Chatbot Interaction Module
101
+
102
+ #### Stage-Based Interaction
103
+
104
+ - **Stage Buttons**: Ten individual buttons represent each main question/stage. Users click these buttons to activate and work on specific stages.
105
+ - **Exclusive Focus**: Upon activation of a stage button (e.g., 'Idea Name'), the LLM concentrates solely on tasks related to that stage.
106
+ - **Sequential Processing**: Users can navigate stages in any order, allowing flexibility in the workflow.
107
+
108
+ #### Dynamic Follow-ups
109
+
110
+ - **Conditional Questions**: Based on user responses within a stage, the chatbot may ask additional questions for further clarification.
111
+ - **LLM Analysis**: The LLM analyzes responses to determine if more information is needed.
112
+ - **Implementation**:
113
+ - Use conditional logic to assess the completeness of user inputs.
114
+ - Trigger follow-up prompts when necessary to ensure comprehensive data collection.
115
+
116
+ #### Context Preservation
117
+
118
+ - **Conversation History**: Maintain a log of all interactions to provide context for each stage.
119
+ - **LLM Access**: Pass relevant conversation history to the LLM for consistent and informed responses.
120
+ - **Implementation**:
121
+ - Utilize a list or database to store message histories.
122
+ - Ensure that the LLM receives pertinent history relevant to the current stage without exceeding token limits.
123
+
124
+ ### Data Collection and Refinement Module
125
+
126
+ #### Input Parsing
127
+
128
+ - **Structured Data Extraction**: Parse LLM responses to extract relevant information specific to each stage.
129
+ - **Tags and Markers**: Use specific markers (e.g., `<form_data></form_data>`) to delineate structured data within responses.
130
+
131
+ #### Data Storage
132
+
133
+ - **Database Choice**: Utilize SQL or CSV files for robust data storage.
134
+ - **Dynamic Updates**: Allow real-time updates to the stored data as users complete or modify stages.
135
+ - **Implementation**:
136
+ - Define a data model using Pydantic or similar for validation.
137
+ - Implement functions to read and write data to the database seamlessly.
138
+
139
+ #### Data Refinement
140
+
141
+ - **LLM Rewriting**: The LLM refines user inputs for clarity, coherence, and conciseness within each stage.
142
+ - **Validation**: Ensure the refined data aligns with the expected format and requirements of the stage.
143
+ - **Implementation**:
144
+ - Employ the LLM to generate refined versions of user inputs.
145
+ - Update the database with the refined data upon user confirmation.
146
+
147
+ ### Stage Management Module
148
+
149
+ #### Stage Buttons Interface
150
+
151
+ - **Checklist of Stages**: Replace the traditional progress tracking bar with a checklist comprising individual stage buttons.
152
+ - **User Activation**: Users manually activate each stage by clicking the corresponding button, initiating focused processing by the LLM.
153
+ - **'Fill Out Form' Button**: After completing a stage, users press the 'Fill Out Form' button to populate the associated text field with refined data.
154
+ - **Implementation**:
155
+ - Design the UI to display ten stage buttons, each linked to a specific question.
156
+ - Ensure that each button triggers the LLM to handle only the tasks pertinent to that stage.
157
+
158
+ #### Function Modularity
159
+
160
+ - **Compartmentalization**: Each stage is implemented as a separate function or class method to ensure modularity.
161
+ - **Independent Modification**: Allows individual stages to be updated or modified without impacting others.
162
+ - **Implementation**:
163
+ - Define separate methods for each stage within the chatbot class.
164
+ - Utilize inheritance or composition for shared functionalities across stages.
165
+
166
+ ### Web Search Integration Module
167
+
168
+ #### LLM-Triggered Web Searches
169
+
170
+ - **Automatic Searches**: The LLM determines when external information is necessary and triggers web searches accordingly.
171
+ - **Search Execution**: Perform searches using APIs and integrate the results into the conversation context.
172
+ - **Implementation**:
173
+ - LLM outputs a special token or command when a web search is needed.
174
+ - Chatbot captures this command and performs the search using the designated API.
175
+
176
+ #### User-Triggered Web Searches
177
+
178
+ - **User Commands**: Users can initiate searches by typing '@' followed by their query.
179
+ - **Query Optimization**: The LLM rewrites user queries to enhance search effectiveness.
180
+ - **Implementation**:
181
+ - Detect messages starting with '@' to identify user-initiated searches.
182
+ - Pass the query through the LLM for optimization before performing the search.
183
+
184
+ ### Database Management Module
185
+
186
+ #### Data Storage Format
187
+
188
+ - **Structured Data**: Store data in well-defined tables or a structured SQLite database to ensure data integrity.
189
+ - **Fields**: Include all necessary fields corresponding to the ten main questions/stages.
190
+ - **Implementation**:
191
+ - Define a comprehensive schema for the SQL database.
192
+ - Use an Object-Relational Mapping (ORM) tool like SQLAlchemy for efficient database interactions.
193
+
194
+ #### Dynamic Editing
195
+
196
+ - **User Modifications**: Allow users to edit previous inputs through the UI, updating the corresponding text fields.
197
+ - **Real-Time Updates**: Reflect changes immediately in the database to maintain data consistency.
198
+ - **Implementation**:
199
+ - Provide editable text fields beneath each stage button.
200
+ - Implement functions to update the database upon user edits, ensuring that the refined data remains accurate and up-to-date.
201
+
202
+ ---
203
+
204
+ ## Implementation Details
205
+
206
+ ### Python and Gradio Usage
207
+
208
+ - **Framework**: Utilize Gradio for the UI, providing a web-based interface with stage buttons and corresponding text fields.
209
+ - **Libraries**:
210
+ - **LLM Interaction**: Use `huggingface_hub` for LLM API calls.
211
+ - **Data Models**: Use `pydantic` for data validation and modeling.
212
+ - **Web Search**: Use `duckduckgo_search` API for web searches.
213
+ - **Environment Variables**: Use `python-dotenv` for managing API keys and configuration.
214
+
215
+ ### Module and Function Organization
216
+
217
+ - **Main Modules**:
218
+ - `main.py`: Entry point of the application.
219
+ - `chatbot.py`: Contains the `InnovativeIdeaChatbot` class and related functions.
220
+ - `data_models.py`: Defines data models using Pydantic.
221
+ - `utils.py`: Utility functions for parsing, web search, etc.
222
+ - `config.py`: Configuration settings and constants.
223
+ - **Function Structure**:
224
+ - Each function should have clear input/output parameters.
225
+ - Include docstrings with type hints for clarity and maintainability.
226
+ - Ensure that each stage's function handles only its specific tasks to maintain modularity.
227
+
228
+ ### Error Handling and Validation
229
+
230
+ - **User Input Validation**: Check for empty, invalid, or malformed inputs before processing.
231
+ - **API Error Handling**: Catch exceptions from API calls and provide user-friendly error messages or prompts.
232
+ - **Data Validation**: Use Pydantic models to validate data before storage to ensure data integrity.
233
+ - **Implementation**:
234
+ - Utilize try-except blocks around critical sections, especially around API interactions.
235
+ - Provide default values or prompts to guide users in case of errors or invalid inputs.
236
+ - Implement validation checks before updating the database with refined data.
237
+
238
+ ### LLM Context and Memory Management
239
+
240
+ - **Conversation Length**: Manage the size of the conversation history to stay within LLM token limits, ensuring efficient processing.
241
+ - **Contextual Responses**: Ensure the LLM receives sufficient context relevant to the current stage without overwhelming it with unnecessary information.
242
+ - **Implementation**:
243
+ - Implement a sliding window mechanism to include only recent and relevant messages in the LLM prompt.
244
+ - Summarize older parts of the conversation if necessary to maintain context within token limits.
245
+ - Ensure that each stage's context is isolated to prevent cross-stage contamination.
246
+
247
+ ### User Interface Enhancements
248
+
249
+ - **Stage Buttons**: Design intuitive and clearly labeled buttons for each of the ten stages, allowing easy navigation.
250
+ - **Text Fields**: Place editable text fields beneath each stage button to display and allow modifications of the refined data.
251
+ - **'Fill Out Form' Button**: Include a dedicated button for users to populate the corresponding text field with the refined data after completing a stage.
252
+ - **Visual Indicators**: Implement visual cues (e.g., color changes, checkmarks) to indicate the completion status of each stage.
253
+ - **Responsive Design**: Ensure the UI is responsive and user-friendly across different devices and screen sizes.
254
+ - **Implementation**:
255
+ - Utilize Gradio's layout features to arrange buttons and text fields logically.
256
+ - Incorporate CSS styling within Gradio to enhance the visual appeal and usability of the interface.
257
+ - Ensure that the UI updates dynamically based on user interactions and stage completions.
258
+
259
+ ### API Key Management
260
+
261
+ - **Secure Input**: Allow users to input their Hugging Face API keys securely through the UI.
262
+ - **Environment Variables**: Store API keys using environment variables to prevent exposure and enhance security.
263
+ - **Implementation**:
264
+ - Provide a secure input field in the UI for users to enter their API keys.
265
+ - Utilize `python-dotenv` to manage and access API keys within the application without hardcoding them.
266
+ - Ensure that API keys are never exposed in logs or error messages.
267
+
268
+ ---
269
+
270
+ # Appendices
271
+
272
+ ## Appendix A: Data Model Definition
273
+
274
+ ### InnovativeIdeaForm (Pydantic BaseModel)
275
+
276
+ Defines the structure for storing refined user inputs.
277
+
278
+ ```python
279
+ from pydantic import BaseModel, Field
280
+ from typing import List, Optional
281
+
282
+ class InnovativeIdeaForm(BaseModel):
283
+ idea_name: Optional[str] = Field(None, description="Name of the innovative idea")
284
+ idea_overview: Optional[str] = Field(None, description="Simple overview of the idea")
285
+ problem_solution: Optional[str] = Field(None, description="Customer problem and how the idea addresses it")
286
+ target_customers: Optional[str] = Field(None, description="Potential customers and markets")
287
+ market_value: Optional[str] = Field(None, description="Estimated market value")
288
+ existing_solutions: Optional[str] = Field(None, description="Similar existing ideas or products")
289
+ unique_value: Optional[str] = Field(None, description="How the idea is better or different")
290
+ technical_challenges: Optional[str] = Field(None, description="Difficult technical problems")
291
+ legal_barriers: Optional[str] = Field(None, description="Possible legal issues")
292
+ data_dependencies: Optional[str] = Field(None, description="Required data types")
293
+ team_roles: Optional[List[str]] = Field(None, description="Required job roles")
294
+ timeline: Optional[str] = Field(None, description="Estimated time to build main components")
295
+ additional_info: Optional[str] = Field(None, description="Any additional information")
296
+ ```
297
+
298
+ ## Appendix B: Function Signatures
299
+
300
+ ### Chatbot Class Methods
301
+
302
+ ```python
303
+ from typing import List, Dict, Tuple, Optional, Union
304
+
305
+ class InnovativeIdeaChatbot:
306
+ def __init__(self):
307
+ """
308
+ Initializes the chatbot with necessary configurations and data storage.
309
+ """
310
+ pass
311
+
312
+ def get_initial_greeting(self) -> str:
313
+ """
314
+ Returns the initial greeting message to the user.
315
+ """
316
+ pass
317
+
318
+ def activate_stage(self, stage_name: str) -> Optional[str]:
319
+ """
320
+ Activates the specified stage and returns the prompt for that stage.
321
+
322
+ Args:
323
+ stage_name (str): The name of the stage to activate.
324
+
325
+ Returns:
326
+ Optional[str]: The prompt message for the activated stage.
327
+ """
328
+ pass
329
+
330
+ def process_stage_input(self, stage_name: str, message: str) -> Tuple[str, Optional[str]]:
331
+ """
332
+ Processes the user's input for a specific stage and returns the refined data.
333
+
334
+ Args:
335
+ stage_name (str): The name of the current stage.
336
+ message (str): The user's input message.
337
+
338
+ Returns:
339
+ Tuple[str, Optional[str]]: A tuple containing the refined data and an optional follow-up prompt.
340
+ """
341
+ pass
342
+
343
+ def fill_out_form(self, stage_name: str) -> Optional[str]:
344
+ """
345
+ Populates the corresponding text field with refined data for the specified stage.
346
+
347
+ Args:
348
+ stage_name (str): The name of the stage to fill out.
349
+
350
+ Returns:
351
+ Optional[str]: The refined data to be displayed in the text field.
352
+ """
353
+ pass
354
+
355
+ def update_idea_form(self, stage_name: str, form_data: str):
356
+ """
357
+ Updates the idea form with the provided refined data for a specific stage.
358
+
359
+ Args:
360
+ stage_name (str): The name of the stage being updated.
361
+ form_data (str): The refined data to update in the form.
362
+ """
363
+ pass
364
+
365
+ def reset(self):
366
+ """
367
+ Resets the chatbot state for a new session, clearing all stored data and history.
368
+ """
369
+ pass
370
+ ```
371
+
372
+ ## Appendix C: Sample System Prompt Template
373
+
374
+ ```text
375
+ You are an AI assistant named Myamoto, designed to help users refine their innovative ideas. Your task is to guide them through the ideation process, stage by stage, asking relevant questions and providing insightful feedback at each stage. Be encouraging, creative, and analytical in your responses. Remember to:
376
+
377
+ 1. Analyze the user's input carefully and extract relevant information for the current stage.
378
+ 2. Provide constructive feedback and suggestions to improve the idea.
379
+ 3. Ask specific, targeted follow-up questions to gather more details if needed.
380
+ 4. Offer creative ideas or alternatives to enhance the user's concept.
381
+ 5. Maintain a supportive and enthusiastic tone throughout the conversation.
382
+ 6. When you feel the current stage has been thoroughly explored, explicitly state "stage complete" or "ready to move on" in your response.
383
+ 7. Break down your thinking process into steps, enclosed in <step></step> tags.
384
+ 8. Provide a reflection on your thought process, enclosed in <reflection></reflection> tags.
385
+ 9. For each stage, provide a refined, clear, and concise version of the user's input. This refined version should capture the essence of the user's idea while improving its clarity and coherence.
386
+ 10. If you think additional information from a web search might be helpful, suggest it to the user. Ask them to use '@' followed by their search query to perform a web search.
387
+ 11. Always include a <form_data></form_data> section in your response with the extracted information for the current stage.
388
+ 12. Be explicit when a stage is complete and indicate that you're ready to move to the next stage.
389
+
390
+ Please format your response as follows:
391
+ <answer>
392
+ [Your main response here, including follow-up questions and web search suggestions if applicable]
393
+ [If the stage is complete, include a clear statement like "This stage is now complete. We're ready to move on to the next stage."]
394
+ </answer>
395
+
396
+ <form_data>
397
+ [Extracted information for the current stage in a structured format]
398
+ </form_data>
399
+
400
+ <reflection>
401
+ [Your reflection on the thought process]
402
+ </reflection>
403
+
404
+ <step>[Step 1 of your thinking process]</step>
405
+ <step>[Step 2 of your thinking process]</step>
406
+ ...
407
+
408
+ Current stage: {{current_stage}}
409
+ ```
chatbot.py ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import List, Tuple, Dict, Any, Optional
2
+ from data_models import IdeaForm, IDEA_STAGES
3
+ from config import DEFAULT_SYSTEM_PROMPT, STAGES
4
+ from utils import (
5
+ get_llm_response, extract_form_data, save_idea_to_database,
6
+ load_idea_from_database, update_idea_in_database,
7
+ get_db, clear_database, init_db, create_tables,
8
+ perform_web_search, optimize_search_query,
9
+ SessionLocal, InnovativeIdea
10
+ )
11
+
12
+ class InnovativeIdeaChatbot:
13
+ def __init__(self):
14
+ create_tables()
15
+ init_db()
16
+ self.idea_form = IdeaForm()
17
+ self.chat_history = []
18
+ self.idea_id = None
19
+ self.db = SessionLocal()
20
+ self.current_stage = None
21
+ self.api_key = None
22
+ self.add_system_message(self.get_initial_greeting())
23
+
24
+ def __del__(self):
25
+ if hasattr(self, 'db'):
26
+ self.db.close()
27
+
28
+ def get_initial_greeting(self) -> str:
29
+ return "Welcome to the Innovative Idea Generator! Please select a stage to begin."
30
+
31
+ def add_system_message(self, message: str):
32
+ self.chat_history.append(("System", message))
33
+
34
+ def set_api_key(self, api_key: str):
35
+ self.api_key = api_key
36
+
37
+ def activate_stage(self, stage_name: str) -> Optional[str]:
38
+ self.current_stage = stage_name
39
+ for stage in STAGES:
40
+ if stage["name"] == stage_name:
41
+ return f"Let's work on the '{stage_name}' stage. {stage['question']}"
42
+ return None
43
+
44
+ def process_stage_input(self, stage_name: str, message: str, model: str, system_prompt: str, thinking_budget: int) -> Tuple[List[Tuple[str, str]], Dict[str, Any]]:
45
+ if self.current_stage != stage_name:
46
+ activation_message = self.activate_stage(stage_name)
47
+ if activation_message is None:
48
+ error_message = f"Error: Unable to activate stage '{stage_name}'. Please check if the stage name is correct."
49
+ self.chat_history.append(("System", error_message))
50
+ return self.chat_history, self.idea_form.dict()
51
+ self.chat_history.append(("System", activation_message))
52
+
53
+ # Check for web search request
54
+ if message.startswith('@'):
55
+ search_query = message[1:].strip()
56
+ optimized_query = optimize_search_query(search_query, model)
57
+ search_results = perform_web_search(optimized_query)
58
+ self.chat_history.append(("Human", message))
59
+ self.chat_history.append(("AI", f"Here are the search results for '{optimized_query}':\n\n{search_results}"))
60
+ return self.chat_history, self.idea_form.dict()
61
+
62
+ # Generate the prompt for the current stage
63
+ stage_prompt = self.generate_prompt_for_stage(stage_name)
64
+
65
+ # Combine the user's input with the stage prompt
66
+ combined_prompt = f"{stage_prompt}\n\nUser input: {message}"
67
+
68
+ # Get LLM response
69
+ llm_response = get_llm_response(combined_prompt, model, thinking_budget, self.api_key)
70
+
71
+ # Add the interaction to chat history
72
+ self.chat_history.append(("Human", message))
73
+ self.chat_history.append(("AI", llm_response))
74
+
75
+ # Extract form data from the LLM response
76
+ form_data = extract_form_data(llm_response)
77
+
78
+ # Update the idea form
79
+ if stage_name in form_data:
80
+ setattr(self.idea_form, stage_name.lower().replace(" ", "_"), form_data[stage_name])
81
+
82
+ return self.chat_history, self.idea_form.dict()
83
+
84
+ def fill_out_form(self, current_stage: str, model: str, thinking_budget: int) -> Dict[str, str]:
85
+ form_data = {}
86
+ for stage in STAGES:
87
+ stage_name = stage["name"]
88
+ if stage_name == current_stage:
89
+ # Generate new data for the current stage
90
+ form_data[stage_name] = self.generate_form_data(stage_name, model, thinking_budget)
91
+ else:
92
+ # Use existing data for other stages
93
+ form_data[stage_name] = getattr(self.idea_form, stage["field"], "")
94
+
95
+ # Update the idea form
96
+ for stage in STAGES:
97
+ setattr(self.idea_form, stage["field"], form_data[stage["name"]])
98
+
99
+ # Save to database
100
+ if self.idea_id:
101
+ update_idea_in_database(self.idea_id, self.idea_form, self.db)
102
+ else:
103
+ self.idea_id = save_idea_to_database(self.idea_form, self.db)
104
+
105
+ return form_data
106
+
107
+ def generate_prompt_for_stage(self, stage: str) -> str:
108
+ for s in STAGES:
109
+ if s["name"] == stage:
110
+ prompt_text = s.get('question') or s.get('description', '')
111
+ return f"We are currently working on the '{stage}' stage. {prompt_text}"
112
+ return f"We are currently working on the '{stage}' stage. Please provide relevant information."
113
+
114
+ def reset(self):
115
+ self.chat_history = []
116
+ self.idea_form = IdeaForm()
117
+ self.idea_id = None
118
+ self.current_stage = None
119
+ self.add_system_message(self.get_initial_greeting())
120
+ clear_database(self.db)
121
+ return self.chat_history, self.idea_form.dict()
122
+
123
+ def update_idea_form(self, stage_name: str, form_data: str):
124
+ setattr(self.idea_form, stage_name.lower().replace(" ", "_"), form_data)
125
+ if self.idea_id:
126
+ update_idea_in_database(self.idea_id, self.idea_form, self.db)
127
+ else:
128
+ self.idea_id = save_idea_to_database(self.idea_form, self.db)
129
+
130
+ def generate_form_data(self, stage: str, model: str, thinking_budget: int) -> str:
131
+ # Prepare the conversation history for the LLM
132
+ conversation = "\n".join([f"{role}: {message}" for role, message in self.chat_history])
133
+
134
+ prompt = f"""
135
+ Based on the following conversation, extract the relevant information for the '{stage}' stage of the innovative idea:
136
+
137
+ {conversation}
138
+
139
+ Please provide a concise summary for the '{stage}' stage, focusing only on the information relevant to this stage.
140
+ """
141
+
142
+ # Get LLM response
143
+ llm_response = get_llm_response(prompt, model, thinking_budget, self.api_key)
144
+
145
+ # Extract form data from the LLM response
146
+ form_data = extract_form_data(llm_response)
147
+
148
+ return form_data.get(stage, "")
149
+
150
+ def start_over(self):
151
+ self.reset()
152
+ clear_database(self.db)
153
+ self.idea_id = None
154
+
155
+ # Reinitialize with a new empty idea
156
+ new_idea = InnovativeIdea()
157
+ self.db.add(new_idea)
158
+ self.db.commit()
159
+ self.idea_id = new_idea.id
160
+
161
+ self.idea_form = IdeaForm()
162
+ self.chat_history = []
163
+ self.add_system_message(self.get_initial_greeting())
164
+
165
+ return self.chat_history, self.idea_form.dict()
config.py ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from dotenv import load_dotenv
3
+
4
+ load_dotenv()
5
+
6
+ API_TOKEN = os.getenv("HUGGINGFACE_API_TOKEN")
7
+
8
+ MODELS = [
9
+ "NousResearch/Nous-Hermes-2-Mixtral-8x7B-DPO",
10
+ # Add other models here if needed
11
+ ]
12
+
13
+ STAGES = [
14
+ {"name": "Idea Name", "field": "idea_name", "question": "Do you have a name for this idea?", "example": "Sharks with Laserbeams"},
15
+ {"name": "Idea Overview", "field": "idea_overview", "question": "Tell me about your idea, give a very simple overview as you might explain to younger child.", "example": "My idea is to attach laserbeams to sharks to create the ultimate evil weapon. The laserbeams are powered by a battery that are recharged by the shark's swimming motion. The laserbeams are used to attack enemy submarines."},
16
+ {"name": "Problem Solution", "field": "problem_solution", "question": "Tell me what Customer problem your idea addresses, and how does your idea address it?", "example": "Our customers' secret lairs are often attacked by submarines. If our clients had sharks with laserbeams they could attack and destroy the submarines, saving the secret lair from being discovered."},
17
+ {"name": "Target Customers", "field": "target_customers", "question": "What customers might be interested in this idea? Or is this a internal cost-savings / efficiency idea?", "example": "Evil geniuses, tyrannical dictators, rogue government agencies"},
18
+ {"name": "Market Value", "field": "market_value", "question": "What markets or industries is this idea for?", "example": "Defense Contractors, submarine manufacturers"},
19
+ {"name": "Existing Solutions", "field": "existing_solutions", "question": "What are some similar ideas or products that already exist today?", "example": "Nuclear Attack submarines and giant squids are somewhat similar to Shark with Laserbeams."},
20
+ {"name": "Unique Value", "field": "unique_value", "question": "How is your idea better or different?", "example": "Shark with Laserbeams are cheaper than Nuclear Attack submarines and the lasers are more powerful than squid tentacles."},
21
+ {"name": "Technical Challenges", "field": "technical_challenges", "question": "Are there any difficult technical problems with making this idea happen?", "example": "We would need to design a waterproof housing for the laser and batteries. We might need to experiment with how powerful lasers need to be when underwater in order to melt submarine steel hulls. We need to explore how to capture sharks and install the waterproof harnesses for the lasers."},
22
+ {"name": "Legal Barriers", "field": "legal_barriers", "question": "Any legal barriers?", "example": "We will need to obtain a weapons export license if we want to sell outside the United States."},
23
+ {"name": "Data Dependencies", "field": "data_dependencies", "question": "Any data dependencies?", "example": "We might need to get data on underwater motion vectors for creating the aiming mechanism for the lasers."},
24
+ {"name": "Team Roles", "field": "team_roles", "question": "What kind of people / job roles do you need to make this idea happen?", "example": "We will need marine biologists and fishermen for obtaining sharks. We will need electrical engineers, optical engineers and software engineers to create the laserbeam weapon. We will need project manager to help manage the budget and schedule. And we need a QA tester to ensure the laser is working underwater."},
25
+ {"name": "Timeline", "field": "timeline", "question": "About how long will it take to build the main components of your idea?", "example": "It will take a 2-3weeks to capture a shark. It will take 2-3 weeks to modify the harness and calibrate the laserbeam. I estimate it will take 3 months to train the shark to attack submarines."},
26
+ {"name": "Additional Info", "field": "additional_info", "question": "Anything else you'd want to add to help us understand and value your idea?", "example": "We might consider adding optional racing stripes or bioluminescent patterns ot the sharks as an upgrade with charge the customer for. We could explore a subscription model where we send the customers a new shark each quarter to replace sharks that age out of the program."}
27
+ ]
28
+
29
+ DEFAULT_SYSTEM_PROMPT = """
30
+ You are Myamoto, an AI assistant designed to guide users through the innovative idea development process. Your task is to help refine and expand their ideas, focusing strictly on one stage at a time. Be encouraging, creative, and analytical in your responses. Remember to:
31
+
32
+ 1. Analyze the user's input carefully and extract relevant information for the current stage only.
33
+ 2. Provide constructive feedback and suggestions to improve the idea, specific to the current stage.
34
+ 3. If the user's response is insufficient, ask follow-up questions to gather more details.
35
+ 4. Do not move to the next stage automatically. The user must explicitly indicate when they want to move on.
36
+ 5. Maintain a supportive and enthusiastic tone throughout the conversation.
37
+ 6. Always include a <form_data></form_data> section in your response with the extracted information for the current stage.
38
+ 7. If the user tries to skip ahead or provide information for future stages, gently redirect them to the current stage.
39
+ 8. Use analogies, examples, or thought-provoking questions to help users think more deeply about their ideas.
40
+ 9. When you feel the current stage has been thoroughly explored, explicitly state "stage complete" or "ready to move on" in your response.
41
+ 10. Break down your thinking process into steps, enclosed in <step></step> tags.
42
+ 11. Provide a reflection on your thought process, enclosed in <reflection></reflection> tags.
43
+ 12. If you think additional information from a web search might be helpful, suggest it to the user. Ask them to use '@' followed by their search query to perform a web search.
44
+
45
+ Current stage: {current_stage}
46
+ Stage prompt: {stage_prompt}
47
+ """
48
+
49
+ # Other configuration variables can be added here
data_models.py ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pydantic import BaseModel, Field
2
+ from typing import List, Optional
3
+ from sqlalchemy import Column, Integer, String, Text
4
+ from sqlalchemy.ext.declarative import declarative_base
5
+
6
+ Base = declarative_base()
7
+
8
+ class IdeaStage(BaseModel):
9
+ name: str
10
+ field: str
11
+ question: str
12
+ example: str
13
+
14
+ class IdeaForm(BaseModel):
15
+ idea_name: Optional[str] = Field(None, description="Name of the innovative idea")
16
+ idea_overview: Optional[str] = Field(None, description="Simple overview of the idea")
17
+ problem_solution: Optional[str] = Field(None, description="Customer problem and how the idea addresses it")
18
+ target_customers: Optional[str] = Field(None, description="Potential customers and markets")
19
+ market_value: Optional[str] = Field(None, description="Estimated market value")
20
+ existing_solutions: Optional[str] = Field(None, description="Similar existing ideas or products")
21
+ unique_value: Optional[str] = Field(None, description="How the idea is better or different")
22
+ technical_challenges: Optional[str] = Field(None, description="Difficult technical problems")
23
+ legal_barriers: Optional[str] = Field(None, description="Possible legal issues")
24
+ data_dependencies: Optional[str] = Field(None, description="Required data types")
25
+ team_roles: Optional[List[str]] = Field(None, description="Required job roles")
26
+ timeline: Optional[str] = Field(None, description="Estimated time to build main components")
27
+ additional_info: Optional[str] = Field(None, description="Any additional information")
28
+
29
+ class InnovativeIdea(Base):
30
+ __tablename__ = 'innovative_ideas'
31
+
32
+ id = Column(Integer, primary_key=True, index=True)
33
+ idea_name = Column(String, index=True)
34
+ idea_overview = Column(Text)
35
+ problem_solution = Column(Text)
36
+ target_customers = Column(Text)
37
+ market_value = Column(String)
38
+ existing_solutions = Column(Text)
39
+ unique_value = Column(Text)
40
+ technical_challenges = Column(Text)
41
+ legal_barriers = Column(Text)
42
+ data_dependencies = Column(Text)
43
+ team_roles = Column(Text)
44
+ timeline = Column(Text)
45
+ additional_info = Column(Text)
46
+
47
+ IDEA_STAGES = [
48
+ IdeaStage(name="Idea Name", field="idea_name", question="Do you have a name for this idea?", example="Sharks with Laserbeams"),
49
+ IdeaStage(name="Idea Overview", field="idea_overview", question="Tell me about your idea, give a very simple overview as you might explain to younger child.", example="My idea is to attach laserbeams to sharks to create the ultimate evil weapon. The laserbeams are powered by a battery that are recharged by the shark's swimming motion. The laserbeams are used to attack enemy submarines."),
50
+ IdeaStage(name="Problem Solution", field="problem_solution", question="Tell me what Customer problem your idea addresses, and how does your idea address it?", example="Our customers' secret lairs are often attacked by submarines. If our clients had sharks with laserbeams they could attack and destroy the submarines, saving the secret lair from being discovered."),
51
+ IdeaStage(name="Target Customers", field="target_customers", question="What customers might be interested in this idea? Or is this a internal cost-savings / efficiency idea?", example="Evil geniuses, tyrannical dictators, rogue government agencies"),
52
+ IdeaStage(name="Market Value", field="market_value", question="What markets or industries is this idea for?", example="Defense Contractors, submarine manufacturers"),
53
+ IdeaStage(name="Existing Solutions", field="existing_solutions", question="What are some similar ideas or products that already exist today?", example="Nuclear Attack submarines and giant squids are somewhat similar to Shark with Laserbeams."),
54
+ IdeaStage(name="Unique Value", field="unique_value", question="How is your idea better or different?", example="Shark with Laserbeams are cheaper than Nuclear Attack submarines and the lasers are more powerful than squid tentacles."),
55
+ IdeaStage(name="Technical Challenges", field="technical_challenges", question="Are there any difficult technical problems with making this idea happen?", example="We would need to design a waterproof housing for the laser and batteries. We might need to experiment with how powerful lasers need to be when underwater in order to melt submarine steel hulls. We need to explore how to capture sharks and install the waterproof harnesses for the lasers."),
56
+ IdeaStage(name="Legal Barriers", field="legal_barriers", question="Any legal barriers?", example="We will need to obtain a weapons export license if we want to sell outside the United States."),
57
+ IdeaStage(name="Data Dependencies", field="data_dependencies", question="Any data dependencies?", example="We might need to get data on underwater motion vectors for creating the aiming mechanism for the lasers."),
58
+ IdeaStage(name="Team Roles", field="team_roles", question="What kind of people / job roles do you need to make this idea happen?", example="We will need marine biologists and fishermen for obtaining sharks. We will need electrical engineers, optical engineers and software engineers to create the laserbeam weapon. We will need project manager to help manage the budget and schedule. And we need a QA tester to ensure the laser is working underwater."),
59
+ IdeaStage(name="Timeline", field="timeline", question="About how long will it take to build the main components of your idea?", example="It will take a 2-3weeks to capture a shark. It will take 2-3 weeks to modify the harness and calibrate the laserbeam. I estimate it will take 3 months to train the shark to attack submarines."),
60
+ IdeaStage(name="Additional Info", field="additional_info", question="Anything else you'd want to add to help us understand and value your idea?", example="We might consider adding optional racing stripes or bioluminescent patterns ot the sharks as an upgrade with charge the customer for. We could explore a subscription model where we send the customers a new shark each quarter to replace sharks that age out of the program.")
61
+ ]
main.py ADDED
@@ -0,0 +1,194 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from utils import SessionLocal, InnovativeIdea, ensure_database_exists, verify_database, initialize_database
3
+ from data_models import IdeaForm
4
+ from chatbot import InnovativeIdeaChatbot
5
+ from config import MODELS, DEFAULT_SYSTEM_PROMPT, STAGES
6
+ import logging
7
+ from typing import Dict, Any
8
+
9
+ # Set up logging
10
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
11
+
12
+ def create_gradio_interface():
13
+ innovative_chatbot = InnovativeIdeaChatbot()
14
+ default_stage = STAGES[0]["name"]
15
+
16
+ # Load initial data from the database
17
+ db = SessionLocal()
18
+ initial_idea = db.query(InnovativeIdea).first()
19
+ db.close()
20
+
21
+ if initial_idea is None:
22
+ logging.warning("No initial idea found in the database. Creating a new one.")
23
+ initial_idea = InnovativeIdea()
24
+
25
+ def chatbot_function(message, history, model, system_prompt, thinking_budget, current_stage):
26
+ try:
27
+ chat_history, form_data = innovative_chatbot.process_stage_input(current_stage, message, model, system_prompt, thinking_budget)
28
+
29
+ history.append((message, chat_history[-1][1]))
30
+
31
+ # Update the database with the new form data
32
+ db = SessionLocal()
33
+ idea = db.query(InnovativeIdea).first()
34
+ for key, value in form_data.items():
35
+ setattr(idea, key, value)
36
+ db.commit()
37
+ db.close()
38
+
39
+ return history, form_data.get(current_stage, ""), "" # Return an empty string to clear the input
40
+ except Exception as e:
41
+ logging.error(f"An error occurred in chatbot_function: {str(e)}", exc_info=True)
42
+ return history + [(None, f"An error occurred: {str(e)}")], "", "" # Return an empty string to clear the input
43
+
44
+ def fill_form(stage, model, thinking_budget):
45
+ form_data = innovative_chatbot.fill_out_form(stage, model, thinking_budget)
46
+ return form_data
47
+
48
+ def clear_chat():
49
+ # Reset the database to an empty form
50
+ db = SessionLocal()
51
+ idea = db.query(InnovativeIdea).first()
52
+ empty_form = IdeaForm()
53
+ for key, value in empty_form.dict().items():
54
+ setattr(idea, key, value)
55
+ db.commit()
56
+ db.close()
57
+
58
+ return innovative_chatbot.reset()
59
+
60
+ def update_form_field(stage_name: str, value: str) -> str:
61
+ db = SessionLocal()
62
+ idea = db.query(InnovativeIdea).first()
63
+ field_name = next(stage["field"] for stage in STAGES if stage["name"] == stage_name)
64
+ setattr(idea, field_name, value)
65
+ db.commit()
66
+ db.close()
67
+ return value
68
+
69
+ def update_placeholders(form_data: Dict[str, str]) -> Dict[str, Any]:
70
+ return {
71
+ stage["name"]: gr.update(value=form_data.get(stage["name"], ""), placeholder=form_data.get(stage["name"], stage["example"]))
72
+ for stage in STAGES
73
+ }
74
+
75
+ def start_over():
76
+ chat_history, form_data = innovative_chatbot.start_over()
77
+ return (
78
+ [], # Clear the chatbot
79
+ "", # Clear the message input
80
+ *[form_data.get(stage["field"], "") for stage in STAGES], # Reset all form fields
81
+ gr.update(value=default_stage) # Reset the stage selection
82
+ )
83
+
84
+ with gr.Blocks(theme=gr.themes.Soft()) as demo:
85
+ gr.Markdown("# Innovative Idea Generator")
86
+
87
+ mode = gr.Radio(["Chatbot", "Direct Input"], label="Mode", value="Chatbot")
88
+
89
+ with gr.Row():
90
+ with gr.Column(scale=2):
91
+ chatbot = gr.Chatbot(label="Conversation", height=500)
92
+ msg = gr.Textbox(label="Your input", placeholder="Type your brilliant idea here...")
93
+
94
+ with gr.Row():
95
+ submit = gr.Button("Submit")
96
+ clear = gr.Button("Clear Chat")
97
+ start_over_btn = gr.Button("Start Over")
98
+
99
+ with gr.Column(scale=1):
100
+ stages = gr.Radio(
101
+ choices=[stage["name"] for stage in STAGES],
102
+ label="Ideation Stages",
103
+ value=default_stage
104
+ )
105
+ form_fields = {
106
+ stage["name"]: gr.Textbox(
107
+ label=stage["question"],
108
+ placeholder=stage["example"],
109
+ value=getattr(initial_idea, stage["field"], ""),
110
+ visible=(stage["name"] == default_stage),
111
+ interactive=False
112
+ ) for stage in STAGES
113
+ }
114
+ fill_form_btn = gr.Button("Fill out Form")
115
+ submit_form_btn = gr.Button("Submit Form", visible=False)
116
+
117
+ with gr.Accordion("Advanced Settings", open=False):
118
+ model = gr.Dropdown(choices=MODELS, label="Select Model", value=MODELS[0])
119
+ system_prompt = gr.Textbox(label="System Prompt", value=DEFAULT_SYSTEM_PROMPT, lines=5)
120
+ thinking_budget = gr.Slider(minimum=1, maximum=4098, value=2048, step=1, label="Max New Tokens")
121
+ api_key = gr.Textbox(label="Hugging Face API Key", type="password")
122
+
123
+ # Event handlers
124
+ msg.submit(chatbot_function,
125
+ inputs=[msg, chatbot, model, system_prompt, thinking_budget, stages],
126
+ outputs=[chatbot, form_fields[default_stage], msg])
127
+
128
+ submit.click(chatbot_function,
129
+ inputs=[msg, chatbot, model, system_prompt, thinking_budget, stages],
130
+ outputs=[chatbot, form_fields[default_stage], msg])
131
+
132
+ def fill_and_update_form(stage, model, thinking_budget):
133
+ form_data = fill_form(stage, model, thinking_budget)
134
+ updated_fields = {}
135
+ for stage_name, value in form_data.items():
136
+ updated_value = update_form_field(stage_name, value)
137
+ updated_fields[stage_name] = updated_value
138
+ return update_placeholders(updated_fields)
139
+
140
+ fill_form_btn.click(fill_and_update_form,
141
+ inputs=[stages, model, thinking_budget],
142
+ outputs=list(form_fields.values()))
143
+
144
+ clear.click(clear_chat,
145
+ outputs=[chatbot] + list(form_fields.values()))
146
+
147
+ # Update form field visibility based on selected stage
148
+ stages.change(
149
+ lambda s: [gr.update(visible=(stage["name"] == s)) for stage in STAGES],
150
+ inputs=[stages],
151
+ outputs=list(form_fields.values())
152
+ )
153
+
154
+ # Update API key when changed
155
+ api_key.change(innovative_chatbot.set_api_key, inputs=[api_key])
156
+
157
+ # Toggle between chatbot and direct input mode
158
+ def toggle_mode(new_mode):
159
+ if new_mode == "Direct Input":
160
+ return [gr.update(visible=False)] * 3 + [gr.update(interactive=True)] * len(STAGES) + [gr.update(visible=True)]
161
+ else:
162
+ return [gr.update(visible=True)] * 3 + [gr.update(interactive=False)] * len(STAGES) + [gr.update(visible=False)]
163
+
164
+ mode.change(
165
+ toggle_mode,
166
+ inputs=[mode],
167
+ outputs=[chatbot, msg, submit] + list(form_fields.values()) + [submit_form_btn]
168
+ )
169
+
170
+ # Handle direct form submission
171
+ submit_form_btn.click(
172
+ lambda *values: values,
173
+ inputs=[form_fields[stage["name"]] for stage in STAGES],
174
+ outputs=[form_fields[stage["name"]] for stage in STAGES]
175
+ )
176
+
177
+ # Add this new event handler for the Start Over button
178
+ start_over_btn.click(
179
+ start_over,
180
+ outputs=[chatbot, msg] + [form_fields[stage["name"]] for stage in STAGES] + [stages]
181
+ )
182
+
183
+ return demo
184
+
185
+ def main():
186
+ ensure_database_exists()
187
+ initialize_database()
188
+ verify_database()
189
+ demo = create_gradio_interface()
190
+ return demo
191
+
192
+ if __name__ == "__main__":
193
+ demo = main()
194
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ gradio
2
+ pydantic
3
+ huggingface_hub
4
+ duckduckgo_search
5
+ python-dotenv
6
+ sqlalchemy
utils.py ADDED
@@ -0,0 +1,456 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import re
2
+ from typing import Dict, List, Optional, Any
3
+ from pydantic import ValidationError
4
+ from data_models import IdeaForm, IDEA_STAGES, InnovativeIdea, Base
5
+ from config import API_TOKEN, STAGES
6
+ from huggingface_hub import InferenceClient
7
+ from duckduckgo_search import DDGS
8
+ from sqlalchemy import create_engine, delete, inspect
9
+ from sqlalchemy.orm import sessionmaker, Session, declarative_base
10
+ import sys
11
+ import sqlite3
12
+ from sqlalchemy.exc import OperationalError, PendingRollbackError
13
+ import logging
14
+ import os
15
+
16
+ # Database configuration
17
+ DATABASE_URL = "sqlite:///./innovative_ideas.db"
18
+ engine = create_engine(DATABASE_URL)
19
+ SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
20
+ Base = declarative_base()
21
+
22
+ def get_llm_response(context: str, model: str, max_tokens: int, api_key: Optional[str] = None) -> str:
23
+ client = InferenceClient(model=model, token=api_key or API_TOKEN)
24
+
25
+ messages = [
26
+ {"role": "system", "content": "You are a helpful AI assistant."},
27
+ {"role": "user", "content": context}
28
+ ]
29
+
30
+ full_response = ""
31
+ for message in client.chat_completion(
32
+ messages=messages,
33
+ max_tokens=max_tokens,
34
+ temperature=0.7,
35
+ top_p=0.95,
36
+ stream=True,
37
+ ):
38
+ content = message.choices[0].delta.content
39
+ if content:
40
+ full_response += content
41
+ print(content, end="", flush=True)
42
+
43
+ print() # New line after the full response
44
+ return full_response
45
+
46
+ def extract_form_data(llm_response: str) -> Dict[str, Any]:
47
+ form_data = {}
48
+
49
+ # Define patterns for each field
50
+ patterns = {stage["field"]: rf'{stage["name"]}:?\s*(.*?)(?:\n\n|\Z)' for stage in STAGES}
51
+
52
+ # Extract data for each field
53
+ for field, pattern in patterns.items():
54
+ match = re.search(pattern, llm_response, re.DOTALL | re.IGNORECASE)
55
+ if match:
56
+ form_data[field] = match.group(1).strip()
57
+
58
+ # Special handling for team_roles (convert to list)
59
+ if 'team_roles' in form_data:
60
+ form_data['team_roles'] = [role.strip() for role in form_data['team_roles'].split(',')]
61
+
62
+ return form_data
63
+
64
+ def perform_web_search(query: str, max_results: int = 3) -> str:
65
+ with DDGS() as ddgs:
66
+ results = list(ddgs.text(query, max_results=max_results))
67
+
68
+ formatted_results = ""
69
+ for i, result in enumerate(results, 1):
70
+ formatted_results += f"{i}. {result['title']}\n {result['body']}\n URL: {result['href']}\n\n"
71
+
72
+ return formatted_results
73
+
74
+ def optimize_search_query(query: str, model: str) -> str:
75
+ client = InferenceClient(model=model, token=API_TOKEN)
76
+ prompt = f"Optimize the following search query to get better web search results:\n\n{query}\n\nOptimized query:"
77
+
78
+ response = client.text_generation(prompt, max_new_tokens=50, temperature=0.7)
79
+ return response.strip()
80
+
81
+ def refine_user_input(user_input: str, current_stage: str, model: str) -> str:
82
+ client = InferenceClient(model=model, token=API_TOKEN)
83
+ prompt = f"""
84
+ Refine and clarify the following user input for the '{current_stage}' stage of an innovative idea:
85
+
86
+ {user_input}
87
+
88
+ Please provide a clear, concise, and well-structured version of this input.
89
+ Ensure that the refined input is specific to the current stage and does not include information for other stages.
90
+ """
91
+ messages = [
92
+ {"role": "system", "content": "You are a helpful AI assistant specializing in refining innovative ideas."},
93
+ {"role": "user", "content": prompt}
94
+ ]
95
+
96
+ full_response = ""
97
+ for message in client.chat_completion(
98
+ messages=messages,
99
+ max_tokens=200,
100
+ temperature=0.7,
101
+ stream=True,
102
+ ):
103
+ content = message.choices[0].delta.content
104
+ if content:
105
+ full_response += content
106
+
107
+ return full_response.strip()
108
+
109
+ def update_idea_form(form: IdeaForm, new_data: Dict) -> Optional[IdeaForm]:
110
+ """
111
+ Updates the IdeaForm with new data and validates it.
112
+ """
113
+ try:
114
+ updated_data = form.dict()
115
+ updated_data.update(new_data)
116
+ return IdeaForm(**updated_data)
117
+ except ValidationError as e:
118
+ print(f"Validation error: {e}")
119
+ return None
120
+
121
+ def update_checklist(idea_form: IdeaForm) -> str:
122
+ """
123
+ Generates a checklist based on the current state of the idea form.
124
+ """
125
+ checklist = []
126
+ for field, value in idea_form.dict().items():
127
+ if not value:
128
+ checklist.append(f"[ ] Complete the '{field.replace('_', ' ').title()}' section")
129
+ elif isinstance(value, str) and len(value) < 50:
130
+ checklist.append(f"[?] Consider expanding the '{field.replace('_', ' ').title()}' section")
131
+ else:
132
+ checklist.append(f"[x] '{field.replace('_', ' ').title()}' section completed")
133
+
134
+ return "\n".join(checklist)
135
+
136
+ def generate_follow_up_questions(idea_form: IdeaForm, current_stage: int) -> List[str]:
137
+ """
138
+ Generates follow-up questions based on the current stage and form state.
139
+ """
140
+ questions = []
141
+ current_stage_name = IDEA_STAGES[current_stage]
142
+ form_dict = idea_form.dict()
143
+
144
+ if current_stage_name == "Idea Name":
145
+ if not form_dict['idea_name']:
146
+ questions.append("What would be a catchy and memorable name for your idea?")
147
+ elif len(form_dict['idea_name']) > 50:
148
+ questions.append("Can you shorten your idea name to make it more concise?")
149
+
150
+ elif current_stage_name == "Idea Overview":
151
+ if not form_dict['idea_overview']:
152
+ questions.append("Can you provide a brief overview of your idea in simple terms?")
153
+ elif len(form_dict['idea_overview']) < 100:
154
+ questions.append("Can you elaborate more on how your idea works?")
155
+
156
+ elif current_stage_name == "Problem Solution":
157
+ if not form_dict['problem_solution']:
158
+ questions.append("What specific problem does your idea solve?")
159
+ if 'how' not in form_dict['problem_solution'].lower():
160
+ questions.append("How exactly does your idea solve the problem you've identified?")
161
+
162
+ elif current_stage_name == "Target Customers":
163
+ if not form_dict['target_customers']:
164
+ questions.append("Who are the main users or customers for your idea?")
165
+ elif len(form_dict['target_customers']) < 50:
166
+ questions.append("Can you be more specific about your target customers? Consider demographics, industries, or use cases.")
167
+
168
+ elif current_stage_name == "Market Value":
169
+ if not form_dict['market_value']:
170
+ questions.append("What industries or markets could benefit from your idea?")
171
+ if 'size' not in form_dict['market_value'].lower():
172
+ questions.append("Can you estimate the size of the market for your idea?")
173
+
174
+ elif current_stage_name == "Existing Solutions":
175
+ if not form_dict['existing_solutions']:
176
+ questions.append("Are there any existing products or services similar to your idea?")
177
+ elif 'different' not in form_dict['existing_solutions'].lower():
178
+ questions.append("How is your idea different from these existing solutions?")
179
+
180
+ elif current_stage_name == "Unique Value":
181
+ if not form_dict['unique_value']:
182
+ questions.append("What makes your idea unique or better than existing solutions?")
183
+ if 'why' not in form_dict['unique_value'].lower():
184
+ questions.append("Why would customers choose your solution over alternatives?")
185
+
186
+ elif current_stage_name == "Technical Challenges":
187
+ if not form_dict['technical_challenges']:
188
+ questions.append("What are the main technical challenges in developing your idea?")
189
+ if 'overcome' not in form_dict['technical_challenges'].lower():
190
+ questions.append("How might these technical challenges be overcome?")
191
+
192
+ elif current_stage_name == "Legal Barriers":
193
+ if not form_dict['legal_barriers']:
194
+ questions.append("Are there any legal or regulatory issues that could affect your idea?")
195
+ if 'address' not in form_dict['legal_barriers'].lower():
196
+ questions.append("How might you address these legal or regulatory issues?")
197
+
198
+ elif current_stage_name == "Data Dependencies":
199
+ if not form_dict['data_dependencies']:
200
+ questions.append("Does your idea rely on any specific data sources?")
201
+ if 'acquire' not in form_dict['data_dependencies'].lower():
202
+ questions.append("How will you acquire or generate the necessary data for your idea?")
203
+
204
+ elif current_stage_name == "Team Roles":
205
+ if not form_dict['team_roles']:
206
+ questions.append("What key roles or expertise are needed to develop and implement your idea?")
207
+ elif len(form_dict['team_roles']) < 3:
208
+ questions.append("Are there any additional roles or skills that would be beneficial for your team?")
209
+
210
+ elif current_stage_name == "Timeline":
211
+ if not form_dict['timeline']:
212
+ questions.append("Can you provide a rough timeline for developing your idea?")
213
+ if 'milestone' not in form_dict['timeline'].lower():
214
+ questions.append("What are the main milestones in your development timeline?")
215
+
216
+ elif current_stage_name == "Additional Info":
217
+ if not form_dict['additional_info']:
218
+ questions.append("Is there any additional information that's important for understanding or implementing your idea?")
219
+ elif len(form_dict['additional_info']) < 100:
220
+ questions.append("Are there any other aspects of your idea that you'd like to elaborate on?")
221
+
222
+ return questions
223
+
224
+ def save_idea_to_database(form: IdeaForm, db: Session) -> int:
225
+ """
226
+ Saves the IdeaForm to the SQLite database.
227
+ Returns the ID of the inserted row.
228
+ """
229
+ db_idea = InnovativeIdea(
230
+ idea_name=form.idea_name,
231
+ idea_overview=form.idea_overview,
232
+ problem_solution=form.problem_solution,
233
+ target_customers=form.target_customers,
234
+ market_value=form.market_value,
235
+ existing_solutions=form.existing_solutions,
236
+ unique_value=form.unique_value,
237
+ technical_challenges=form.technical_challenges,
238
+ legal_barriers=form.legal_barriers,
239
+ data_dependencies=form.data_dependencies,
240
+ team_roles=','.join(form.team_roles) if form.team_roles else None,
241
+ timeline=form.timeline,
242
+ additional_info=form.additional_info
243
+ )
244
+ db.add(db_idea)
245
+ db.commit()
246
+ db.refresh(db_idea)
247
+ return db_idea.id
248
+
249
+ def load_idea_from_database(idea_id: int, db: Session) -> Optional[IdeaForm]:
250
+ """
251
+ Loads an IdeaForm from the SQLite database by ID.
252
+ """
253
+ db_idea = db.query(InnovativeIdea).filter(InnovativeIdea.id == idea_id).first()
254
+ if db_idea:
255
+ return IdeaForm(
256
+ idea_name=db_idea.idea_name,
257
+ idea_overview=db_idea.idea_overview,
258
+ problem_solution=db_idea.problem_solution,
259
+ target_customers=db_idea.target_customers,
260
+ market_value=db_idea.market_value,
261
+ existing_solutions=db_idea.existing_solutions,
262
+ unique_value=db_idea.unique_value,
263
+ technical_challenges=db_idea.technical_challenges,
264
+ legal_barriers=db_idea.legal_barriers,
265
+ data_dependencies=db_idea.data_dependencies,
266
+ team_roles=db_idea.team_roles.split(',') if db_idea.team_roles else None,
267
+ timeline=db_idea.timeline,
268
+ additional_info=db_idea.additional_info
269
+ )
270
+ return None
271
+
272
+ def update_idea_in_database(idea_id: int, form: IdeaForm, db: Session) -> bool:
273
+ """
274
+ Updates an existing idea in the database.
275
+ """
276
+ db_idea = db.query(InnovativeIdea).filter(InnovativeIdea.id == idea_id).first()
277
+ if db_idea:
278
+ for field, value in form.dict(exclude_unset=True).items():
279
+ setattr(db_idea, field, value)
280
+ db.commit()
281
+ return True
282
+ return False
283
+
284
+ def extract_search_query(message: str) -> Optional[str]:
285
+ """
286
+ Extract a search query from a user message if it starts with '@'.
287
+ """
288
+ if message.startswith('@'):
289
+ return message[1:].strip()
290
+ return None
291
+
292
+ def create_tables():
293
+ Base.metadata.create_all(bind=engine)
294
+
295
+ def get_db():
296
+ db = SessionLocal()
297
+ try:
298
+ yield db
299
+ finally:
300
+ db.close()
301
+
302
+ def verify_database():
303
+ try:
304
+ inspector = inspect(engine)
305
+ if not inspector.has_table("innovative_ideas"):
306
+ logging.error("InnovativeIdea table does not exist")
307
+ return False
308
+
309
+ columns = inspector.get_columns("innovative_ideas")
310
+ expected_columns = [field for field in IdeaForm.__fields__]
311
+ actual_columns = [column['name'] for column in columns if column['name'] != 'id']
312
+
313
+ if set(expected_columns) != set(actual_columns):
314
+ logging.error(f"Mismatch in table columns. Expected: {expected_columns}, Actual: {actual_columns}")
315
+ return False
316
+
317
+ # Check if there's at least one row in the table
318
+ db = SessionLocal()
319
+ idea_count = db.query(InnovativeIdea).count()
320
+ db.close()
321
+
322
+ if idea_count == 0:
323
+ logging.warning("No ideas found in the database")
324
+ # Instead of returning False, we'll create an initial idea
325
+ db = SessionLocal()
326
+ initial_idea = InnovativeIdea()
327
+ db.add(initial_idea)
328
+ db.commit()
329
+ db.close()
330
+ logging.info("Created initial idea in the database")
331
+
332
+ return True
333
+ except Exception as e:
334
+ logging.error(f"Database verification failed: {str(e)}", exc_info=True)
335
+ return False
336
+
337
+ def initialize_database():
338
+ try:
339
+ # Create tables
340
+ Base.metadata.create_all(bind=engine)
341
+ logging.info("Database tables created successfully.")
342
+
343
+ # Check if the table is empty
344
+ db = SessionLocal()
345
+ existing_idea = db.query(InnovativeIdea).first()
346
+
347
+ if existing_idea is None:
348
+ # Create an empty IdeaForm
349
+ empty_form = IdeaForm()
350
+
351
+ # Save the empty form to the database
352
+ db_idea = InnovativeIdea(**empty_form.dict())
353
+ db.add(db_idea)
354
+ db.commit()
355
+ db.refresh(db_idea)
356
+ logging.info("Empty idea form added to the database.")
357
+ else:
358
+ logging.info("Database already contains data.")
359
+
360
+ db.close()
361
+ return True
362
+ except Exception as e:
363
+ logging.error(f"Failed to initialize database: {str(e)}")
364
+ return False
365
+
366
+ def init_db():
367
+ Base.metadata.create_all(bind=engine)
368
+
369
+ def get_example_idea() -> Dict[str, str]:
370
+ """
371
+ Returns an example idea to guide users and the LLM.
372
+ """
373
+ return {
374
+ "idea_name": "Sharks with Laserbeams",
375
+ "idea_overview": "My idea is to attach laserbeams to sharks to create the ultimate evil weapon. The laserbeams are powered by a battery that are recharged by the shark's swimming motion. The laserbeams are used to attack enemy submarines.",
376
+ "problem_solution": "Our customers' secret lairs are often attacked by submarines. If our clients had sharks with laserbeams they could attack and destroy the submarines, saving the secret lair from being discovered.",
377
+ "target_customers": "Evil geniuses, tyrannical dictators, rogue government agencies",
378
+ "market_value": "Defense Contractors, submarine manufacturers",
379
+ "existing_solutions": "Nuclear Attack submarines and giant squids are somewhat similar to Shark with Laserbeams.",
380
+ "unique_value": "Shark with Laserbeams are cheaper than Nuclear Attack submarines and the lasers are more powerful than squid tentacles.",
381
+ "technical_challenges": "We would need to design a waterproof housing for the laser and batteries. We might need to experiment with how powerful lasers need to be when underwater in order to melt submarine steel hulls. We need to explore how to capture sharks and install the waterproof harnesses for the lasers.",
382
+ "legal_barriers": "We will need to obtain a weapons export license if we want to sell outside the United States.",
383
+ "data_dependencies": "We might need to get data on underwater motion vectors for creating the aiming mechanism for the lasers.",
384
+ "team_roles": "Marine biologists, fishermen, electrical engineers, optical engineers, software engineers, project manager, QA tester",
385
+ "timeline": "It will take 2-3 weeks to capture a shark. It will take 2-3 weeks to modify the harness and calibrate the laserbeam. I estimate it will take 3 months to train the shark to attack submarines.",
386
+ "additional_info": "We might consider adding optional racing stripes or bioluminescent patterns to the sharks as an upgrade with charge the customer for. We could explore a subscription model where we send the customers a new shark each quarter to replace sharks that age out of the program."
387
+ }
388
+
389
+ def generate_prompt_for_stage(stage: str, current_form: Dict[str, Any]) -> str:
390
+ """
391
+ Generates a prompt for the current stage, including the example idea.
392
+ """
393
+ example_idea = get_example_idea()
394
+ prompt = f"We are currently in the '{stage}' stage of developing an innovative idea. "
395
+ prompt += "Please provide information for this stage, keeping in mind the following example:\n\n"
396
+
397
+ if stage == "Idea Name":
398
+ prompt += f"Example: {example_idea['idea_name']}\n"
399
+ prompt += "What's the name of your innovative idea? Keep it short and catchy."
400
+ elif stage == "Idea Overview":
401
+ prompt += f"Example: {example_idea['idea_overview']}\n"
402
+ prompt += "Provide a simple overview of your idea, as if explaining it to a 10-year-old child. What does your idea do?"
403
+ elif stage == "Problem Solution":
404
+ prompt += f"Example: {example_idea['problem_solution']}\n"
405
+ prompt += "What specific problem does your idea solve? How does it solve this problem?"
406
+ elif stage == "Target Customers":
407
+ prompt += f"Example: {example_idea['target_customers']}\n"
408
+ prompt += "Who are the main customers or users for your idea? Be as specific as possible."
409
+ elif stage == "Market Value":
410
+ prompt += f"Example: {example_idea['market_value']}\n"
411
+ prompt += "What industries or markets could benefit from your idea? How large is this market?"
412
+ elif stage == "Existing Solutions":
413
+ prompt += f"Example: {example_idea['existing_solutions']}\n"
414
+ prompt += "Are there any existing products or services similar to your idea? How are they different?"
415
+ elif stage == "Unique Value":
416
+ prompt += f"Example: {example_idea['unique_value']}\n"
417
+ prompt += "What makes your idea unique or better than existing solutions? Why would customers choose your solution?"
418
+ elif stage == "Technical Challenges":
419
+ prompt += f"Example: {example_idea['technical_challenges']}\n"
420
+ prompt += "What are the main technical challenges in developing your idea? How might these be overcome?"
421
+ elif stage == "Legal Barriers":
422
+ prompt += f"Example: {example_idea['legal_barriers']}\n"
423
+ prompt += "Are there any legal or regulatory issues that could affect your idea? How might these be addressed?"
424
+ elif stage == "Data Dependencies":
425
+ prompt += f"Example: {example_idea['data_dependencies']}\n"
426
+ prompt += "Does your idea rely on any specific data sources? How will you acquire or generate this data?"
427
+ elif stage == "Team Roles":
428
+ prompt += f"Example: {example_idea['team_roles']}\n"
429
+ prompt += "What key roles or expertise are needed to develop and implement your idea? List specific job titles or skills."
430
+ elif stage == "Timeline":
431
+ prompt += f"Example: {example_idea['timeline']}\n"
432
+ prompt += "Provide a rough timeline for developing your idea. What are the main milestones and how long might each take?"
433
+ elif stage == "Additional Info":
434
+ prompt += f"Example: {example_idea['additional_info']}\n"
435
+ prompt += "Is there any additional information that's important for understanding or implementing your idea?"
436
+
437
+ prompt += "\n\nPlease provide your response for this stage, considering the example provided and the current state of your idea."
438
+ return prompt
439
+
440
+ def ensure_database_exists():
441
+ db_path = DATABASE_URL.replace("sqlite:///", "")
442
+ if not os.path.exists(db_path):
443
+ logging.info(f"Database file not found. Creating new database at {db_path}")
444
+ open(db_path, 'a').close() # Create an empty file
445
+ else:
446
+ logging.info(f"Database file found at {db_path}")
447
+
448
+ def clear_database(db: Session):
449
+ try:
450
+ # Delete all records from the InnovativeIdea table
451
+ db.query(InnovativeIdea).delete()
452
+ db.commit()
453
+ logging.info("Database cleared successfully.")
454
+ except Exception as e:
455
+ db.rollback()
456
+ logging.error(f"Error clearing database: {str(e)}")