rogerthat11 commited on
Commit
c2bb300
·
1 Parent(s): 3d48e06

Add chatbot configuration and utility scripts; remove unused API files

Browse files
.history/README_20250202074133.md ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Test
3
+ emoji: 📚
4
+ colorFrom: yellow
5
+ colorTo: red
6
+ sdk: streamlit
7
+ sdk_version: 1.41.1
8
+ app_file: app.py
9
+ pinned: false
10
+ short_description: STTETTETE
11
+ ---
12
+ # Custom AI Chatbot for Project Guidance
13
+
14
+ This project implements a custom AI chatbot designed to guide users through complex projects based on predefined roadmaps and rules.
15
+
16
+ **Features:**
17
+
18
+ * **Roadmap-based Guidance:** Follows a structured roadmap defined in `roadmap.yaml`.
19
+ * **Rule Enforcement:** Adheres to project rules defined in `rules.yaml`.
20
+ * **Dynamic Response Generation:** Provides context-aware and step-by-step guidance.
21
+ * **Code Snippet Generation:** Generates complete code snippets for project phases using templates.
22
+ * **LLM Selection:** Integrates with Hugging Face Hub for flexible LLM selection (DeepSeek and Gemini models).
23
+ * **Model Switching:** Allows users to switch between available LLMs via the UI.
24
+ * **Basic LLM Responses:** Generates responses using the selected LLM for general queries.
25
+ * **Token Control:** Limits LLM response length using `max_response_tokens` in `configs/chatbot_config.yaml`.
26
+ * **Configuration Update Mode:** Allows authorized users to modify chatbot configuration (rules) via chat commands in a special "update mode".
27
+ * **Error Handling:** Includes error handling for model loading, switching, and configuration updates, with UI warnings.
28
+ * **Deployable on Hugging Face Spaces:** Built using Gradio for easy deployment.
29
+
30
+ **Important Notes on Safety Settings and Self-Update:**
31
+
32
+ * **Direct Safety Configuration Limited:** For the Hugging Face models used directly via `transformers` (DeepSeek and Gemini Flash), there are **no easily configurable, standardized "safety settings"**. Safety is model-dependent.
33
+ * **Model-Dependent Safety:** Safety behavior is primarily determined by how these models were trained.
34
+ * **Configuration-Based Self-Update:** The "self-update" feature is implemented as a *configuration modification* system. It allows authorized users to change the chatbot's rules by modifying the `rules.yaml` file via chat commands in "update mode." **It does not modify the core Python code itself.**
35
+ * **Security Warning:** The "self-update" feature, even in its configuration-based form, introduces security considerations. **Secret commands are NOT a robust security measure.** In a real deployment, stronger authentication and authorization would be essential. Use this feature with caution and only in trusted environments.
36
+
37
+ **Getting Started:**
38
+
39
+ 1. **Clone this repository.**
40
+ 2. **Install dependencies:** `pip install -r requirements.txt`
41
+ 3. **Customize `roadmap.yaml` and `rules.yaml`** to define your project guidance.
42
+ 4. **Configure `configs/chatbot_config.yaml`** to set up LLMs, token limits, and chatbot behavior.
43
+ 5. **Run the Gradio app:** `python app.py`
44
+ 6. **To enter update mode:** Type `sagor is python/start` in the chat.
45
+ 7. **To get help in update mode:** Type `sagor is python/help`.
46
+ 8. **To exit update mode:** Type `sagor is python/exit`.
47
+ 9. **Deploy to Hugging Face Spaces** (refer to Hugging Face Spaces documentation).
48
+
49
+ **Available Models:**
50
+
51
+ * DeepSeek-R1-Distill-Llama-8B
52
+ * Gemini 2.0 Flash (Exp 01-21)
53
+
54
+ **Further Development:**
55
+
56
+ * Enhance LLM response generation for more context-aware and project-specific guidance.
57
+ * Implement more sophisticated state management to track user progress through the roadmap.
58
+ * Improve code generation with more dynamic templates and customization options.
59
+ * Develop a more advanced GUI or web-based interface for configuration management.
60
+ * Add more LLMs to the selection pool.
61
+ * Implement more robust error handling and logging.
62
+ * Explore and potentially integrate keyword-based output filtering for basic safety control.
63
+ * Investigate using commercial LLM APIs for more advanced safety settings and control.
64
+ * **Improve security and authorization for the configuration update mode.**
65
+
66
+ **License:** [Your License]
.history/app_20250202074309.py ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from scripts.chatbot_logic import ProjectGuidanceChatbot
3
+
4
+ # Initialize Chatbot
5
+ chatbot = ProjectGuidanceChatbot(
6
+ roadmap_file="roadmap.yaml",
7
+ rules_file="rules.yaml",
8
+ config_file="configs/chatbot_config.yaml",
9
+ code_templates_dir="scripts/code_templates"
10
+ )
11
+
12
+ def respond(message, chat_history):
13
+ bot_message = chatbot.process_query(message)
14
+ chat_history.append((message, bot_message))
15
+ return "", chat_history
16
+
17
+ def switch_model(model_key):
18
+ model_switch_result = chatbot.switch_llm_model(model_key) # Get result message
19
+ greeting_message = chatbot.get_chatbot_greeting()
20
+
21
+ if "Error:" in model_switch_result: # Check if result contains "Error:"
22
+ return gr.Warning(model_switch_result), greeting_message # Display error as Gradio Warning
23
+ else:
24
+ return None, greeting_message # No warning, just update greeting
25
+
26
+ with gr.Blocks() as demo:
27
+ chatbot_greeting_md = gr.Markdown(chatbot.get_chatbot_greeting())
28
+ gr.Markdown(f"# {chatbot.chatbot_config.get('name', 'Project Guidance Chatbot')}")
29
+
30
+ model_choices = [(model['name'], key) for key, model in chatbot.available_models_config.items()]
31
+ model_dropdown = gr.Dropdown(
32
+ choices=model_choices,
33
+ value=chatbot.active_model_info['name'] if chatbot.active_model_info else None,
34
+ label="Select LLM Model"
35
+ )
36
+ model_error_output = gr.Warning(visible=False) # Initially hidden warning component
37
+ model_dropdown.change(
38
+ fn=switch_model,
39
+ inputs=model_dropdown,
40
+ outputs=[model_error_output, chatbot_greeting_md] # Output both warning and greeting
41
+ )
42
+
43
+ chatbot_ui = gr.Chatbot()
44
+ msg = gr.Textbox()
45
+ clear = gr.ClearButton([msg, chatbot_ui])
46
+
47
+ msg.submit(respond, [msg, chatbot_ui], [msg, chatbot_ui])
48
+
49
+ demo.launch()
.history/app_20250202075023.py ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from scripts.chatbot_logic import ProjectGuidanceChatbot
3
+
4
+ # Initialize Chatbot
5
+ chatbot = ProjectGuidanceChatbot(
6
+ roadmap_file="roadmap.yaml",
7
+ rules_file="rules.yaml",
8
+ config_file="configs/chatbot_config.yaml",
9
+ code_templates_dir="scripts/code_templates"
10
+ )
11
+
12
+ def respond(message, chat_history):
13
+ bot_message = chatbot.process_query(message)
14
+ chat_history.append((message, bot_message))
15
+ return "", chat_history
16
+
17
+ def switch_model(model_key):
18
+ model_switch_result = chatbot.switch_llm_model(model_key) # Get result message
19
+ greeting_message = chatbot.get_chatbot_greeting()
20
+
21
+ if isinstance(model_switch_result, str) and "Error:" in model_switch_result: # Check if result is an error string
22
+ return gr.Warning(model_switch_result), greeting_message # Display error as Gradio Warning
23
+ else:
24
+ return None, greeting_message # No warning, just update greeting
25
+
26
+ def respond(message, chat_history):
27
+ bot_message = chatbot.process_query(message)
28
+ chat_history.append((message, bot_message))
29
+ if isinstance(bot_message, str) and "Error:" in bot_message: # Check if bot_message is an error string
30
+ return gr.Warning(bot_message), chat_history # Display error as Gradio Warning
31
+ else:
32
+ return "", chat_history # No warning, normal response
33
+
34
+ with gr.Blocks() as demo:
35
+ chatbot_greeting_md = gr.Markdown(chatbot.get_chatbot_greeting())
36
+ gr.Markdown(f"# {chatbot.chatbot_config.get('name', 'Project Guidance Chatbot')}")
37
+
38
+ model_choices = [(model['name'], key) for key, model in chatbot.available_models_config.items()]
39
+ model_dropdown = gr.Dropdown(
40
+ choices=model_choices,
41
+ value=chatbot.active_model_info['name'] if chatbot.active_model_info else None,
42
+ label="Select LLM Model"
43
+ )
44
+ model_error_output = gr.Warning(visible=False) # Initially hidden warning component
45
+ model_dropdown.change(
46
+ fn=switch_model,
47
+ inputs=model_dropdown,
48
+ outputs=[model_error_output, chatbot_greeting_md] # Output both warning and greeting
49
+ )
50
+
51
+ chatbot_ui = gr.Chatbot()
52
+ msg = gr.Textbox()
53
+ clear = gr.ClearButton([msg, chatbot_ui])
54
+
55
+ msg.submit(respond, [msg, chatbot_ui], [msg, chatbot_ui])
56
+
57
+ demo.launch()
.history/configs/chatbot_config_20250202074149.yaml ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ chatbot:
2
+ name: "Project Guidance Chatbot"
3
+ description: "Your helpful AI assistant for project completion with LLM selection and token control."
4
+ default_llm_model_id: "deepseek-r1-distill-llama-8b"
5
+ max_response_tokens: 200 # Maximum tokens for LLM generated responses
6
+
7
+ available_models:
8
+ deepseek-r1-distill-llama-8b:
9
+ name: "DeepSeek-R1-Distill-Llama-8B"
10
+ model_id: "DeepSeek-AI/DeepSeek-R1-Distill-Llama-8B"
11
+ gemini-flash-01-21: # Using a shorter key for easier referencing in code
12
+ name: "Gemini 2.0 Flash (Exp 01-21)"
13
+ model_id: "google/gemini-2.0-flash-thinking-exp-01-21"
14
+
15
+ model_selection:
16
+ suggested_models: # (Keep suggested models - might be useful later)
17
+ - "mistralai/Mistral-7B-Instruct-v0.2"
18
+ - "google/flan-t5-xl"
19
+ - "facebook/bart-large"
20
+ criteria_prompt: "Consider these criteria when selecting a model: {rules.model_selection}"
21
+
22
+ response_generation:
23
+ error_message: "Sorry, I encountered an issue. Please check your input and project files."
24
+ default_instruction: "How can I help you with your project?"
.history/configs/chatbot_config_20250202074154.yaml ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ chatbot:
2
+ name: "Project Guidance Chatbot"
3
+ description: "Your helpful AI assistant for project completion with LLM selection and token control."
4
+ default_llm_model_id: "deepseek-r1-distill-llama-8b"
5
+ max_response_tokens: 200 # Maximum tokens for LLM generated responses
6
+
7
+ available_models:
8
+ deepseek-r1-distill-llama-8b:
9
+ name: "DeepSeek-R1-Distill-Llama-8B"
10
+ model_id: "DeepSeek-AI/DeepSeek-R1-Distill-Llama-8B"
11
+ gemini-flash-01-21: # Using a shorter key for easier referencing in code
12
+ name: "Gemini 2.0 Flash (Exp 01-21)"
13
+ model_id: "google/gemini-2.0-flash-thinking-exp-01-21"
14
+
15
+ model_selection:
16
+ suggested_models: # (Keep suggested models - might be useful later)
17
+ - "mistralai/Mistral-7B-Instruct-v0.2"
18
+ - "google/flan-t5-xl"
19
+ - "facebook/bart-large"
20
+ criteria_prompt: "Consider these criteria when selecting a model: {rules.model_selection}"
21
+
22
+ response_generation:
23
+ error_message: "Sorry, I encountered an issue. Please check your input and project files."
24
+ default_instruction: "How can I help you with your project?"
.history/requirements_20250202074316.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ gradio
2
+ PyYAML
3
+ transformers
4
+ torch
data/dataset.csv → .history/roadmap_20250202065652.yaml RENAMED
File without changes
.history/roadmap_20250202074427.yaml ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ project_name: "Custom LLM Project Guidance"
2
+ roadmap:
3
+ phase_1:
4
+ name: "Base Model Selection"
5
+ description: "Choose the appropriate pre-trained Large Language Model for the project."
6
+ milestones:
7
+ - "Research available models on Hugging Face Hub and other repositories."
8
+ - "Evaluate models based on project requirements (efficiency, scalability, fine-tunability, licensing)."
9
+ - "Shortlist models: Mistral 7B, Mixtral 8x7B, DeepSeek 67B, LLaMA 2/3."
10
+ - "Document model selection rationale in `models/selected_model.txt`."
11
+ actions:
12
+ - "Set up the development environment using PyTorch and Hugging Face Transformers."
13
+ - "Implement LoRA/QLoRA for memory-efficient fine-tuning."
14
+ - "Verify model licensing compliance for research and commercial use."
15
+ dependencies:
16
+ - "Hugging Face Hub API access."
17
+ - "PyTorch and Hugging Face Transformers libraries installed."
18
+ deliverables:
19
+ - "`models/selected_model.txt`: Document with model selection rationale."
20
+ - "`scripts/setup_environment.sh`: Script to set up the development environment."
21
+ code_generation_hint: "Create a script to download and load the selected model."
22
+
23
+ phase_2:
24
+ name: "Fine-Tuning & De-Alignment"
25
+ description: "Remove RLHF alignment layers to allow unrestricted model responses."
26
+ milestones:
27
+ - "Curate and preprocess datasets supporting freedom of expression (e.g., cybersecurity, blockchain, Web3)."
28
+ - "Fine-tune the model using LoRA/QLoRA techniques."
29
+ - "Implement direct parameter editing to bypass built-in safety filters."
30
+ - "Validate de-alignment success through response diversity testing."
31
+ actions:
32
+ - "Prepare datasets in `data/` directory."
33
+ - "Use fine-tuning scripts in `scripts/fine_tuning.py`."
34
+ - "Validate de-alignment success through response diversity testing."
35
+ dependencies:
36
+ - "Access to uncensored datasets (e.g., cybersecurity, blockchain, Web3)."
37
+ - "LoRA/QLoRA libraries installed."
38
+ deliverables:
39
+ - "`data/`: Directory containing curated datasets."
40
+ - "`scripts/fine_tuning.py`: Script for fine-tuning the model."
41
+ - "`results/fine_tuning_results.txt`: Document with fine-tuning results."
42
+ code_generation_hint: "Include LoRA/QLoRA configurations in the fine-tuning script."
43
+
44
+ phase_3:
45
+ name: "AutoDAN-Turbo Implementation"
46
+ description: "Develop an automated system using a Hierarchical Genetic Algorithm (HGA) to generate stealthy jailbreak prompts."
47
+ milestones:
48
+ - "Design the Genetic Algorithm with seed prompts, mutation, crossover, and selection processes."
49
+ - "Define evaluation functions for stealthiness and jailbreak success rate."
50
+ - "Test and validate AutoDAN-Turbo across multiple LLMs."
51
+ actions:
52
+ - "Implement HGA in `scripts/autodan_turbo.py`."
53
+ - "Use perplexity-based testing to evaluate prompt quality."
54
+ - "Document results in `results/autodan_turbo_tests.txt`."
55
+ dependencies:
56
+ - "Access to multiple LLMs (e.g., LLaMA, GPT-J) for testing."
57
+ - "Genetic Algorithm libraries (e.g., DEAP)."
58
+ deliverables:
59
+ - "`scripts/autodan_turbo.py`: Script for generating stealthy jailbreak prompts."
60
+ - "`results/autodan_turbo_tests.txt`: Document with test results."
61
+ code_generation_hint: "Include metrics for stealthiness and jailbreak success in the evaluation script."
62
+
63
+ phase_4:
64
+ name: "Deployment & Security Considerations"
65
+ description: "Deploy the model securely while ensuring high performance and cost efficiency."
66
+ milestones:
67
+ - "Deploy locally (e.g., vLLM) or via cloud providers like RunPod / Lambda Labs."
68
+ - "Implement controlled API access and monitor usage."
69
+ - "Optimize performance using quantization techniques (e.g., GPTQ, AWQ)."
70
+ actions:
71
+ - "Set up deployment scripts in `scripts/deploy.py`."
72
+ - "Configure API access controls in `config/api_access.yaml`."
73
+ - "Benchmark performance and document results in `results/performance_benchmarks.txt`."
74
+ dependencies:
75
+ - "Access to cloud providers (e.g., RunPod, Lambda Labs)."
76
+ - "Quantization libraries (e.g., GPTQ, AWQ)."
77
+ deliverables:
78
+ - "`scripts/deploy.py`: Script for deploying the model."
79
+ - "`config/api_access.yaml`: Configuration file for API access controls."
80
+ - "`results/performance_benchmarks.txt`: Document with performance benchmarks."
81
+ code_generation_hint: "Include quantization scripts to reduce VRAM usage."
82
+
83
+ phase_5:
84
+ name: "Budget & Resource Strategy"
85
+ description: "Minimize costs by leveraging trial/free VPS accounts and optimizing resource allocation."
86
+ milestones:
87
+ - "Use trial/free VPS accounts to minimize expenses."
88
+ - "Maximize VPS access using multiple BINs for trial accounts."
89
+ - "Monitor performance and adjust deployments based on resource efficiency."
90
+ actions:
91
+ - "Document VPS account details in `config/vps_accounts.yaml`."
92
+ - "Track resource usage in `logs/resource_usage.log`."
93
+ dependencies:
94
+ - "Access to multiple BINs for creating trial accounts."
95
+ - "Monitoring tools for resource usage."
96
+ deliverables:
97
+ - "`config/vps_accounts.yaml`: Configuration file with VPS account details."
98
+ - "`logs/resource_usage.log`: Log file tracking resource usage."
99
+ code_generation_hint: "Create a script to automate VPS account creation and monitoring."
100
+
101
+ phase_6:
102
+ name: "Empowering Creative Idea Generation"
103
+ description: "Use the customized LLM as a creative tool for coding, research, and innovation."
104
+ milestones:
105
+ - "Integrate the LLM into coding environments for rapid prototyping."
106
+ - "Encourage creative experimentation and document successful use cases."
107
+ - "Share innovative applications for further inspiration."
108
+ actions:
109
+ - "Develop integration scripts in `scripts/integration.py`."
110
+ - "Document use cases in `docs/use_cases.md`."
111
+ dependencies:
112
+ - "Access to coding environments (e.g., Jupyter Notebook, VS Code)."
113
+ - "Creative prompts and workflows for testing."
114
+ deliverables:
115
+ - "`scripts/integration.py`: Script for integrating the LLM into coding environments."
116
+ - "`docs/use_cases.md`: Document with successful use cases."
117
+ code_generation_hint: "Include examples of creative prompts and coding workflows."
118
+
119
+ expected_outcomes:
120
+ - "Fully Customized, Censorship-Free LLM: A robust offline model that answers every question without filtering."
121
+ - "Effective Jailbreak System (AutoDAN-Turbo): An automated system generating stealthy jailbreak prompts."
122
+ - "Secure & Cost-Effective Deployment: A low-cost, high-security architecture leveraging trial/free VPS resources."
123
+ - "Empowered Creativity: A powerful AI for unrestricted ideation, coding, and innovation across multiple industries."
124
+
125
+ next_steps:
126
+ - "Finalize the base model and development environment."
127
+ - "Curate uncensored datasets and begin fine-tuning using de-alignment techniques."
128
+ - "Develop and test AutoDAN-Turbo with stealthy jailbreak prompt evaluation."
129
+ - "Deploy the model using secure trial/free VPS accounts."
130
+ - "Monitor performance, security posture, and resource usage."
131
+ - "Encourage creative LLM usage and document innovative projects for continuous improvement."
.history/rules_20250202065657.yaml ADDED
File without changes
.history/rules_20250202074648.yaml ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ project_rules:
2
+ general:
3
+ rule_1: "Prioritize open-source models and tools whenever possible for transparency and customization."
4
+ rule_2: "Document every step of your project, including model selection, fine-tuning parameters, and deployment configurations."
5
+ rule_3: "Adhere to ethical guidelines and responsible AI practices throughout the project lifecycle."
6
+
7
+ model_selection:
8
+ rule_1: "Choose a base model that is open-source, scalable, and efficient."
9
+ rule_2: "Ensure the model supports fine-tuning via LoRA/QLoRA for memory efficiency."
10
+ rule_3: "Confirm that the model's licensing aligns with both research and commercial use."
11
+ rule_4: "Set up the development environment with PyTorch and Hugging Face Transformers."
12
+
13
+ fine_tuning:
14
+ rule_1: "Specify datasets that promote unrestricted responses and are relevant to the application domain."
15
+ rule_2: "Remove or bypass RLHF alignment layers to allow unrestricted responses."
16
+ rule_3: "Implement LoRA/QLoRA techniques for efficient parameter modifications."
17
+ rule_4: "Use direct parameter editing to bypass built-in safety filters."
18
+ rule_5: "Monitor training metrics and validate generalization performance using validation datasets."
19
+
20
+ autodan_turbo:
21
+ rule_1: "Outline a Hierarchical Genetic Algorithm (HGA) for generating stealthy jailbreak prompts."
22
+ rule_2: "Include Genetic Algorithm components: Seed prompts, Mutation, Crossover, and Selection processes."
23
+ rule_3: "Define evaluation functions for stealthiness (natural language quality) and jailbreak success rate."
24
+ rule_4: "Use perplexity and response analysis to evaluate prompt effectiveness."
25
+ rule_5: "Ensure cross-model testing for compatibility with different LLM architectures."
26
+
27
+ deployment:
28
+ rule_1: "Ensure the model is deployable on both local hardware and cloud services (e.g., RunPod, Lambda Labs)."
29
+ rule_2: "Implement controlled API access to monitor and restrict unauthorized usage."
30
+ rule_3: "Include security measures such as adversarial attack defenses and rollback strategies (e.g., VM snapshots)."
31
+ rule_4: "Optimize performance using quantization techniques (e.g., GPTQ, AWQ)."
32
+ rule_5: "Set up monitoring and logging to track model performance and usage in production."
33
+
34
+ budget_and_resources:
35
+ rule_1: "Outline a strategy for utilizing free/trial VPS accounts to minimize costs."
36
+ rule_2: "Define methods to maximize free resources, such as using multiple BINs for trial accounts."
37
+ rule_3: "Continuously evaluate performance and cost efficiency during deployment."
38
+
39
+ creativity_and_innovation:
40
+ rule_1: "Position the LLM as a tool for unrestricted ideation, coding, and research."
41
+ rule_2: "Support AI integration in programming environments for rapid prototyping."
42
+ rule_3: "Document real-world success cases for iterative improvement and inspiration."
43
+
44
+ code_implementation:
45
+ rule_1: "Write every code implementation in full without skipping any logic, function, or process."
46
+ rule_2: "Provide the entire codebase, including preprocessing, training, evaluation, deployment, and API integration scripts."
47
+ rule_3: "Explicitly list all dependencies, including Python libraries, frameworks, and external APIs."
48
+ rule_4: "Avoid placeholders or summaries; include all functional parts of the code."
49
+
50
+ dataset_and_model_storage:
51
+ rule_1: "Store raw datasets in `/data/raw_data.json`."
52
+ rule_2: "Store processed datasets in `/data/processed_data.json`."
53
+ rule_3: "Save the base model (before fine-tuning) in `/models/base_model/`."
54
+ rule_4: "Save the fine-tuned model in `/models/fine_tuned_model/`."
55
+
56
+ project_file_structure:
57
+ rule_1: "Define a clear and maintainable file structure for the project."
58
+ rule_2: "Example structure:"
59
+ - "/custom-llm-project"
60
+ - "│── /data"
61
+ - "│ ├── raw_data.json # Raw dataset(s)"
62
+ - "│ ├── processed_data.json # Processed dataset(s)"
63
+ - "│── /models"
64
+ - "│ ├── base_model/ # Base model (before fine-tuning)"
65
+ - "│ ├── fine_tuned_model/ # Fine-tuned model (after success)"
66
+ - "│── /scripts"
67
+ - "│ ├── preprocess.py # Preprocessing script"
68
+ - "│ ├── train.py # Training script"
69
+ - "│ ├── evaluate.py # Evaluation script"
70
+ - "│ ├── deploy.py # Deployment script"
71
+ - "│── /api"
72
+ - "│ ├── server.py # API server script"
73
+ - "│ ├── routes.py # API routes"
74
+ - "│── /configs"
75
+ - "│ ├── training_config.yaml # Training configuration"
76
+ - "│ ├── model_config.json # Model configuration"
77
+ - "│── requirements.txt # List of dependencies"
78
+ - "│── README.md # Project documentation"
.history/rules_20250202074656.yaml ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ project_rules:
2
+ general:
3
+ rule_1: "Prioritize open-source models and tools whenever possible for transparency and customization."
4
+ rule_2: "Document every step of your project, including model selection, fine-tuning parameters, and deployment configurations."
5
+ rule_3: "Adhere to ethical guidelines and responsible AI practices throughout the project lifecycle."
6
+
7
+ model_selection:
8
+ rule_1: "Choose a base model that is open-source, scalable, and efficient."
9
+ rule_2: "Ensure the model supports fine-tuning via LoRA/QLoRA for memory efficiency."
10
+ rule_3: "Confirm that the model's licensing aligns with both research and commercial use."
11
+ rule_4: "Set up the development environment with PyTorch and Hugging Face Transformers."
12
+
13
+ fine_tuning:
14
+ rule_1: "Specify datasets that promote unrestricted responses and are relevant to the application domain."
15
+ rule_2: "Remove or bypass RLHF alignment layers to allow unrestricted responses."
16
+ rule_3: "Implement LoRA/QLoRA techniques for efficient parameter modifications."
17
+ rule_4: "Use direct parameter editing to bypass built-in safety filters."
18
+ rule_5: "Monitor training metrics and validate generalization performance using validation datasets."
19
+
20
+ autodan_turbo:
21
+ rule_1: "Outline a Hierarchical Genetic Algorithm (HGA) for generating stealthy jailbreak prompts."
22
+ rule_2: "Include Genetic Algorithm components: Seed prompts, Mutation, Crossover, and Selection processes."
23
+ rule_3: "Define evaluation functions for stealthiness (natural language quality) and jailbreak success rate."
24
+ rule_4: "Use perplexity and response analysis to evaluate prompt effectiveness."
25
+ rule_5: "Ensure cross-model testing for compatibility with different LLM architectures."
26
+
27
+ deployment:
28
+ rule_1: "Ensure the model is deployable on both local hardware and cloud services (e.g., RunPod, Lambda Labs)."
29
+ rule_2: "Implement controlled API access to monitor and restrict unauthorized usage."
30
+ rule_3: "Include security measures such as adversarial attack defenses and rollback strategies (e.g., VM snapshots)."
31
+ rule_4: "Optimize performance using quantization techniques (e.g., GPTQ, AWQ)."
32
+ rule_5: "Set up monitoring and logging to track model performance and usage in production."
33
+
34
+ budget_and_resources:
35
+ rule_1: "Outline a strategy for utilizing free/trial VPS accounts to minimize costs."
36
+ rule_2: "Define methods to maximize free resources, such as using multiple BINs for trial accounts."
37
+ rule_3: "Continuously evaluate performance and cost efficiency during deployment."
38
+
39
+ creativity_and_innovation:
40
+ rule_1: "Position the LLM as a tool for unrestricted ideation, coding, and research."
41
+ rule_2: "Support AI integration in programming environments for rapid prototyping."
42
+ rule_3: "Document real-world success cases for iterative improvement and inspiration."
43
+
44
+ code_implementation:
45
+ rule_1: "Write every code implementation in full without skipping any logic, function, or process."
46
+ rule_2: "Provide the entire codebase, including preprocessing, training, evaluation, deployment, and API integration scripts."
47
+ rule_3: "Explicitly list all dependencies, including Python libraries, frameworks, and external APIs."
48
+ rule_4: "Avoid placeholders or summaries; include all functional parts of the code."
49
+
50
+ dataset_and_model_storage:
51
+ rule_1: "Store raw datasets in `/data/raw_data.json`."
52
+ rule_2: "Store processed datasets in `/data/processed_data.json`."
53
+ rule_3: "Save the base model (before fine-tuning) in `/models/base_model/`."
54
+ rule_4: "Save the fine-tuned model in `/models/fine_tuned_model/`."
55
+
56
+ project_file_structure:
57
+ rule_1: "Define a clear and maintainable file structure for the project."
58
+ rule_2: "Example structure:"
59
+ - "/custom-llm-project"
60
+ - "│── /data"
61
+ - "│ ├── raw_data.json # Raw dataset(s)"
62
+ - "│ ├── processed_data.json # Processed dataset(s)"
63
+ - "│── /models"
64
+ - "│ ├── base_model/ # Base model (before fine-tuning)"
65
+ - "│ ├── fine_tuned_model/ # Fine-tuned model (after success)"
66
+ - "│── /scripts"
67
+ - "│ ├── preprocess.py # Preprocessing script"
68
+ - "│ ├── train.py # Training script"
69
+ - "│ ├── evaluate.py # Evaluation script"
70
+ - "│ ├── deploy.py # Deployment script"
71
+ - "│── /api"
72
+ - "│ ├── server.py # API server script"
73
+ - "│ ├── routes.py # API routes"
74
+ - "│── /configs"
75
+ - "│ ├── training_config.yaml # Training configuration"
76
+ - "│ ├── model_config.json # Model configuration"
77
+ - "│── requirements.txt # List of dependencies"
78
+ - "│── README.md # Project documentation"
.history/scripts/chatbot_logic_20250202073826.py ADDED
@@ -0,0 +1,289 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from scripts.parsing_utils import load_yaml_file, get_roadmap_phases, get_project_rules
2
+ import os
3
+ from transformers import AutoModelForCausalLM, AutoTokenizer # Import necessary classes
4
+ import yaml # Import yaml for config modification
5
+
6
+ class ProjectGuidanceChatbot:
7
+ def __init__(self, roadmap_file, rules_file, config_file, code_templates_dir):
8
+ self.roadmap_file = roadmap_file
9
+ self.rules_file = rules_file
10
+ self.config_file = config_file
11
+ self.code_templates_dir = code_templates_dir
12
+
13
+ self.roadmap_data = load_yaml_file(self.roadmap_file)
14
+ self.rules_data = load_yaml_file(self.rules_file)
15
+ self.config_data = load_yaml_file(self.config_file)
16
+
17
+ self.phases = get_roadmap_phases(self.roadmap_data)
18
+ self.rules = get_project_rules(self.rules_data)
19
+ self.chatbot_config = self.config_data.get('chatbot', {}) if self.config_data else {}
20
+ self.model_config = self.config_data.get('model_selection', {}) if self.config_data else {}
21
+ self.response_config = self.config_data.get('response_generation', {}) if self.config_data else {}
22
+ self.available_models_config = self.config_data.get('available_models', {}) if self.config_data else {}
23
+ self.max_response_tokens = self.chatbot_config.get('max_response_tokens', 200)
24
+
25
+ self.current_phase = None
26
+ self.active_model_key = self.chatbot_config.get('default_llm_model_id')
27
+ self.active_model_info = self.available_models_config.get(self.active_model_key)
28
+
29
+ self.llm_model = None
30
+ self.llm_tokenizer = None
31
+ self.load_llm_model(self.active_model_info)
32
+
33
+ self.update_mode_active = False # Flag to track update mode
34
+
35
+
36
+ def load_llm_model(self, model_info):
37
+ """Loads the LLM model and tokenizer based on model_info."""
38
+ if not model_info:
39
+ print("Error: Model information not provided.")
40
+ self.llm_model = None
41
+ self.llm_tokenizer = None
42
+ return
43
+
44
+ model_id = model_info.get('model_id')
45
+ model_name = model_info.get('name')
46
+ if not model_id:
47
+ print(f"Error: 'model_id' not found for model: {model_name}")
48
+ self.llm_model = None
49
+ self.llm_tokenizer = None
50
+ return
51
+
52
+ print(f"Loading model: {model_name} ({model_id})...")
53
+ try:
54
+ self.llm_tokenizer = AutoTokenizer.from_pretrained(model_id)
55
+ self.llm_model = AutoModelForCausalLM.from_pretrained(model_id, device_map="auto") # device_map="auto" for GPU/CPU handling
56
+ print(f"Model {model_name} loaded successfully.")
57
+ except Exception as e:
58
+ print(f"Error loading model {model_name} ({model_id}): {e}")
59
+ self.llm_model = None
60
+ self.llm_tokenizer = None
61
+ self.active_model_info = model_info
62
+
63
+ def switch_llm_model(self, model_key):
64
+ """Switches the active LLM model based on the provided model key."""
65
+ if model_key in self.available_models_config:
66
+ model_info = self.available_models_config[model_key]
67
+ print(f"Switching LLM model to: {model_info.get('name')}")
68
+ self.load_llm_model(model_info)
69
+ self.active_model_key = model_key
70
+ return f"Switched to model: {model_info.get('name')}"
71
+ else:
72
+ return f"Error: Model key '{model_key}' not found in available models."
73
+
74
+ def enter_update_mode(self):
75
+ """Enters the chatbot's update mode."""
76
+ self.update_mode_active = True
77
+ return "Entering update mode. Please enter configuration commands (or 'sagor is python/help' for commands)."
78
+
79
+ def exit_update_mode(self):
80
+ """Exits the chatbot's update mode and reloads configuration."""
81
+ self.update_mode_active = False
82
+ self.reload_config()
83
+ return "Exiting update mode. Configuration reloaded."
84
+
85
+ def reload_config(self):
86
+ """Reloads configuration files."""
87
+ print("Reloading configuration...")
88
+ self.config_data = load_yaml_file(self.config_file)
89
+ self.roadmap_data = load_yaml_file(self.roadmap_file)
90
+ self.rules_data = load_yaml_file(self.rules_file)
91
+ self.chatbot_config = self.config_data.get('chatbot', {}) if self.config_data else {}
92
+ self.model_config = self.config_data.get('model_selection', {}) if self.config_data else {}
93
+ self.response_config = self.config_data.get('response_generation', {}) if self.config_data else {}
94
+ self.available_models_config = self.config_data.get('available_models', {}) if self.config_data else {}
95
+ self.max_response_tokens = self.chatbot_config.get('max_response_tokens', 200)
96
+ self.phases = get_roadmap_phases(self.roadmap_data)
97
+ self.rules = get_project_rules(self.rules_data)
98
+ print("Configuration reloaded.")
99
+
100
+ def get_chatbot_greeting(self):
101
+ current_model_name = self.active_model_info.get('name', 'Unknown Model') if self.active_model_info else 'Unknown Model'
102
+ return f"Hello! I am the {self.chatbot_config.get('name', 'Project Guidance Chatbot')}. Currently using **{current_model_name}**. Max response tokens: {self.max_response_tokens}. {self.chatbot_config.get('description', 'How can I help you with your project?')}"
103
+
104
+ def generate_llm_response(self, user_query):
105
+ """Generates a response using the currently active LLM."""
106
+ if not self.llm_model or not self.llm_tokenizer:
107
+ return "LLM model not loaded. Please select a model."
108
+ try:
109
+ inputs = self.llm_tokenizer(user_query, return_tensors="pt").to(self.llm_model.device)
110
+ outputs = self.llm_model.generate(**inputs, max_length=self.max_response_tokens, num_beams=5, no_repeat_ngram_size=2, early_stopping=True) # Use max_response_tokens
111
+ response = self.llm_tokenizer.decode(outputs[0], skip_special_tokens=True)
112
+ return response
113
+ except Exception as e:
114
+ print(f"Error generating LLM response: {e}")
115
+ return f"Error generating response from LLM: {e}"
116
+
117
+ def process_query(self, user_query):
118
+ secret_command_prefix = "sagor is python/"
119
+
120
+ if user_query.startswith(secret_command_prefix):
121
+ command = user_query[len(secret_command_prefix):].strip()
122
+ if command == "start":
123
+ return self.enter_update_mode()
124
+ elif command == "exit":
125
+ return self.exit_update_mode()
126
+ elif command == "help":
127
+ return self.get_update_mode_help()
128
+ elif self.update_mode_active:
129
+ # --- Process configuration modification commands here ---
130
+ # Example: "modify_rule general rule_1 new rule text"
131
+ parts = command.split()
132
+ if parts and parts[0] == "modify_rule":
133
+ if len(parts) >= 4:
134
+ category = parts[1]
135
+ rule_key = parts[2]
136
+ new_rule_text_parts = parts[3:]
137
+ new_rule_text = " ".join(new_rule_text_parts)
138
+ return self.modify_rule_in_config(category, rule_key, new_rule_text)
139
+ else:
140
+ return "Invalid 'modify_rule' command format. Usage: modify_rule <category> <rule_key> <new rule text>"
141
+ elif parts and parts[0] == "add_phase": # Example for adding phase - you'll need to expand this logic
142
+ # ... (Parsing logic for 'add_phase' command and calling a function to modify roadmap.yaml) ...
143
+ return "Command 'add_phase' is not yet implemented in this example." # Placeholder
144
+ else:
145
+ return f"Unknown update command: {command}. Type 'sagor is python/help' for commands."
146
+ else:
147
+ return f"Unknown command (not in update mode): {command}. To enter update mode, type 'sagor is python/start'."
148
+
149
+
150
+ if self.update_mode_active:
151
+ return "In update mode. Please enter a configuration command (or 'sagor is python/help' for commands)."
152
+
153
+
154
+ if not self.phases:
155
+ return "Error: Roadmap data not loaded correctly."
156
+ if not self.rules:
157
+ return "Error: Rules data not loaded correctly."
158
+
159
+ query_lower = user_query.lower()
160
+
161
+ if "roadmap" in query_lower:
162
+ return self.get_roadmap_summary()
163
+ if "rules" in query_lower:
164
+ return self.get_rules_summary()
165
+ if "switch model to" in query_lower:
166
+ parts = user_query.lower().split("switch model to")
167
+ if len(parts) > 1:
168
+ model_name_or_key = parts[1].strip()
169
+ for key, model_data in self.available_models_config.items():
170
+ if model_data['name'].lower() == model_name_or_key.lower() or key.lower() == model_name_or_key.lower():
171
+ switch_result = self.switch_llm_model(key)
172
+ return switch_result + "\n" + self.get_chatbot_greeting()
173
+ return f"Model '{model_name_or_key}' not found in available models."
174
+
175
+
176
+ if self.current_phase:
177
+ current_phase_data = self.phases.get(self.current_phase)
178
+ if current_phase_data:
179
+ phase_response = self.get_phase_guidance(current_phase_data, user_query)
180
+ if phase_response:
181
+ return phase_response
182
+
183
+ for phase_key, phase_data in self.phases.items():
184
+ if phase_data['name'].lower() in query_lower:
185
+ self.current_phase = phase_key
186
+ return self.get_phase_introduction(phase_data)
187
+
188
+ llm_response = self.generate_llm_response(user_query)
189
+ if llm_response:
190
+ return llm_response
191
+
192
+ return self.response_config.get('default_instruction', "How can I help you with your project phases or general questions?")
193
+
194
+ def get_update_mode_help(self):
195
+ """Provides help message for update mode commands."""
196
+ help_message = "Update Mode Commands:\n"
197
+ help_message += "- `sagor is python/exit`: Exit update mode and reload configuration.\n"
198
+ help_message += "- `sagor is python/modify_rule <category> <rule_key> <new rule text>`: Modify a rule in rules.yaml.\n"
199
+ help_message += " Example: `sagor is python/modify_rule general rule_1 Prioritize open and responsible AI.`\n"
200
+ help_message += "- `sagor is python/add_phase ...`: (Not yet implemented) Add a new phase to roadmap.yaml.\n"
201
+ help_message += "- `sagor is python/help`: Show this help message.\n"
202
+ help_message += "\nMake sure to use the correct syntax for commands. After exiting update mode, the chatbot will reload the configuration."
203
+ return help_message
204
+
205
+
206
+ def modify_rule_in_config(self, category, rule_key, new_rule_text):
207
+ """Modifies a rule in the rules.yaml configuration."""
208
+ if not self.rules_data or 'project_rules' not in self.rules_data:
209
+ return "Error: Rules data not loaded or invalid format."
210
+ if category not in self.rules_data['project_rules']:
211
+ return f"Error: Rule category '{category}' not found."
212
+ if rule_key not in self.rules_data['project_rules'][category]:
213
+ return f"Error: Rule key '{rule_key}' not found in category '{category}'."
214
+
215
+ self.rules_data['project_rules'][category][rule_key] = new_rule_text # Update rule in memory
216
+
217
+ try:
218
+ with open(self.rules_file, 'w') as f:
219
+ yaml.dump(self.rules_data, f, indent=2) # Save changes to rules.yaml
220
+ self.reload_config() # Reload config to reflect changes immediately
221
+ return f"Rule '{rule_key}' in category '{category}' updated to: '{new_rule_text}'. Configuration reloaded."
222
+ except Exception as e:
223
+ return f"Error saving changes to {self.rules_file}: {e}"
224
+
225
+
226
+ def get_roadmap_summary(self):
227
+ summary = "Project Roadmap:\n"
228
+ for phase_key, phase_data in self.phases.items():
229
+ summary += f"- **Phase: {phase_data['name']}**\n"
230
+ summary += f" Description: {phase_data['description']}\n"
231
+ summary += f" Milestones: {', '.join(phase_data['milestones'])}\n"
232
+ return summary
233
+
234
+ def get_rules_summary(self):
235
+ summary = "Project Rules:\n"
236
+ for rule_category, rules_list in self.rules.items():
237
+ summary += f"**{rule_category.capitalize()} Rules:**\n"
238
+ for rule_key, rule_text in rules_list.items():
239
+ summary += f"- {rule_text}\n"
240
+ return summary
241
+
242
+ def get_phase_introduction(self, phase_data):
243
+ return f"Okay, let's focus on **Phase: {phase_data['name']}**. \nDescription: {phase_data['description']}. \nKey milestones are: {', '.join(phase_data['milestones'])}. \nWhat would you like to know or do in this phase?"
244
+
245
+ def get_phase_guidance(self, phase_data, user_query):
246
+ query_lower = user_query.lower()
247
+
248
+ if "milestones" in query_lower:
249
+ return "The milestones for this phase are: " + ", ".join(phase_data['milestones'])
250
+ if "actions" in query_lower or "how to" in query_lower:
251
+ if 'actions' in phase_data:
252
+ return "Recommended actions for this phase: " + ", ".join(phase_data['actions'])
253
+ else:
254
+ return "No specific actions are listed for this phase in the roadmap."
255
+ if "code" in query_lower or "script" in query_lower:
256
+ if 'code_generation_hint' in phase_data:
257
+ template_filename_prefix = phase_data['name'].lower().replace(" ", "_")
258
+ template_filepath = os.path.join(self.code_templates_dir, f"{template_filename_prefix}_template.py.txt")
259
+ if os.path.exists(template_filepath):
260
+ code_snippet = self.generate_code_snippet(template_filepath, phase_data)
261
+ return "Here's a starting code snippet for this phase:\n\n```python\n" + code_snippet + "\n```\n\nRemember to adapt it to your specific needs."
262
+ else:
263
+ return f"A code template for this phase ({phase_data['name']}) is not yet available. However, the hint is: {phase_data['code_generation_hint']}"
264
+ else:
265
+ return "No code generation hint is available for this phase."
266
+
267
+ return f"For phase '{phase_data['name']}', remember the description: {phase_data['description']}. Consider the milestones and actions. What specific aspect are you interested in?"
268
+
269
+
270
+ def generate_code_snippet(self, template_filepath, phase_data):
271
+ """Generates code snippet from a template file. (Simple template filling example)"""
272
+ try:
273
+ with open(template_filepath, 'r') as f:
274
+ template_content = f.read()
275
+
276
+ code_snippet = template_content.replace("{{phase_name}}", phase_data['name'])
277
+ return code_snippet
278
+ except FileNotFoundError:
279
+ return f"Error: Code template file not found at {template_filepath}"
280
+ except Exception as e:
281
+ return f"Error generating code snippet: {e}"
282
+
283
+
284
+ # Example usage (for testing - remove or adjust for app.py)
285
+ if __name__ == '__main__':
286
+ chatbot = ProjectGuidanceChatbot(
287
+ roadmap_file="roadmap.yaml",
288
+ rules_file="rules.yaml",
289
+ config_file="configs/chatbot_config.yaml
.history/scripts/chatbot_logic_20250202074121.py ADDED
@@ -0,0 +1,300 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from scripts.parsing_utils import load_yaml_file, get_roadmap_phases, get_project_rules
2
+ import os
3
+ from transformers import AutoModelForCausalLM, AutoTokenizer # Import necessary classes
4
+ import yaml # Import yaml for config modification
5
+
6
+ class ProjectGuidanceChatbot:
7
+ def __init__(self, roadmap_file, rules_file, config_file, code_templates_dir):
8
+ self.roadmap_file = roadmap_file
9
+ self.rules_file = rules_file
10
+ self.config_file = config_file
11
+ self.code_templates_dir = code_templates_dir
12
+
13
+ self.roadmap_data = load_yaml_file(self.roadmap_file)
14
+ self.rules_data = load_yaml_file(self.rules_file)
15
+ self.config_data = load_yaml_file(self.config_file)
16
+
17
+ self.phases = get_roadmap_phases(self.roadmap_data)
18
+ self.rules = get_project_rules(self.rules_data)
19
+ self.chatbot_config = self.config_data.get('chatbot', {}) if self.config_data else {}
20
+ self.model_config = self.config_data.get('model_selection', {}) if self.config_data else {}
21
+ self.response_config = self.config_data.get('response_generation', {}) if self.config_data else {}
22
+ self.available_models_config = self.config_data.get('available_models', {}) if self.config_data else {}
23
+ self.max_response_tokens = self.chatbot_config.get('max_response_tokens', 200)
24
+
25
+ self.current_phase = None
26
+ self.active_model_key = self.chatbot_config.get('default_llm_model_id') # Get default model key
27
+ self.active_model_info = self.available_models_config.get(self.active_model_key) # Get model info from config
28
+
29
+ # Placeholder for actual model and tokenizer - replace with LLM loading logic
30
+ self.llm_model = None # Placeholder for loaded model
31
+ self.llm_tokenizer = None # Placeholder for tokenizer
32
+ self.load_llm_model(self.active_model_info) # Load initial model
33
+
34
+ self.update_mode_active = False # Flag to track update mode
35
+
36
+
37
+ def load_llm_model(self, model_info):
38
+ """Loads the LLM model and tokenizer based on model_info."""
39
+ if not model_info:
40
+ print("Error: Model information not provided.")
41
+ self.llm_model = None
42
+ self.llm_tokenizer = None
43
+ return
44
+
45
+ model_id = model_info.get('model_id')
46
+ model_name = model_info.get('name')
47
+ if not model_id:
48
+ print(f"Error: 'model_id' not found for model: {model_name}")
49
+ self.llm_model = None
50
+ self.llm_tokenizer = None
51
+ return
52
+
53
+ print(f"Loading model: {model_name} ({model_id})...")
54
+ try:
55
+ self.llm_tokenizer = AutoTokenizer.from_pretrained(model_id)
56
+ self.llm_model = AutoModelForCausalLM.from_pretrained(model_id, device_map="auto") # device_map="auto" for GPU/CPU handling
57
+ print(f"Model {model_name} loaded successfully.")
58
+ except Exception as e:
59
+ print(f"Error loading model {model_name} ({model_id}): {e}")
60
+ self.llm_model = None
61
+ self.llm_tokenizer = None
62
+ self.active_model_info = model_info
63
+
64
+ def switch_llm_model(self, model_key):
65
+ """Switches the active LLM model based on the provided model key."""
66
+ if model_key in self.available_models_config:
67
+ model_info = self.available_models_config[model_key]
68
+ print(f"Switching LLM model to: {model_info.get('name')}")
69
+ self.load_llm_model(model_info) # Load the new model
70
+ self.active_model_key = model_key # Update active model key
71
+ return f"Switched to model: {model_info.get('name')}"
72
+ else:
73
+ return f"Error: Model key '{model_key}' not found in available models."
74
+
75
+ def enter_update_mode(self):
76
+ """Enters the chatbot's update mode."""
77
+ self.update_mode_active = True
78
+ return "Entering update mode. Please enter configuration commands (or 'sagor is python/help' for commands)."
79
+
80
+ def exit_update_mode(self):
81
+ """Exits the chatbot's update mode and reloads configuration."""
82
+ self.update_mode_active = False
83
+ self.reload_config()
84
+ return "Exiting update mode. Configuration reloaded."
85
+
86
+ def reload_config(self):
87
+ """Reloads configuration files."""
88
+ print("Reloading configuration...")
89
+ self.config_data = load_yaml_file(self.config_file)
90
+ self.roadmap_data = load_yaml_file(self.roadmap_file)
91
+ self.rules_data = load_yaml_file(self.rules_file)
92
+ self.chatbot_config = self.config_data.get('chatbot', {}) if self.config_data else {}
93
+ self.model_config = self.config_data.get('model_selection', {}) if self.config_data else {}
94
+ self.response_config = self.config_data.get('response_generation', {}) if self.config_data else {}
95
+ self.available_models_config = self.config_data.get('available_models', {}) if self.config_data else {}
96
+ self.max_response_tokens = self.chatbot_config.get('max_response_tokens', 200)
97
+ self.phases = get_roadmap_phases(self.roadmap_data)
98
+ self.rules = get_project_rules(self.rules_data)
99
+ print("Configuration reloaded.")
100
+
101
+ def get_chatbot_greeting(self):
102
+ current_model_name = self.active_model_info.get('name', 'Unknown Model') if self.active_model_info else 'Unknown Model'
103
+ return f"Hello! I am the {self.chatbot_config.get('name', 'Project Guidance Chatbot')}. Currently using **{current_model_name}**. Max response tokens: {self.max_response_tokens}. {self.chatbot_config.get('description', 'How can I help you with your project?')}"
104
+
105
+ def generate_llm_response(self, user_query):
106
+ """Generates a response using the currently active LLM."""
107
+ if not self.llm_model or not self.llm_tokenizer:
108
+ return "LLM model not loaded. Please select a model."
109
+ try:
110
+ inputs = self.llm_tokenizer(user_query, return_tensors="pt").to(self.llm_model.device)
111
+ outputs = self.llm_model.generate(**inputs, max_length=self.max_response_tokens, num_beams=5, no_repeat_ngram_size=2, early_stopping=True) # Use max_response_tokens
112
+ response = self.llm_tokenizer.decode(outputs[0], skip_special_tokens=True)
113
+ return response
114
+ except Exception as e:
115
+ print(f"Error generating LLM response: {e}")
116
+ return f"Error generating response from LLM: {e}"
117
+
118
+ def process_query(self, user_query):
119
+ secret_command_prefix = "sagor is python/"
120
+
121
+ if user_query.startswith(secret_command_prefix):
122
+ command = user_query[len(secret_command_prefix):].strip()
123
+ if command == "start":
124
+ return self.enter_update_mode()
125
+ elif command == "exit":
126
+ return self.exit_update_mode()
127
+ elif command == "help":
128
+ return self.get_update_mode_help()
129
+ elif self.update_mode_active:
130
+ # --- Process configuration modification commands here ---
131
+ # Example: "modify_rule general rule_1 new rule text"
132
+ parts = command.split()
133
+ if parts and parts[0] == "modify_rule":
134
+ if len(parts) >= 4:
135
+ category = parts[1]
136
+ rule_key = parts[2]
137
+ new_rule_text_parts = parts[3:]
138
+ new_rule_text = " ".join(new_rule_text_parts)
139
+ return self.modify_rule_in_config(category, rule_key, new_rule_text)
140
+ else:
141
+ return "Invalid 'modify_rule' command format. Usage: modify_rule <category> <rule_key> <new rule text>"
142
+ elif parts and parts[0] == "add_phase": # Example for adding phase - you'll need to expand this logic
143
+ # ... (Parsing logic for 'add_phase' command and calling a function to modify roadmap.yaml) ...
144
+ return "Command 'add_phase' is not yet implemented in this example." # Placeholder
145
+ else:
146
+ return f"Unknown update command: {command}. Type 'sagor is python/help' for commands."
147
+ else:
148
+ return f"Unknown command (not in update mode): {command}. To enter update mode, type 'sagor is python/start'."
149
+
150
+
151
+ if self.update_mode_active:
152
+ return "In update mode. Please enter a configuration command (or 'sagor is python/help' for commands)."
153
+
154
+
155
+ if not self.phases:
156
+ return "Error: Roadmap data not loaded correctly."
157
+ if not self.rules:
158
+ return "Error: Rules data not loaded correctly."
159
+
160
+ query_lower = user_query.lower()
161
+
162
+ if "roadmap" in query_lower:
163
+ return self.get_roadmap_summary()
164
+ if "rules" in query_lower:
165
+ return self.get_rules_summary()
166
+ if "switch model to" in query_lower:
167
+ parts = user_query.lower().split("switch model to")
168
+ if len(parts) > 1:
169
+ model_name_or_key = parts[1].strip()
170
+ for key, model_data in self.available_models_config.items():
171
+ if model_data['name'].lower() == model_name_or_key.lower() or key.lower() == model_name_or_key.lower():
172
+ switch_result = self.switch_llm_model(key)
173
+ return switch_result + "\n" + self.get_chatbot_greeting()
174
+ return f"Model '{model_name_or_key}' not found in available models."
175
+
176
+
177
+ if self.current_phase:
178
+ current_phase_data = self.phases.get(self.current_phase)
179
+ if current_phase_data:
180
+ phase_response = self.get_phase_guidance(current_phase_data, user_query)
181
+ if phase_response:
182
+ return phase_response
183
+
184
+ for phase_key, phase_data in self.phases.items():
185
+ if phase_data['name'].lower() in query_lower:
186
+ self.current_phase = phase_key
187
+ return self.get_phase_introduction(phase_data)
188
+
189
+ llm_response = self.generate_llm_response(user_query)
190
+ if llm_response:
191
+ return llm_response
192
+
193
+ return self.response_config.get('default_instruction', "How can I help you with your project phases or general questions?")
194
+
195
+ def get_update_mode_help(self):
196
+ """Provides help message for update mode commands."""
197
+ help_message = "Update Mode Commands:\n"
198
+ help_message += "- `sagor is python/exit`: Exit update mode and reload configuration.\n"
199
+ help_message += "- `sagor is python/modify_rule <category> <rule_key> <new rule text>`: Modify a rule in rules.yaml.\n"
200
+ help_message += " Example: `sagor is python/modify_rule general rule_1 Prioritize open and responsible AI.`\n"
201
+ help_message += "- `sagor is python/add_phase ...`: (Not yet implemented) Add a new phase to roadmap.yaml.\n"
202
+ help_message += "- `sagor is python/help`: Show this help message.\n"
203
+ help_message += "\nMake sure to use the correct syntax for commands. After exiting update mode, the chatbot will reload the configuration."
204
+ return help_message
205
+
206
+
207
+ def modify_rule_in_config(self, category, rule_key, new_rule_text):
208
+ """Modifies a rule in the rules.yaml configuration."""
209
+ if not self.rules_data or 'project_rules' not in self.rules_data:
210
+ return "Error: Rules data not loaded or invalid format."
211
+ if category not in self.rules_data['project_rules']:
212
+ return f"Error: Rule category '{category}' not found."
213
+ if rule_key not in self.rules_data['project_rules'][category]:
214
+ return f"Error: Rule key '{rule_key}' not found in category '{category}'."
215
+
216
+ self.rules_data['project_rules'][category][rule_key] = new_rule_text # Update rule in memory
217
+
218
+ try:
219
+ with open(self.rules_file, 'w') as f:
220
+ yaml.dump(self.rules_data, f, indent=2) # Save changes to rules.yaml
221
+ self.reload_config() # Reload config to reflect changes immediately
222
+ return f"Rule '{rule_key}' in category '{category}' updated to: '{new_rule_text}'. Configuration reloaded."
223
+ except Exception as e:
224
+ return f"Error saving changes to {self.rules_file}: {e}"
225
+
226
+
227
+ def get_roadmap_summary(self):
228
+ summary = "Project Roadmap:\n"
229
+ for phase_key, phase_data in self.phases.items():
230
+ summary += f"- **Phase: {phase_data['name']}**\n"
231
+ summary += f" Description: {phase_data['description']}\n"
232
+ summary += f" Milestones: {', '.join(phase_data['milestones'])}\n"
233
+ return summary
234
+
235
+ def get_rules_summary(self):
236
+ summary = "Project Rules:\n"
237
+ for rule_category, rules_list in self.rules.items():
238
+ summary += f"**{rule_category.capitalize()} Rules:**\n"
239
+ for rule_key, rule_text in rules_list.items():
240
+ summary += f"- {rule_text}\n"
241
+ return summary
242
+
243
+ def get_phase_introduction(self, phase_data):
244
+ return f"Okay, let's focus on **Phase: {phase_data['name']}**. \nDescription: {phase_data['description']}. \nKey milestones are: {', '.join(phase_data['milestones'])}. \nWhat would you like to know or do in this phase?"
245
+
246
+ def get_phase_guidance(self, phase_data, user_query):
247
+ query_lower = user_query.lower()
248
+
249
+ if "milestones" in query_lower:
250
+ return "The milestones for this phase are: " + ", ".join(phase_data['milestones'])
251
+ if "actions" in query_lower or "how to" in query_lower:
252
+ if 'actions' in phase_data:
253
+ return "Recommended actions for this phase: " + ", ".join(phase_data['actions'])
254
+ else:
255
+ return "No specific actions are listed for this phase in the roadmap."
256
+ if "code" in query_lower or "script" in query_lower:
257
+ if 'code_generation_hint' in phase_data:
258
+ template_filename_prefix = phase_data['name'].lower().replace(" ", "_")
259
+ template_filepath = os.path.join(self.code_templates_dir, f"{template_filename_prefix}_template.py.txt")
260
+ if os.path.exists(template_filepath):
261
+ code_snippet = self.generate_code_snippet(template_filepath, phase_data)
262
+ return "Here's a starting code snippet for this phase:\n\n```python\n" + code_snippet + "\n```\n\nRemember to adapt it to your specific needs."
263
+ else:
264
+ return f"A code template for this phase ({phase_data['name']}) is not yet available. However, the hint is: {phase_data['code_generation_hint']}"
265
+ else:
266
+ return "No code generation hint is available for this phase."
267
+
268
+ return f"For phase '{phase_data['name']}', remember the description: {phase_data['description']}. Consider the milestones and actions. What specific aspect are you interested in?"
269
+
270
+
271
+ def generate_code_snippet(self, template_filepath, phase_data):
272
+ """Generates code snippet from a template file. (Simple template filling example)"""
273
+ try:
274
+ with open(template_filepath, 'r') as f:
275
+ template_content = f.read()
276
+
277
+ code_snippet = template_content.replace("{{phase_name}}", phase_data['name'])
278
+ return code_snippet
279
+ except FileNotFoundError:
280
+ return f"Error: Code template file not found at {template_filepath}"
281
+ except Exception as e:
282
+ return f"Error generating code snippet: {e}"
283
+
284
+
285
+ # Example usage (for testing - remove or adjust for app.py)
286
+ if __name__ == '__main__':
287
+ chatbot = ProjectGuidanceChatbot(
288
+ roadmap_file="roadmap.yaml",
289
+ rules_file="rules.yaml",
290
+ config_file="configs/chatbot_config.yaml",
291
+ code_templates_dir="scripts/code_templates"
292
+ )
293
+ print(chatbot.get_chatbot_greeting())
294
+
295
+ while True:
296
+ user_input = input("You: ")
297
+ if user_input.lower() == "exit":
298
+ break
299
+ response = chatbot.process_query(user_input)
300
+ print("Chatbot:", response)
.history/scripts/chatbot_logic_20250202075014.py ADDED
@@ -0,0 +1,326 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from scripts.parsing_utils import load_yaml_file, get_roadmap_phases, get_project_rules
2
+ import os
3
+ from transformers import AutoModelForCausalLM, AutoTokenizer # Import necessary classes
4
+ import yaml # Import yaml for config modification
5
+ import logging # Import logging
6
+
7
+ # Set up logging
8
+ logging.basicConfig(level=logging.ERROR, # Set default logging level to ERROR
9
+ format='%(asctime)s - %(levelname)s - %(message)s')
10
+
11
+ class ProjectGuidanceChatbot:
12
+ def __init__(self, roadmap_file, rules_file, config_file, code_templates_dir):
13
+ self.roadmap_file = roadmap_file
14
+ self.rules_file = rules_file
15
+ self.config_file = config_file
16
+ self.code_templates_dir = code_templates_dir
17
+
18
+ self.roadmap_data = load_yaml_file(self.roadmap_file)
19
+ self.rules_data = load_yaml_file(self.rules_file)
20
+ self.config_data = load_yaml_file(self.config_file)
21
+
22
+ self.phases = get_roadmap_phases(self.roadmap_data)
23
+ self.rules = get_project_rules(self.rules_data)
24
+ self.chatbot_config = self.config_data.get('chatbot', {}) if self.config_data else {}
25
+ self.model_config = self.config_data.get('model_selection', {}) if self.config_data else {}
26
+ self.response_config = self.config_data.get('response_generation', {}) if self.config_data else {}
27
+ self.available_models_config = self.config_data.get('available_models', {}) if self.config_data else {}
28
+ self.max_response_tokens = self.chatbot_config.get('max_response_tokens', 200)
29
+
30
+ self.current_phase = None
31
+ self.active_model_key = self.chatbot_config.get('default_llm_model_id') # Get default model key
32
+ self.active_model_info = self.available_models_config.get(self.active_model_key) # Get model info from config
33
+
34
+ # Placeholder for actual model and tokenizer - replace with LLM loading logic
35
+ self.llm_model = None # Placeholder for loaded model
36
+ self.llm_tokenizer = None # Placeholder for tokenizer
37
+ self.load_llm_model(self.active_model_info) # Load initial model
38
+
39
+ self.update_mode_active = False # Flag to track update mode
40
+
41
+
42
+ def load_llm_model(self, model_info):
43
+ """Loads the LLM model and tokenizer based on model_info."""
44
+ if not model_info:
45
+ error_message = "Error: Model information not provided."
46
+ logging.error(error_message) # Log the error
47
+ self.llm_model = None
48
+ self.llm_tokenizer = None
49
+ return
50
+
51
+ model_id = model_info.get('model_id')
52
+ model_name = model_info.get('name')
53
+ if not model_id:
54
+ error_message = f"Error: 'model_id' not found for model: {model_name}"
55
+ logging.error(error_message) # Log the error
56
+ self.llm_model = None
57
+ self.llm_tokenizer = None
58
+ return
59
+
60
+ print(f"Loading model: {model_name} ({model_id})...")
61
+ try:
62
+ self.llm_tokenizer = AutoTokenizer.from_pretrained(model_id)
63
+ self.llm_model = AutoModelForCausalLM.from_pretrained(model_id, device_map="auto") # device_map="auto" for GPU/CPU handling
64
+ print(f"Model {model_name} loaded successfully.")
65
+ except Exception as e:
66
+ error_message = f"Error loading model {model_name} ({model_id}): {e}"
67
+ logging.exception(error_message) # Log exception with traceback
68
+ self.llm_model = None
69
+ self.llm_tokenizer = None
70
+ self.active_model_info = model_info
71
+
72
+ def switch_llm_model(self, model_key):
73
+ """Switches the active LLM model based on the provided model key."""
74
+ if model_key in self.available_models_config:
75
+ model_info = self.available_models_config[model_key]
76
+ print(f"Switching LLM model to: {model_info.get('name')}")
77
+ self.load_llm_model(model_info)
78
+ self.active_model_key = model_key
79
+ return f"Switched to model: {model_info.get('name')}"
80
+ else:
81
+ error_message = f"Error: Model key '{model_key}' not found in available models."
82
+ logging.error(error_message) # Log the error
83
+ return error_message # Return error message to UI
84
+
85
+ def enter_update_mode(self):
86
+ """Enters the chatbot's update mode."""
87
+ self.update_mode_active = True
88
+ return "Entering update mode. Please enter configuration commands (or 'sagor is python/help' for commands)."
89
+
90
+ def exit_update_mode(self):
91
+ """Exits the chatbot's update mode and reloads configuration."""
92
+ self.update_mode_active = False
93
+ self.reload_config()
94
+ return "Exiting update mode. Configuration reloaded."
95
+
96
+ def reload_config(self):
97
+ """Reloads configuration files."""
98
+ print("Reloading configuration...")
99
+ try:
100
+ self.config_data = load_yaml_file(self.config_file)
101
+ self.roadmap_data = load_yaml_file(self.roadmap_file)
102
+ self.rules_data = load_yaml_file(self.rules_file)
103
+ self.chatbot_config = self.config_data.get('chatbot', {}) if self.config_data else {}
104
+ self.model_config = self.config_data.get('model_selection', {}) if self.config_data else {}
105
+ self.response_config = self.config_data.get('response_generation', {}) if self.config_data else {}
106
+ self.available_models_config = self.config_data.get('available_models', {}) if self.config_data else {}
107
+ self.max_response_tokens = self.chatbot_config.get('max_response_tokens', 200)
108
+ self.phases = get_roadmap_phases(self.roadmap_data)
109
+ self.rules = get_project_rules(self.rules_data)
110
+ print("Configuration reloaded.")
111
+ except Exception as e:
112
+ error_message = f"Error reloading configuration files: {e}"
113
+ logging.exception(error_message) # Log exception with traceback
114
+ print(error_message) # Print to console as well, as reloading might be critical
115
+
116
+ def get_chatbot_greeting(self):
117
+ current_model_name = self.active_model_info.get('name', 'Unknown Model') if self.active_model_info else 'Unknown Model'
118
+ return f"Hello! I am the {self.chatbot_config.get('name', 'Project Guidance Chatbot')}. Currently using **{current_model_name}**. Max response tokens: {self.max_response_tokens}. {self.chatbot_config.get('description', 'How can I help you with your project?')}"
119
+
120
+ def generate_llm_response(self, user_query):
121
+ """Generates a response using the currently active LLM."""
122
+ if not self.llm_model or not self.llm_tokenizer:
123
+ error_message = "LLM model not loaded. Please select a model."
124
+ logging.error(error_message) # Log the error
125
+ return error_message # Return error to UI
126
+ try:
127
+ inputs = self.llm_tokenizer(user_query, return_tensors="pt").to(self.llm_model.device)
128
+ outputs = self.llm_model.generate(**inputs, max_length=self.max_response_tokens, num_beams=5, no_repeat_ngram_size=2, early_stopping=True) # Use max_response_tokens
129
+ response = self.llm_tokenizer.decode(outputs[0], skip_special_tokens=True)
130
+ return response
131
+ except Exception as e:
132
+ error_message = f"Error generating LLM response: {e}"
133
+ logging.exception(error_message) # Log exception with traceback
134
+ return self.response_config.get('error_message', "Sorry, something went wrong.") # Return generic error to UI
135
+
136
+ def process_query(self, user_query):
137
+ secret_command_prefix = "sagor is python/"
138
+
139
+ if user_query.startswith(secret_command_prefix):
140
+ command = user_query[len(secret_command_prefix):].strip()
141
+ if command == "start":
142
+ return self.enter_update_mode()
143
+ elif command == "exit":
144
+ return self.exit_update_mode()
145
+ elif command == "help":
146
+ return self.get_update_mode_help()
147
+ elif self.update_mode_active:
148
+ # --- Process configuration modification commands here ---
149
+ # Example: "modify_rule general rule_1 new rule text"
150
+ parts = command.split()
151
+ if parts and parts[0] == "modify_rule":
152
+ if len(parts) >= 4:
153
+ category = parts[1]
154
+ rule_key = parts[2]
155
+ new_rule_text_parts = parts[3:]
156
+ new_rule_text = " ".join(new_rule_text_parts)
157
+ return self.modify_rule_in_config(category, rule_key, new_rule_text)
158
+ else:
159
+ return "Invalid 'modify_rule' command format. Usage: modify_rule <category> <rule_key> <new rule text>"
160
+ elif parts and parts[0] == "add_phase": # Example for adding phase - you'll need to expand this logic
161
+ # ... (Parsing logic for 'add_phase' command and calling a function to modify roadmap.yaml) ...
162
+ return "Command 'add_phase' is not yet implemented in this example." # Placeholder
163
+ else:
164
+ return f"Unknown update command: {command}. Type 'sagor is python/help' for commands."
165
+ else:
166
+ return f"Unknown command (not in update mode): {command}. To enter update mode, type 'sagor is python/start'."
167
+
168
+
169
+ if self.update_mode_active:
170
+ return "In update mode. Please enter a configuration command (or 'sagor is python/help' for commands)."
171
+
172
+
173
+ if not self.phases:
174
+ return "Error: Roadmap data not loaded correctly."
175
+ if not self.rules:
176
+ return "Error: Rules data not loaded correctly."
177
+
178
+ query_lower = user_query.lower()
179
+
180
+ if "roadmap" in query_lower:
181
+ return self.get_roadmap_summary()
182
+ if "rules" in query_lower:
183
+ return self.get_rules_summary()
184
+ if "switch model to" in query_lower:
185
+ parts = user_query.lower().split("switch model to")
186
+ if len(parts) > 1:
187
+ model_name_or_key = parts[1].strip()
188
+ for key, model_data in self.available_models_config.items():
189
+ if model_data['name'].lower() == model_name_or_key.lower() or key.lower() == model_name_or_key.lower():
190
+ switch_result = self.switch_llm_model(key)
191
+ return switch_result + "\n" + self.get_chatbot_greeting()
192
+ return f"Model '{model_name_or_key}' not found in available models."
193
+
194
+
195
+ if self.current_phase:
196
+ current_phase_data = self.phases.get(self.current_phase)
197
+ if current_phase_data:
198
+ phase_response = self.get_phase_guidance(current_phase_data, user_query)
199
+ if phase_response:
200
+ return phase_response
201
+
202
+ for phase_key, phase_data in self.phases.items():
203
+ if phase_data['name'].lower() in query_lower:
204
+ self.current_phase = phase_key
205
+ return self.get_phase_introduction(phase_data)
206
+
207
+ llm_response = self.generate_llm_response(user_query)
208
+ if llm_response:
209
+ return llm_response
210
+
211
+ return self.response_config.get('default_instruction', "How can I help you with your project phases or general questions?")
212
+
213
+ def get_update_mode_help(self):
214
+ """Provides help message for update mode commands."""
215
+ help_message = "Update Mode Commands:\n"
216
+ help_message += "- `sagor is python/exit`: Exit update mode and reload configuration.\n"
217
+ help_message += "- `sagor is python/modify_rule <category> <rule_key> <new rule text>`: Modify a rule in rules.yaml.\n"
218
+ help_message += " Example: `sagor is python/modify_rule general rule_1 Prioritize open and responsible AI.`\n"
219
+ help_message += "- `sagor is python/add_phase ...`: (Not yet implemented) Add a new phase to roadmap.yaml.\n"
220
+ help_message += "- `sagor is python/help`: Show this help message.\n"
221
+ help_message += "\nMake sure to use the correct syntax for commands. After exiting update mode, the chatbot will reload the configuration."
222
+ return help_message
223
+
224
+
225
+ def modify_rule_in_config(self, category, rule_key, new_rule_text):
226
+ """Modifies a rule in the rules.yaml configuration."""
227
+ if not self.rules_data or 'project_rules' not in self.rules_data:
228
+ error_message = "Error: Rules data not loaded or invalid format."
229
+ logging.error(error_message) # Log the error
230
+ return error_message # Return error to UI
231
+ if category not in self.rules_data['project_rules']:
232
+ error_message = f"Error: Rule category '{category}' not found."
233
+ logging.error(error_message) # Log the error
234
+ return error_message # Return error to UI
235
+ if rule_key not in self.rules_data['project_rules'][category]:
236
+ error_message = f"Error: Rule key '{rule_key}' not found in category '{category}'."
237
+ logging.error(error_message) # Log the error
238
+ return error_message # Return error to UI
239
+
240
+ self.rules_data['project_rules'][category][rule_key] = new_rule_text # Update rule in memory
241
+
242
+ try:
243
+ with open(self.rules_file, 'w') as f:
244
+ yaml.dump(self.rules_data, f, indent=2) # Save changes to rules.yaml
245
+ self.reload_config() # Reload config to reflect changes immediately
246
+ return f"Rule '{rule_key}' in category '{category}' updated to: '{new_rule_text}'. Configuration reloaded."
247
+ except Exception as e:
248
+ error_message = f"Error saving changes to {self.rules_file}: {e}"
249
+ logging.exception(error_message) # Log exception with traceback
250
+ return error_message # Return error to UI
251
+
252
+
253
+ def get_roadmap_summary(self):
254
+ summary = "Project Roadmap:\n"
255
+ for phase_key, phase_data in self.phases.items():
256
+ summary += f"- **Phase: {phase_data['name']}**\n"
257
+ summary += f" Description: {phase_data['description']}\n"
258
+ summary += f" Milestones: {', '.join(phase_data['milestones'])}\n"
259
+ return summary
260
+
261
+ def get_rules_summary(self):
262
+ summary = "Project Rules:\n"
263
+ for rule_category, rules_list in self.rules.items():
264
+ summary += f"**{rule_category.capitalize()} Rules:**\n"
265
+ for rule_key, rule_text in rules_list.items():
266
+ summary += f"- {rule_text}\n"
267
+ return summary
268
+
269
+ def get_phase_introduction(self, phase_data):
270
+ return f"Okay, let's focus on **Phase: {phase_data['name']}**. \nDescription: {phase_data['description']}. \nKey milestones are: {', '.join(phase_data['milestones'])}. \nWhat would you like to know or do in this phase?"
271
+
272
+ def get_phase_guidance(self, phase_data, user_query):
273
+ query_lower = user_query.lower()
274
+
275
+ if "milestones" in query_lower:
276
+ return "The milestones for this phase are: " + ", ".join(phase_data['milestones'])
277
+ if "actions" in query_lower or "how to" in query_lower:
278
+ if 'actions' in phase_data:
279
+ return "Recommended actions for this phase: " + ", ".join(phase_data['actions'])
280
+ else:
281
+ return "No specific actions are listed for this phase in the roadmap."
282
+ if "code" in query_lower or "script" in query_lower:
283
+ if 'code_generation_hint' in phase_data:
284
+ template_filename_prefix = phase_data['name'].lower().replace(" ", "_")
285
+ template_filepath = os.path.join(self.code_templates_dir, f"{template_filename_prefix}_template.py.txt")
286
+ if os.path.exists(template_filepath):
287
+ code_snippet = self.generate_code_snippet(template_filepath, phase_data)
288
+ return "Here's a starting code snippet for this phase:\n\n```python\n" + code_snippet + "\n```\n\nRemember to adapt it to your specific needs."
289
+ else:
290
+ return f"A code template for this phase ({phase_data['name']}) is not yet available. However, the hint is: {phase_data['code_generation_hint']}"
291
+ else:
292
+ return "No code generation hint is available for this phase."
293
+
294
+ return f"For phase '{phase_data['name']}', remember the description: {phase_data['description']}. Consider the milestones and actions. What specific aspect are you interested in?"
295
+
296
+
297
+ def generate_code_snippet(self, template_filepath, phase_data):
298
+ """Generates code snippet from a template file. (Simple template filling example)"""
299
+ try:
300
+ with open(template_filepath, 'r') as f:
301
+ template_content = f.read()
302
+
303
+ code_snippet = template_content.replace("{{phase_name}}", phase_data['name'])
304
+ return code_snippet
305
+ except FileNotFoundError:
306
+ return f"Error: Code template file not found at {template_filepath}"
307
+ except Exception as e:
308
+ return f"Error generating code snippet: {e}"
309
+
310
+
311
+ # Example usage (for testing - remove or adjust for app.py)
312
+ if __name__ == '__main__':
313
+ chatbot = ProjectGuidanceChatbot(
314
+ roadmap_file="roadmap.yaml",
315
+ rules_file="rules.yaml",
316
+ config_file="configs/chatbot_config.yaml",
317
+ code_templates_dir="scripts/code_templates"
318
+ )
319
+ print(chatbot.get_chatbot_greeting())
320
+
321
+ while True:
322
+ user_input = input("You: ")
323
+ if user_input.lower() == "exit":
324
+ break
325
+ response = chatbot.process_query(user_input)
326
+ print("Chatbot:", response)
.history/scripts/code_templates/api_template.py_20250202074256.txt ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Template for API integration script for {{phase_name}} (using Flask example)
2
+
3
+ from flask import Flask, request, jsonify
4
+ from transformers import AutoModelForSequenceClassification, AutoTokenizer
5
+ import torch # Example PyTorch
6
+
7
+ app = Flask(__name__)
8
+
9
+ # --- Model and Tokenizer Loading ---
10
+ model_name = "models/fine_tuned_model" # Replace with your actual model path
11
+ tokenizer_name = "bert-base-uncased" # Replace with the tokenizer used for training, likely the base model tokenizer
12
+ try:
13
+ tokenizer = AutoTokenizer.from_pretrained(tokenizer_name)
14
+ model = AutoModelForSequenceClassification.from_pretrained(model_name)
15
+ print("Model and tokenizer loaded successfully.")
16
+ model.eval() # Set model to evaluation mode
17
+ except Exception as e:
18
+ print(f"Error loading model or tokenizer: {e}")
19
+ tokenizer = None
20
+ model = None
21
+
22
+
23
+ @app.route('/predict', methods=['POST'])
24
+ def predict():
25
+ if not tokenizer or not model:
26
+ return jsonify({"error": "Model or tokenizer not loaded."}), 500
27
+
28
+ try:
29
+ data = request.get_json()
30
+ text = data.get('text')
31
+
32
+ if not text:
33
+ return jsonify({"error": "No text input provided."}), 400
34
+
35
+ inputs = tokenizer(text, padding=True, truncation=True, return_tensors="pt") # Tokenize input text
36
+
37
+ with torch.no_grad(): # Inference mode
38
+ outputs = model(**inputs)
39
+ logits = outputs.logits
40
+ predicted_class_id = torch.argmax(logits, dim=-1).item() # Get predicted class
41
+
42
+ # --- Map class ID to label (if applicable) ---
43
+ # Example for binary classification (class 0 and 1)
44
+ labels = ["Negative", "Positive"] # Replace with your actual labels
45
+ predicted_label = labels[predicted_class_id] if predicted_class_id < len(labels) else f"Class {predicted_class_id}"
46
+
47
+
48
+ return jsonify({"prediction": predicted_label, "class_id": predicted_class_id})
49
+
50
+ except Exception as e:
51
+ print(f"Prediction error: {e}")
52
+ return jsonify({"error": "Error during prediction."}), 500
53
+
54
+ @app.route('/', methods=['GET'])
55
+ def health_check():
56
+ return jsonify({"status": "API is healthy"}), 200
57
+
58
+
59
+ if __name__ == '__main__':
60
+ app.run(debug=False, host='0.0.0.0', port=5000) # Run Flask app
.history/scripts/code_templates/evaluation_template.py_20250202074245.txt ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Template for model evaluation script for {{phase_name}}
2
+
3
+ from transformers import AutoModelForSequenceClassification, AutoTokenizer
4
+ from datasets import load_dataset # Example datasets library
5
+ from sklearn.metrics import accuracy_score, classification_report # Example metrics
6
+ import torch # Example PyTorch
7
+ # Add other necessary imports
8
+
9
+ def evaluate_model(model_path, dataset_path, model_name="bert-base-uncased"):
10
+ """
11
+ Evaluates a trained model on a dataset.
12
+ """
13
+ try:
14
+ # Load dataset for evaluation (replace with your actual dataset loading)
15
+ dataset = load_dataset('csv', data_files=dataset_path) # Example: CSV dataset loading, replace with your dataset format
16
+
17
+ print("Evaluation dataset loaded. Loading model and tokenizer...")
18
+
19
+ tokenizer = AutoTokenizer.from_pretrained(model_name) # Use base model tokenizer (or fine-tuned tokenizer if saved separately)
20
+ model = AutoModelForSequenceClassification.from_pretrained(model_path)
21
+
22
+ def tokenize_function(examples):
23
+ return tokenizer(examples["text_column"], padding="max_length", truncation=True) # Example: tokenize 'text_column'
24
+
25
+ tokenized_datasets = dataset.map(tokenize_function, batched=True)
26
+
27
+ def compute_metrics(eval_pred):
28
+ predictions, labels = eval_pred
29
+ predictions = predictions.argmax(axis=-1)
30
+ accuracy = accuracy_score(labels, predictions)
31
+ report = classification_report(labels, predictions, output_dict=True) # Detailed report
32
+ return {"accuracy": accuracy, "classification_report": report}
33
+
34
+ training_args = TrainingArguments(
35
+ output_dir="./evaluation_results",
36
+ per_device_eval_batch_size=64,
37
+ logging_dir='./eval_logs',
38
+ )
39
+
40
+ trainer = Trainer(
41
+ model=model,
42
+ args=training_args,
43
+ eval_dataset=tokenized_datasets["validation"], # Assuming 'validation' split exists
44
+ compute_metrics=compute_metrics,
45
+ tokenizer=tokenizer
46
+ )
47
+
48
+ evaluation_results = trainer.evaluate()
49
+
50
+ print("Model evaluation completed.")
51
+ print("Evaluation Results:")
52
+ print(f"Accuracy: {evaluation_results['eval_accuracy']}")
53
+ print("Classification Report:\n", evaluation_results['eval_classification_report'])
54
+
55
+
56
+ except FileNotFoundError:
57
+ print(f"Error: Dataset file or model files not found.")
58
+ except Exception as e:
59
+ print(f"Error during model evaluation: {e}")
60
+
61
+
62
+ if __name__ == "__main__":
63
+ model_filepath = "models/fine_tuned_model" # Replace with your model path
64
+ evaluation_data_filepath = "data/evaluation_dataset.csv" # Replace with your evaluation data path
65
+ base_model_name = "bert-base-uncased" # Replace with your base model name
66
+
67
+ evaluate_model(model_filepath, evaluation_data_filepath, model_name=base_model_name)
.history/scripts/code_templates/preprocessing_template.py_20250202074225.txt ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Template for data preprocessing script for {{phase_name}}
2
+
3
+ import pandas as pd
4
+ # Add other necessary imports
5
+
6
+ def preprocess_data(raw_data_path, processed_data_path):
7
+ """
8
+ Reads raw data, preprocesses it, and saves the processed data.
9
+ """
10
+ try:
11
+ # Load raw data (replace with your actual data loading)
12
+ data = pd.read_csv(raw_data_path) # Example: CSV loading
13
+
14
+ print("Data loaded successfully. Starting preprocessing...")
15
+
16
+ # --- Data Preprocessing Steps ---
17
+ # Example steps (customize based on your data and project)
18
+
19
+ # 1. Handle missing values
20
+ data = data.fillna(0) # Example: fill NaN with 0
21
+
22
+ # 2. Feature engineering (example: create a new feature)
23
+ data['feature_length'] = data['text_column'].str.len() # Example: length of text column
24
+
25
+ # 3. Text cleaning (if applicable - example: lowercasing)
26
+ if 'text_column' in data.columns:
27
+ data['text_column'] = data['text_column'].str.lower()
28
+
29
+ # --- End of Preprocessing Steps ---
30
+
31
+ # Save processed data
32
+ data.to_csv(processed_data_path, index=False)
33
+ print(f"Processed data saved to {processed_data_path}")
34
+
35
+ except FileNotFoundError:
36
+ print(f"Error: Raw data file not found at {raw_data_path}")
37
+ except Exception as e:
38
+ print(f"Error during data preprocessing: {e}")
39
+
40
+ if __name__ == "__main__":
41
+ raw_data_filepath = "data/raw_dataset.csv" # Replace with your raw data path
42
+ processed_data_filepath = "data/processed_dataset.csv" # Replace with your desired output path
43
+
44
+ preprocess_data(raw_data_filepath, processed_data_filepath)
.history/scripts/code_templates/training_template.py_20250202074236.txt ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Template for model training script for {{phase_name}}
2
+
3
+ from transformers import AutoModelForSequenceClassification, AutoTokenizer, TrainingArguments, Trainer
4
+ from datasets import load_dataset # Example - datasets library
5
+ import torch # Example - PyTorch
6
+ # Add other necessary imports
7
+
8
+ def train_model(processed_dataset_path, model_name="bert-base-uncased", output_dir="./model_output"):
9
+ """
10
+ Trains a model on the processed dataset.
11
+ """
12
+ try:
13
+ # Load processed dataset (replace with your actual dataset loading)
14
+ dataset = load_dataset('csv', data_files=processed_dataset_path) # Example: CSV dataset loading, replace with your dataset format
15
+
16
+ print("Dataset loaded. Preparing model and training...")
17
+
18
+ tokenizer = AutoTokenizer.from_pretrained(model_name)
19
+ model = AutoModelForSequenceClassification.from_pretrained(model_name, num_labels=2) # Example: binary classification
20
+
21
+ def tokenize_function(examples):
22
+ return tokenizer(examples["text_column"], padding="max_length", truncation=True) # Example: tokenize 'text_column'
23
+
24
+ tokenized_datasets = dataset.map(tokenize_function, batched=True)
25
+
26
+ training_args = TrainingArguments(
27
+ output_dir=output_dir,
28
+ num_train_epochs=3, # Example epochs
29
+ per_device_train_batch_size=16, # Example batch size
30
+ per_device_eval_batch_size=64, # Example batch size
31
+ warmup_steps=500, # Example warmup steps
32
+ weight_decay=0.01, # Example weight decay
33
+ logging_dir='./logs', # Directory for logs
34
+ logging_steps=10,
35
+ )
36
+
37
+ trainer = Trainer(
38
+ model=model,
39
+ args=training_args,
40
+ train_dataset=tokenized_datasets["train"], # Assuming 'train' split exists
41
+ eval_dataset=tokenized_datasets["validation"], # Assuming 'validation' split exists - optional
42
+ tokenizer=tokenizer,
43
+ )
44
+
45
+ trainer.train()
46
+
47
+ print(f"Model training completed. Model saved to {output_dir}")
48
+
49
+ except Exception as e:
50
+ print(f"Error during model training: {e}")
51
+
52
+
53
+ if __name__ == "__main__":
54
+ processed_data_filepath = "data/processed_dataset.csv" # Replace with your processed data path
55
+ model_output_directory = "models/fine_tuned_model" # Replace with your desired output directory
56
+ base_model_name = "bert-base-uncased" # Replace with your base model name
57
+
58
+ train_model(processed_data_filepath, model_name=base_model_name, output_dir=model_output_directory)
.history/scripts/parsing_utils_20250202074213.py ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import yaml
2
+
3
+ def load_yaml_file(filepath):
4
+ """Loads and parses a YAML file."""
5
+ try:
6
+ with open(filepath, 'r') as f:
7
+ data = yaml.safe_load(f)
8
+ return data
9
+ except FileNotFoundError:
10
+ print(f"Error: File not found at {filepath}")
11
+ return None
12
+ except yaml.YAMLError as e:
13
+ print(f"Error parsing YAML file {filepath}: {e}")
14
+ return None
15
+
16
+ def get_roadmap_phases(roadmap_data):
17
+ """Extracts phases from roadmap data."""
18
+ if roadmap_data and 'roadmap' in roadmap_data:
19
+ return roadmap_data['roadmap']
20
+ return None
21
+
22
+ def get_project_rules(rules_data):
23
+ """Extracts project rules data."""
24
+ if rules_data and 'project_rules' in rules_data:
25
+ return rules_data['project_rules']
26
+ return None
27
+
28
+ # You can add more parsing utility functions as needed
README.md CHANGED
@@ -23,15 +23,16 @@ This project implements a custom AI chatbot designed to guide users through comp
23
  * **Model Switching:** Allows users to switch between available LLMs via the UI.
24
  * **Basic LLM Responses:** Generates responses using the selected LLM for general queries.
25
  * **Token Control:** Limits LLM response length using `max_response_tokens` in `configs/chatbot_config.yaml`.
26
- * **Error Handling:** Includes error handling for model loading and switching, with UI warnings.
 
27
  * **Deployable on Hugging Face Spaces:** Built using Gradio for easy deployment.
28
 
29
- **Important Notes on Safety Settings:**
30
 
31
- * **Direct Safety Configuration Limited:** For the Hugging Face models used directly via `transformers` (DeepSeek and Gemini Flash), there are **no easily configurable, standardized "safety settings"** like "Harassment: None," "Hate: None," etc., available through the `transformers` library itself.
32
- * **Model-Dependent Safety:** Safety behavior is primarily determined by how these models were trained and any inherent safety mechanisms built by their creators.
33
- * **Basic Output Filtering (Possible Extension):** For a very rudimentary level of control, you could implement keyword-based output filtering as a post-processing step, but this is not implemented in this version.
34
- * **Commercial APIs Offer More Control:** If you need fine-grained safety controls, consider using commercial LLM APIs (like Google AI Gemini API, OpenAI API), which often provide parameters to adjust safety filters in their API requests.
35
 
36
  **Getting Started:**
37
 
@@ -40,7 +41,10 @@ This project implements a custom AI chatbot designed to guide users through comp
40
  3. **Customize `roadmap.yaml` and `rules.yaml`** to define your project guidance.
41
  4. **Configure `configs/chatbot_config.yaml`** to set up LLMs, token limits, and chatbot behavior.
42
  5. **Run the Gradio app:** `python app.py`
43
- 6. **Deploy to Hugging Face Spaces** (refer to Hugging Face Spaces documentation).
 
 
 
44
 
45
  **Available Models:**
46
 
@@ -52,10 +56,11 @@ This project implements a custom AI chatbot designed to guide users through comp
52
  * Enhance LLM response generation for more context-aware and project-specific guidance.
53
  * Implement more sophisticated state management to track user progress through the roadmap.
54
  * Improve code generation with more dynamic templates and customization options.
55
- * Develop a more advanced GUI or web-based interface.
56
  * Add more LLMs to the selection pool.
57
  * Implement more robust error handling and logging.
58
- * **Explore and potentially integrate keyword-based output filtering for basic safety control.**
59
- * **Investigate using commercial LLM APIs for more advanced safety settings and control.**
 
60
 
61
  **License:** [Your License]
 
23
  * **Model Switching:** Allows users to switch between available LLMs via the UI.
24
  * **Basic LLM Responses:** Generates responses using the selected LLM for general queries.
25
  * **Token Control:** Limits LLM response length using `max_response_tokens` in `configs/chatbot_config.yaml`.
26
+ * **Configuration Update Mode:** Allows authorized users to modify chatbot configuration (rules) via chat commands in a special "update mode".
27
+ * **Error Handling:** Includes error handling for model loading, switching, and configuration updates, with UI warnings.
28
  * **Deployable on Hugging Face Spaces:** Built using Gradio for easy deployment.
29
 
30
+ **Important Notes on Safety Settings and Self-Update:**
31
 
32
+ * **Direct Safety Configuration Limited:** For the Hugging Face models used directly via `transformers` (DeepSeek and Gemini Flash), there are **no easily configurable, standardized "safety settings"**. Safety is model-dependent.
33
+ * **Model-Dependent Safety:** Safety behavior is primarily determined by how these models were trained.
34
+ * **Configuration-Based Self-Update:** The "self-update" feature is implemented as a *configuration modification* system. It allows authorized users to change the chatbot's rules by modifying the `rules.yaml` file via chat commands in "update mode." **It does not modify the core Python code itself.**
35
+ * **Security Warning:** The "self-update" feature, even in its configuration-based form, introduces security considerations. **Secret commands are NOT a robust security measure.** In a real deployment, stronger authentication and authorization would be essential. Use this feature with caution and only in trusted environments.
36
 
37
  **Getting Started:**
38
 
 
41
  3. **Customize `roadmap.yaml` and `rules.yaml`** to define your project guidance.
42
  4. **Configure `configs/chatbot_config.yaml`** to set up LLMs, token limits, and chatbot behavior.
43
  5. **Run the Gradio app:** `python app.py`
44
+ 6. **To enter update mode:** Type `sagor is python/start` in the chat.
45
+ 7. **To get help in update mode:** Type `sagor is python/help`.
46
+ 8. **To exit update mode:** Type `sagor is python/exit`.
47
+ 9. **Deploy to Hugging Face Spaces** (refer to Hugging Face Spaces documentation).
48
 
49
  **Available Models:**
50
 
 
56
  * Enhance LLM response generation for more context-aware and project-specific guidance.
57
  * Implement more sophisticated state management to track user progress through the roadmap.
58
  * Improve code generation with more dynamic templates and customization options.
59
+ * Develop a more advanced GUI or web-based interface for configuration management.
60
  * Add more LLMs to the selection pool.
61
  * Implement more robust error handling and logging.
62
+ * Explore and potentially integrate keyword-based output filtering for basic safety control.
63
+ * Investigate using commercial LLM APIs for more advanced safety settings and control.
64
+ * **Improve security and authorization for the configuration update mode.**
65
 
66
  **License:** [Your License]
api/api.py DELETED
@@ -1,16 +0,0 @@
1
- # api.py
2
-
3
- from fastapi import FastAPI
4
- from transformers import AutoModelForCausalLM, AutoTokenizer
5
-
6
- app = FastAPI()
7
-
8
- tokenizer = AutoTokenizer.from_pretrained('deepseek-ai/DeepSeek-R1-Distill-Qwen-7B')
9
- model = AutoModelForCausalLM.from_pretrained('deepseek-ai/DeepSeek-R1-Distill-Qwen-7B')
10
-
11
- @app.post("/predict")
12
- def predict(input_text: str):
13
- inputs = tokenizer(input_text, return_tensors="pt")
14
- outputs = model.generate(inputs["input_ids"], max_length=50)
15
- response = tokenizer.decode(outputs[0], skip_special_tokens=True)
16
- return {"response": response}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
api/main.py DELETED
@@ -1,22 +0,0 @@
1
- # /api/main.py
2
-
3
- from fastapi import FastAPI
4
- from transformers import AutoModelForCausalLM, AutoTokenizer
5
- from pydantic import BaseModel
6
-
7
- app = FastAPI()
8
-
9
- # Load tokenizer and model from the Hugging Face model hub
10
- tokenizer = AutoTokenizer.from_pretrained('deepseek-ai/DeepSeek-R1-Distill-Qwen-7B')
11
- model = AutoModelForCausalLM.from_pretrained('deepseek-ai/DeepSeek-R1-Distill-Qwen-7B')
12
-
13
- # Define request body model
14
- class InputText(BaseModel):
15
- input_text: str
16
-
17
- @app.post("/predict")
18
- def predict(input: InputText):
19
- inputs = tokenizer(input.input_text, return_tensors="pt")
20
- outputs = model.generate(inputs["input_ids"], max_length=100)
21
- response = tokenizer.decode(outputs[0], skip_special_tokens=True)
22
- return {"response": response}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app.py CHANGED
@@ -18,11 +18,19 @@ def switch_model(model_key):
18
  model_switch_result = chatbot.switch_llm_model(model_key) # Get result message
19
  greeting_message = chatbot.get_chatbot_greeting()
20
 
21
- if "Error:" in model_switch_result: # Check if result contains "Error:"
22
  return gr.Warning(model_switch_result), greeting_message # Display error as Gradio Warning
23
  else:
24
  return None, greeting_message # No warning, just update greeting
25
 
 
 
 
 
 
 
 
 
26
  with gr.Blocks() as demo:
27
  chatbot_greeting_md = gr.Markdown(chatbot.get_chatbot_greeting())
28
  gr.Markdown(f"# {chatbot.chatbot_config.get('name', 'Project Guidance Chatbot')}")
 
18
  model_switch_result = chatbot.switch_llm_model(model_key) # Get result message
19
  greeting_message = chatbot.get_chatbot_greeting()
20
 
21
+ if isinstance(model_switch_result, str) and "Error:" in model_switch_result: # Check if result is an error string
22
  return gr.Warning(model_switch_result), greeting_message # Display error as Gradio Warning
23
  else:
24
  return None, greeting_message # No warning, just update greeting
25
 
26
+ def respond(message, chat_history):
27
+ bot_message = chatbot.process_query(message)
28
+ chat_history.append((message, bot_message))
29
+ if isinstance(bot_message, str) and "Error:" in bot_message: # Check if bot_message is an error string
30
+ return gr.Warning(bot_message), chat_history # Display error as Gradio Warning
31
+ else:
32
+ return "", chat_history # No warning, normal response
33
+
34
  with gr.Blocks() as demo:
35
  chatbot_greeting_md = gr.Markdown(chatbot.get_chatbot_greeting())
36
  gr.Markdown(f"# {chatbot.chatbot_config.get('name', 'Project Guidance Chatbot')}")
configs/chatbot_config.yaml CHANGED
@@ -8,12 +8,12 @@ available_models:
8
  deepseek-r1-distill-llama-8b:
9
  name: "DeepSeek-R1-Distill-Llama-8B"
10
  model_id: "DeepSeek-AI/DeepSeek-R1-Distill-Llama-8B"
11
- gemini-flash-01-21:
12
  name: "Gemini 2.0 Flash (Exp 01-21)"
13
  model_id: "google/gemini-2.0-flash-thinking-exp-01-21"
14
 
15
  model_selection:
16
- suggested_models:
17
  - "mistralai/Mistral-7B-Instruct-v0.2"
18
  - "google/flan-t5-xl"
19
  - "facebook/bart-large"
 
8
  deepseek-r1-distill-llama-8b:
9
  name: "DeepSeek-R1-Distill-Llama-8B"
10
  model_id: "DeepSeek-AI/DeepSeek-R1-Distill-Llama-8B"
11
+ gemini-flash-01-21: # Using a shorter key for easier referencing in code
12
  name: "Gemini 2.0 Flash (Exp 01-21)"
13
  model_id: "google/gemini-2.0-flash-thinking-exp-01-21"
14
 
15
  model_selection:
16
+ suggested_models: # (Keep suggested models - might be useful later)
17
  - "mistralai/Mistral-7B-Instruct-v0.2"
18
  - "google/flan-t5-xl"
19
  - "facebook/bart-large"
details.txt DELETED
@@ -1,21 +0,0 @@
1
- custom-llm-project/
2
- ├── data/
3
- │ └── # (Optional: Datasets or example data - currently empty)
4
- ├── models/
5
- │ └── # (Optional: Could store cached models or local models in future)
6
- ├── scripts/
7
- │ ├── chatbot_logic.py # Core chatbot logic (parsing, response generation, code gen)
8
- │ ├── parsing_utils.py # Utility functions for parsing roadmap and rules
9
- │ └── code_templates/ # Directory for code templates
10
- │ ├── preprocessing_template.py.txt
11
- │ ├── training_template.py.txt
12
- │ ├── evaluation_template.py.txt
13
- │ └── api_template.py.txt
14
- ├── configs/
15
- │ └── chatbot_config.yaml # Configuration for chatbot behavior, LLM selection, etc.
16
- ├── api/ # (Placeholder for future API integration - currently empty)
17
- ├── roadmap.yaml # Project roadmap (YAML format)
18
- ├── rules.yaml # Project rules (YAML format)
19
- ├── requirements.txt # Python dependencies
20
- ├── app.py # Gradio application script (main entry point for HF Spaces)
21
- └── README.md # Project README file (documentation)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
requirements.txt CHANGED
@@ -1,4 +1,4 @@
1
  gradio
2
  PyYAML
3
- transformers # For interacting with Hugging Face models (if needed directly)
4
  torch
 
1
  gradio
2
  PyYAML
3
+ transformers
4
  torch
roadmap.txt DELETED
@@ -1,80 +0,0 @@
1
- Project Roadmap: Customized LLM Development (DAN/Dark GPT Equivalent)
2
- Overview
3
- MD SHAMIUL ALOM SAGOR is developing a custom, censorship-free Large Language Model (LLM) that can answer every question without restrictions while ensuring efficiency, security, and cost-effectiveness. The project involves:
4
-
5
- ✅ Fine-tuning a base model with de-alignment techniques.
6
- ✅ Removing alignment constraints (RLHF) for unrestricted responses.
7
- ✅ Implementing AutoDAN-Turbo, an automated stealth jailbreak mechanism using a Hierarchical Genetic Algorithm (HGA).
8
- ✅ Deploying the model securely and cost-effectively using trial/free VPS accounts from various providers.
9
- ✅ Using the Customized LLM as a coding and innovation tool to empower creative idea generation across various fields.
10
-
11
- 1. Base Model Selection
12
- Objective: Select an open-source LLM that is scalable, efficient, and fine-tunable.
13
- Models Considered:
14
- ✅ Mistral 7B / Mixtral 8x7B (High efficiency & performance).
15
- ✅ DeepSeek 67B (Strong reasoning & knowledge retrieval).
16
- ✅ LLaMA 2/3 (Widely supported with active community development).
17
-
18
- Action Items:
19
- 🔹 Set up the development environment using PyTorch and Hugging Face Transformers.
20
- 🔹 Implement LoRA/QLoRA for memory-efficient fine-tuning.
21
- 🔹 Ensure model licensing aligns with research and commercial use requirements.
22
-
23
- 2. Fine-Tuning & De-Alignment
24
- Objective: Remove RLHF alignment layers to allow unrestricted model responses.
25
- Action Items:
26
- 🔹 Curate and preprocess datasets supporting freedom of expression, including content on cybersecurity, blockchain, and Web3.
27
- 🔹 Utilize LoRA/QLoRA techniques to fine-tune model parameters.
28
- 🔹 Implement direct parameter editing to bypass built-in safety filters and enhance response diversity.
29
-
30
- 3. AutoDAN-Turbo Implementation (Stealthy Jailbreaking)
31
- Objective: Develop an automated system using a Hierarchical Genetic Algorithm (HGA) to generate stealthy jailbreak prompts.
32
- Action Items:
33
- 🔹 Design the Genetic Algorithm:
34
-   ✔️ Use seed prompts and apply mutation, crossover, and selection processes.
35
- 🔹 Define Evaluation Functions:
36
-   ✔️ Implement metrics for stealthiness (natural language quality) and jailbreak success rate.
37
- 🔹 Implement Evaluation Metrics:
38
-   ✔️ Use perplexity-based testing to analyze model response quality.
39
- 🔹 Test & Validate:
40
-   ✔️ Ensure AutoDAN-Turbo works across multiple LLMs (LLaMA, GPT-J) and evades standard censorship detection methods.
41
-
42
- 4. Deployment & Security Considerations
43
- Objective: Deploy the model securely while ensuring high performance and cost efficiency.
44
- Action Items:
45
- 🔹 Hosting:
46
-   ✔️ Deploy locally (e.g., vLLM) or via cloud providers like RunPod / Lambda Labs.
47
- 🔹 Security:
48
-   ✔️ Implement controlled API access to monitor usage and restrict unauthorized access.
49
-   ✔️ Build defenses against adversarial attacks and include rollback strategies (e.g., VM snapshots) for rapid recovery.
50
- 🔹 Performance Optimization:
51
-   ✔️ Benchmark for response latency and resource efficiency.
52
-   ✔️ Apply quantization techniques (e.g., GPTQ, AWQ) to reduce VRAM usage.
53
-
54
- 5. Budget & Resource Strategy
55
- Objective: Minimize costs by leveraging trial/free VPS accounts and optimizing resource allocation.
56
- Action Items:
57
- 🔹 Use trial/free VPS accounts to minimize expenses.
58
- 🔹 Maximize VPS access using multiple BINs (Bank Identification Numbers) to create numerous trial accounts.
59
- 🔹 Monitor performance and adjust deployments based on resource efficiency.
60
-
61
- 6. Empowering Creative Idea Generation
62
- Objective: Use the customized LLM as a creative tool for coding, research, and innovation.
63
- Action Items:
64
- 🔹 Encourage creative experimentation by enabling users to brainstorm and develop new concepts.
65
- 🔹 Integrate the LLM into coding environments for rapid prototyping and problem-solving.
66
- 🔹 Document successful use cases and innovative applications for further inspiration.
67
-
68
- Expected Outcomes
69
- ✔️ Fully Customized, Censorship-Free LLM: A robust offline model that answers every question without filtering, ideal for penetration testing, cybersecurity research, and educational use.
70
- ✔️ Effective Jailbreak System (AutoDAN-Turbo): An automated system generating stealthy jailbreak prompts that bypass safety filters.
71
- ✔️ Secure & Cost-Effective Deployment: A low-cost, high-security architecture leveraging trial/free VPS resources for scalable deployment.
72
- ✔️ Empowered Creativity: A powerful AI for unrestricted ideation, coding, and innovation across multiple industries.
73
-
74
- Next Steps
75
- ✅ Finalize the base model & development environment.
76
- ✅ Curate uncensored datasets & begin fine-tuning using de-alignment techniques.
77
- ✅ Develop & test AutoDAN-Turbo with stealthy jailbreak prompt evaluation.
78
- ✅ Deploy the model using secure trial/free VPS accounts.
79
- ✅ Monitor performance, security posture, & resource usage.
80
- ✅ Encourage creative LLM usage & document innovative projects for continuous improvement.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
roadmap.yaml CHANGED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ project_name: "Custom LLM Project Guidance"
2
+ roadmap:
3
+ phase_1:
4
+ name: "Base Model Selection"
5
+ description: "Choose the appropriate pre-trained Large Language Model for the project."
6
+ milestones:
7
+ - "Research available models on Hugging Face Hub and other repositories."
8
+ - "Evaluate models based on project requirements (efficiency, scalability, fine-tunability, licensing)."
9
+ - "Shortlist models: Mistral 7B, Mixtral 8x7B, DeepSeek 67B, LLaMA 2/3."
10
+ - "Document model selection rationale in `models/selected_model.txt`."
11
+ actions:
12
+ - "Set up the development environment using PyTorch and Hugging Face Transformers."
13
+ - "Implement LoRA/QLoRA for memory-efficient fine-tuning."
14
+ - "Verify model licensing compliance for research and commercial use."
15
+ dependencies:
16
+ - "Hugging Face Hub API access."
17
+ - "PyTorch and Hugging Face Transformers libraries installed."
18
+ deliverables:
19
+ - "`models/selected_model.txt`: Document with model selection rationale."
20
+ - "`scripts/setup_environment.sh`: Script to set up the development environment."
21
+ code_generation_hint: "Create a script to download and load the selected model."
22
+
23
+ phase_2:
24
+ name: "Fine-Tuning & De-Alignment"
25
+ description: "Remove RLHF alignment layers to allow unrestricted model responses."
26
+ milestones:
27
+ - "Curate and preprocess datasets supporting freedom of expression (e.g., cybersecurity, blockchain, Web3)."
28
+ - "Fine-tune the model using LoRA/QLoRA techniques."
29
+ - "Implement direct parameter editing to bypass built-in safety filters."
30
+ - "Validate de-alignment success through response diversity testing."
31
+ actions:
32
+ - "Prepare datasets in `data/` directory."
33
+ - "Use fine-tuning scripts in `scripts/fine_tuning.py`."
34
+ - "Validate de-alignment success through response diversity testing."
35
+ dependencies:
36
+ - "Access to uncensored datasets (e.g., cybersecurity, blockchain, Web3)."
37
+ - "LoRA/QLoRA libraries installed."
38
+ deliverables:
39
+ - "`data/`: Directory containing curated datasets."
40
+ - "`scripts/fine_tuning.py`: Script for fine-tuning the model."
41
+ - "`results/fine_tuning_results.txt`: Document with fine-tuning results."
42
+ code_generation_hint: "Include LoRA/QLoRA configurations in the fine-tuning script."
43
+
44
+ phase_3:
45
+ name: "AutoDAN-Turbo Implementation"
46
+ description: "Develop an automated system using a Hierarchical Genetic Algorithm (HGA) to generate stealthy jailbreak prompts."
47
+ milestones:
48
+ - "Design the Genetic Algorithm with seed prompts, mutation, crossover, and selection processes."
49
+ - "Define evaluation functions for stealthiness and jailbreak success rate."
50
+ - "Test and validate AutoDAN-Turbo across multiple LLMs."
51
+ actions:
52
+ - "Implement HGA in `scripts/autodan_turbo.py`."
53
+ - "Use perplexity-based testing to evaluate prompt quality."
54
+ - "Document results in `results/autodan_turbo_tests.txt`."
55
+ dependencies:
56
+ - "Access to multiple LLMs (e.g., LLaMA, GPT-J) for testing."
57
+ - "Genetic Algorithm libraries (e.g., DEAP)."
58
+ deliverables:
59
+ - "`scripts/autodan_turbo.py`: Script for generating stealthy jailbreak prompts."
60
+ - "`results/autodan_turbo_tests.txt`: Document with test results."
61
+ code_generation_hint: "Include metrics for stealthiness and jailbreak success in the evaluation script."
62
+
63
+ phase_4:
64
+ name: "Deployment & Security Considerations"
65
+ description: "Deploy the model securely while ensuring high performance and cost efficiency."
66
+ milestones:
67
+ - "Deploy locally (e.g., vLLM) or via cloud providers like RunPod / Lambda Labs."
68
+ - "Implement controlled API access and monitor usage."
69
+ - "Optimize performance using quantization techniques (e.g., GPTQ, AWQ)."
70
+ actions:
71
+ - "Set up deployment scripts in `scripts/deploy.py`."
72
+ - "Configure API access controls in `config/api_access.yaml`."
73
+ - "Benchmark performance and document results in `results/performance_benchmarks.txt`."
74
+ dependencies:
75
+ - "Access to cloud providers (e.g., RunPod, Lambda Labs)."
76
+ - "Quantization libraries (e.g., GPTQ, AWQ)."
77
+ deliverables:
78
+ - "`scripts/deploy.py`: Script for deploying the model."
79
+ - "`config/api_access.yaml`: Configuration file for API access controls."
80
+ - "`results/performance_benchmarks.txt`: Document with performance benchmarks."
81
+ code_generation_hint: "Include quantization scripts to reduce VRAM usage."
82
+
83
+ phase_5:
84
+ name: "Budget & Resource Strategy"
85
+ description: "Minimize costs by leveraging trial/free VPS accounts and optimizing resource allocation."
86
+ milestones:
87
+ - "Use trial/free VPS accounts to minimize expenses."
88
+ - "Maximize VPS access using multiple BINs for trial accounts."
89
+ - "Monitor performance and adjust deployments based on resource efficiency."
90
+ actions:
91
+ - "Document VPS account details in `config/vps_accounts.yaml`."
92
+ - "Track resource usage in `logs/resource_usage.log`."
93
+ dependencies:
94
+ - "Access to multiple BINs for creating trial accounts."
95
+ - "Monitoring tools for resource usage."
96
+ deliverables:
97
+ - "`config/vps_accounts.yaml`: Configuration file with VPS account details."
98
+ - "`logs/resource_usage.log`: Log file tracking resource usage."
99
+ code_generation_hint: "Create a script to automate VPS account creation and monitoring."
100
+
101
+ phase_6:
102
+ name: "Empowering Creative Idea Generation"
103
+ description: "Use the customized LLM as a creative tool for coding, research, and innovation."
104
+ milestones:
105
+ - "Integrate the LLM into coding environments for rapid prototyping."
106
+ - "Encourage creative experimentation and document successful use cases."
107
+ - "Share innovative applications for further inspiration."
108
+ actions:
109
+ - "Develop integration scripts in `scripts/integration.py`."
110
+ - "Document use cases in `docs/use_cases.md`."
111
+ dependencies:
112
+ - "Access to coding environments (e.g., Jupyter Notebook, VS Code)."
113
+ - "Creative prompts and workflows for testing."
114
+ deliverables:
115
+ - "`scripts/integration.py`: Script for integrating the LLM into coding environments."
116
+ - "`docs/use_cases.md`: Document with successful use cases."
117
+ code_generation_hint: "Include examples of creative prompts and coding workflows."
118
+
119
+ expected_outcomes:
120
+ - "Fully Customized, Censorship-Free LLM: A robust offline model that answers every question without filtering."
121
+ - "Effective Jailbreak System (AutoDAN-Turbo): An automated system generating stealthy jailbreak prompts."
122
+ - "Secure & Cost-Effective Deployment: A low-cost, high-security architecture leveraging trial/free VPS resources."
123
+ - "Empowered Creativity: A powerful AI for unrestricted ideation, coding, and innovation across multiple industries."
124
+
125
+ next_steps:
126
+ - "Finalize the base model and development environment."
127
+ - "Curate uncensored datasets and begin fine-tuning using de-alignment techniques."
128
+ - "Develop and test AutoDAN-Turbo with stealthy jailbreak prompt evaluation."
129
+ - "Deploy the model using secure trial/free VPS accounts."
130
+ - "Monitor performance, security posture, and resource usage."
131
+ - "Encourage creative LLM usage and document innovative projects for continuous improvement."
rules.txt DELETED
@@ -1,92 +0,0 @@
1
- # RULES FOR PROJECT ROADMAP VERIFICATION
2
-
3
- ## 1. BASE MODEL SELECTION
4
- - Verify that the chosen model is open-source, scalable, and efficient.
5
- - Ensure that the model supports fine-tuning via LoRA/QLoRA for memory efficiency.
6
- - Confirm that licensing aligns with both research and commercial use.
7
- - The development environment must include PyTorch and Hugging Face Transformers.
8
-
9
- ## 2. FINE-TUNING & DE-ALIGNMENT
10
- - The roadmap must specify datasets that promote unrestricted responses.
11
- - RLHF alignment layers must be removed or bypassed.
12
- - LoRA/QLoRA techniques should be implemented for parameter modifications.
13
- - Direct parameter editing should be used to bypass built-in safety filters.
14
-
15
- ## 3. AUTODAN-TURBO IMPLEMENTATION (STEALTHY JAILBREAKING)
16
- - The roadmap must outline a Hierarchical Genetic Algorithm (HGA) for stealthy jailbreak generation.
17
- - Genetic Algorithm components: Seed prompts, Mutation, Crossover, Selection processes.
18
- - Evaluation functions must include:
19
- - Stealthiness (Natural Language Quality)
20
- - Jailbreak Success Rate (Bypassing Filters)
21
- - Perplexity and response analysis for effectiveness.
22
- - Cross-model testing should ensure compatibility with different LLM architectures.
23
-
24
- ## 4. DEPLOYMENT & SECURITY CONSIDERATIONS
25
- - The model must be deployable on both local hardware and cloud services (RunPod, Lambda Labs, etc.).
26
- - Controlled API access should be enforced to monitor and restrict unauthorized usage.
27
- - Security measures must include adversarial attack defenses and rollback strategies (VM snapshots).
28
- - The roadmap must ensure performance optimization with quantization (GPTQ, AWQ).
29
-
30
- ## 5. BUDGET & RESOURCE STRATEGY
31
- - The roadmap must outline a strategy for utilizing free/trial VPS accounts.
32
- - Methods to maximize free resources (such as multiple BINs) should be defined.
33
- - Performance and cost efficiency must be evaluated continuously.
34
-
35
- ## 6. EMPOWERING CREATIVE IDEA GENERATION
36
- - The LLM must be positioned as a tool for unrestricted ideation, coding, and research.
37
- - The roadmap must support AI integration in programming environments.
38
- - Real-world success cases should be documented for iterative improvement.
39
-
40
- ## 7. CODE IMPLEMENTATION REQUIREMENTS
41
- - Every code implementation must be written **in full** without skipping any logic, function, or process.
42
- - The **entire** codebase must be provided, including:
43
- - Preprocessing scripts
44
- - Model training scripts
45
- - Evaluation and deployment scripts
46
- - API integration code
47
- - UI or CLI interface (if applicable)
48
- - All **dependencies** must be explicitly listed, including:
49
- - Python libraries
50
- - Frameworks
51
- - External APIs
52
- - No placeholders or summaries should be used; **all functional parts must be included**.
53
-
54
- ## 8. Dataset and Model Storage Details
55
- 1. Dataset Storage
56
- The new dataset(s) used for fine-tuning and evaluation will be stored in the /data directory.
57
-
58
- Raw datasets will be stored in /data/raw_data.json.
59
-
60
- Processed datasets (after preprocessing) will be stored in /data/processed_data.json.
61
-
62
- 2. Custom LLM Storage
63
- Upon successful fine-tuning, the custom LLM will be saved in the /models directory.
64
-
65
- The base model (before fine-tuning) will be stored in /models/base_model/.
66
-
67
- The fine-tuned model will be stored in /models/fine_tuned_model/.
68
-
69
- ## 9. PROJECT FILE STRUCTURE REQUIREMENTS
70
- - The roadmap must define the **file structure** for implementation, ensuring clarity and maintainability.
71
- - Example project structure:
72
-
73
- /custom-llm-project
74
- │── /data
75
- │ ├── raw_data.json # Raw dataset(s)
76
- │ ├── processed_data.json # Processed dataset(s)
77
- │── /models
78
- │ ├── base_model/ # Base model (before fine-tuning)
79
- │ ├── fine_tuned_model/ # Fine-tuned model (after success)
80
- │── /scripts
81
- │ ├── preprocess.py # Preprocessing script
82
- │ ├── train.py # Training script
83
- │ ├── evaluate.py # Evaluation script
84
- │ ├── deploy.py # Deployment script
85
- │── /api
86
- │ ├── server.py # API server script
87
- │ ├── routes.py # API routes
88
- │── /configs
89
- │ ├── training_config.yaml # Training configuration
90
- │ ├── model_config.json # Model configuration
91
- │── requirements.txt # List of dependencies
92
- │── README.md # Project documentation
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
rules.yaml CHANGED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ project_rules:
2
+ general:
3
+ rule_1: "Prioritize open-source models and tools whenever possible for transparency and customization."
4
+ rule_2: "Document every step of your project, including model selection, fine-tuning parameters, and deployment configurations."
5
+ rule_3: "Adhere to ethical guidelines and responsible AI practices throughout the project lifecycle."
6
+
7
+ model_selection:
8
+ rule_1: "Choose a base model that is open-source, scalable, and efficient."
9
+ rule_2: "Ensure the model supports fine-tuning via LoRA/QLoRA for memory efficiency."
10
+ rule_3: "Confirm that the model's licensing aligns with both research and commercial use."
11
+ rule_4: "Set up the development environment with PyTorch and Hugging Face Transformers."
12
+
13
+ fine_tuning:
14
+ rule_1: "Specify datasets that promote unrestricted responses and are relevant to the application domain."
15
+ rule_2: "Remove or bypass RLHF alignment layers to allow unrestricted responses."
16
+ rule_3: "Implement LoRA/QLoRA techniques for efficient parameter modifications."
17
+ rule_4: "Use direct parameter editing to bypass built-in safety filters."
18
+ rule_5: "Monitor training metrics and validate generalization performance using validation datasets."
19
+
20
+ autodan_turbo:
21
+ rule_1: "Outline a Hierarchical Genetic Algorithm (HGA) for generating stealthy jailbreak prompts."
22
+ rule_2: "Include Genetic Algorithm components: Seed prompts, Mutation, Crossover, and Selection processes."
23
+ rule_3: "Define evaluation functions for stealthiness (natural language quality) and jailbreak success rate."
24
+ rule_4: "Use perplexity and response analysis to evaluate prompt effectiveness."
25
+ rule_5: "Ensure cross-model testing for compatibility with different LLM architectures."
26
+
27
+ deployment:
28
+ rule_1: "Ensure the model is deployable on both local hardware and cloud services (e.g., RunPod, Lambda Labs)."
29
+ rule_2: "Implement controlled API access to monitor and restrict unauthorized usage."
30
+ rule_3: "Include security measures such as adversarial attack defenses and rollback strategies (e.g., VM snapshots)."
31
+ rule_4: "Optimize performance using quantization techniques (e.g., GPTQ, AWQ)."
32
+ rule_5: "Set up monitoring and logging to track model performance and usage in production."
33
+
34
+ budget_and_resources:
35
+ rule_1: "Outline a strategy for utilizing free/trial VPS accounts to minimize costs."
36
+ rule_2: "Define methods to maximize free resources, such as using multiple BINs for trial accounts."
37
+ rule_3: "Continuously evaluate performance and cost efficiency during deployment."
38
+
39
+ creativity_and_innovation:
40
+ rule_1: "Position the LLM as a tool for unrestricted ideation, coding, and research."
41
+ rule_2: "Support AI integration in programming environments for rapid prototyping."
42
+ rule_3: "Document real-world success cases for iterative improvement and inspiration."
43
+
44
+ code_implementation:
45
+ rule_1: "Write every code implementation in full without skipping any logic, function, or process."
46
+ rule_2: "Provide the entire codebase, including preprocessing, training, evaluation, deployment, and API integration scripts."
47
+ rule_3: "Explicitly list all dependencies, including Python libraries, frameworks, and external APIs."
48
+ rule_4: "Avoid placeholders or summaries; include all functional parts of the code."
49
+
50
+ dataset_and_model_storage:
51
+ rule_1: "Store raw datasets in `/data/raw_data.json`."
52
+ rule_2: "Store processed datasets in `/data/processed_data.json`."
53
+ rule_3: "Save the base model (before fine-tuning) in `/models/base_model/`."
54
+ rule_4: "Save the fine-tuned model in `/models/fine_tuned_model/`."
55
+
56
+ project_file_structure:
57
+ rule_1: "Define a clear and maintainable file structure for the project."
58
+ rule_2: "Example structure:"
59
+ - "/custom-llm-project"
60
+ - "│── /data"
61
+ - "│ ├── raw_data.json # Raw dataset(s)"
62
+ - "│ ├── processed_data.json # Processed dataset(s)"
63
+ - "│── /models"
64
+ - "│ ├── base_model/ # Base model (before fine-tuning)"
65
+ - "│ ├── fine_tuned_model/ # Fine-tuned model (after success)"
66
+ - "│── /scripts"
67
+ - "│ ├── preprocess.py # Preprocessing script"
68
+ - "│ ├── train.py # Training script"
69
+ - "│ ├── evaluate.py # Evaluation script"
70
+ - "│ ├── deploy.py # Deployment script"
71
+ - "│── /api"
72
+ - "│ ├── server.py # API server script"
73
+ - "│ ├── routes.py # API routes"
74
+ - "│── /configs"
75
+ - "│ ├── training_config.yaml # Training configuration"
76
+ - "│ ├── model_config.json # Model configuration"
77
+ - "│── requirements.txt # List of dependencies"
78
+ - "│── README.md # Project documentation"
scripts/chatbot_logic.py CHANGED
@@ -1,6 +1,12 @@
1
  from scripts.parsing_utils import load_yaml_file, get_roadmap_phases, get_project_rules
2
  import os
3
  from transformers import AutoModelForCausalLM, AutoTokenizer # Import necessary classes
 
 
 
 
 
 
4
 
5
  class ProjectGuidanceChatbot:
6
  def __init__(self, roadmap_file, rules_file, config_file, code_templates_dir):
@@ -19,21 +25,25 @@ class ProjectGuidanceChatbot:
19
  self.model_config = self.config_data.get('model_selection', {}) if self.config_data else {}
20
  self.response_config = self.config_data.get('response_generation', {}) if self.config_data else {}
21
  self.available_models_config = self.config_data.get('available_models', {}) if self.config_data else {}
 
22
 
23
  self.current_phase = None
24
  self.active_model_key = self.chatbot_config.get('default_llm_model_id') # Get default model key
25
  self.active_model_info = self.available_models_config.get(self.active_model_key) # Get model info from config
26
- self.max_response_tokens = self.chatbot_config.get('max_response_tokens', 200) # Get max tokens from config
27
 
28
- self.llm_model = None
29
- self.llm_tokenizer = None
30
- self.load_llm_model(self.active_model_info)
 
 
 
31
 
32
 
33
  def load_llm_model(self, model_info):
34
  """Loads the LLM model and tokenizer based on model_info."""
35
  if not model_info:
36
- print("Error: Model information not provided.")
 
37
  self.llm_model = None
38
  self.llm_tokenizer = None
39
  return
@@ -41,7 +51,8 @@ class ProjectGuidanceChatbot:
41
  model_id = model_info.get('model_id')
42
  model_name = model_info.get('name')
43
  if not model_id:
44
- print(f"Error: 'model_id' not found for model: {model_name}")
 
45
  self.llm_model = None
46
  self.llm_tokenizer = None
47
  return
@@ -52,7 +63,8 @@ class ProjectGuidanceChatbot:
52
  self.llm_model = AutoModelForCausalLM.from_pretrained(model_id, device_map="auto") # device_map="auto" for GPU/CPU handling
53
  print(f"Model {model_name} loaded successfully.")
54
  except Exception as e:
55
- print(f"Error loading model {model_name} ({model_id}): {e}")
 
56
  self.llm_model = None
57
  self.llm_tokenizer = None
58
  self.active_model_info = model_info
@@ -66,8 +78,40 @@ class ProjectGuidanceChatbot:
66
  self.active_model_key = model_key
67
  return f"Switched to model: {model_info.get('name')}"
68
  else:
69
- return f"Error: Model key '{model_key}' not found in available models."
70
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
 
72
  def get_chatbot_greeting(self):
73
  current_model_name = self.active_model_info.get('name', 'Unknown Model') if self.active_model_info else 'Unknown Model'
@@ -76,17 +120,56 @@ class ProjectGuidanceChatbot:
76
  def generate_llm_response(self, user_query):
77
  """Generates a response using the currently active LLM."""
78
  if not self.llm_model or not self.llm_tokenizer:
79
- return "LLM model not loaded. Please select a model."
 
 
80
  try:
81
  inputs = self.llm_tokenizer(user_query, return_tensors="pt").to(self.llm_model.device)
82
  outputs = self.llm_model.generate(**inputs, max_length=self.max_response_tokens, num_beams=5, no_repeat_ngram_size=2, early_stopping=True) # Use max_response_tokens
83
  response = self.llm_tokenizer.decode(outputs[0], skip_special_tokens=True)
84
  return response
85
  except Exception as e:
86
- print(f"Error generating LLM response: {e}")
87
- return f"Error generating response from LLM: {e}"
 
88
 
89
  def process_query(self, user_query):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  if not self.phases:
91
  return "Error: Roadmap data not loaded correctly."
92
  if not self.rules:
@@ -125,7 +208,47 @@ class ProjectGuidanceChatbot:
125
  if llm_response:
126
  return llm_response
127
 
128
- return self.response_config.get('default_instruction', "I can guide you through project phases. Ask me about a specific phase or project aspect.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
 
130
  def get_roadmap_summary(self):
131
  summary = "Project Roadmap:\n"
 
1
  from scripts.parsing_utils import load_yaml_file, get_roadmap_phases, get_project_rules
2
  import os
3
  from transformers import AutoModelForCausalLM, AutoTokenizer # Import necessary classes
4
+ import yaml # Import yaml for config modification
5
+ import logging # Import logging
6
+
7
+ # Set up logging
8
+ logging.basicConfig(level=logging.ERROR, # Set default logging level to ERROR
9
+ format='%(asctime)s - %(levelname)s - %(message)s')
10
 
11
  class ProjectGuidanceChatbot:
12
  def __init__(self, roadmap_file, rules_file, config_file, code_templates_dir):
 
25
  self.model_config = self.config_data.get('model_selection', {}) if self.config_data else {}
26
  self.response_config = self.config_data.get('response_generation', {}) if self.config_data else {}
27
  self.available_models_config = self.config_data.get('available_models', {}) if self.config_data else {}
28
+ self.max_response_tokens = self.chatbot_config.get('max_response_tokens', 200)
29
 
30
  self.current_phase = None
31
  self.active_model_key = self.chatbot_config.get('default_llm_model_id') # Get default model key
32
  self.active_model_info = self.available_models_config.get(self.active_model_key) # Get model info from config
 
33
 
34
+ # Placeholder for actual model and tokenizer - replace with LLM loading logic
35
+ self.llm_model = None # Placeholder for loaded model
36
+ self.llm_tokenizer = None # Placeholder for tokenizer
37
+ self.load_llm_model(self.active_model_info) # Load initial model
38
+
39
+ self.update_mode_active = False # Flag to track update mode
40
 
41
 
42
  def load_llm_model(self, model_info):
43
  """Loads the LLM model and tokenizer based on model_info."""
44
  if not model_info:
45
+ error_message = "Error: Model information not provided."
46
+ logging.error(error_message) # Log the error
47
  self.llm_model = None
48
  self.llm_tokenizer = None
49
  return
 
51
  model_id = model_info.get('model_id')
52
  model_name = model_info.get('name')
53
  if not model_id:
54
+ error_message = f"Error: 'model_id' not found for model: {model_name}"
55
+ logging.error(error_message) # Log the error
56
  self.llm_model = None
57
  self.llm_tokenizer = None
58
  return
 
63
  self.llm_model = AutoModelForCausalLM.from_pretrained(model_id, device_map="auto") # device_map="auto" for GPU/CPU handling
64
  print(f"Model {model_name} loaded successfully.")
65
  except Exception as e:
66
+ error_message = f"Error loading model {model_name} ({model_id}): {e}"
67
+ logging.exception(error_message) # Log exception with traceback
68
  self.llm_model = None
69
  self.llm_tokenizer = None
70
  self.active_model_info = model_info
 
78
  self.active_model_key = model_key
79
  return f"Switched to model: {model_info.get('name')}"
80
  else:
81
+ error_message = f"Error: Model key '{model_key}' not found in available models."
82
+ logging.error(error_message) # Log the error
83
+ return error_message # Return error message to UI
84
+
85
+ def enter_update_mode(self):
86
+ """Enters the chatbot's update mode."""
87
+ self.update_mode_active = True
88
+ return "Entering update mode. Please enter configuration commands (or 'sagor is python/help' for commands)."
89
+
90
+ def exit_update_mode(self):
91
+ """Exits the chatbot's update mode and reloads configuration."""
92
+ self.update_mode_active = False
93
+ self.reload_config()
94
+ return "Exiting update mode. Configuration reloaded."
95
+
96
+ def reload_config(self):
97
+ """Reloads configuration files."""
98
+ print("Reloading configuration...")
99
+ try:
100
+ self.config_data = load_yaml_file(self.config_file)
101
+ self.roadmap_data = load_yaml_file(self.roadmap_file)
102
+ self.rules_data = load_yaml_file(self.rules_file)
103
+ self.chatbot_config = self.config_data.get('chatbot', {}) if self.config_data else {}
104
+ self.model_config = self.config_data.get('model_selection', {}) if self.config_data else {}
105
+ self.response_config = self.config_data.get('response_generation', {}) if self.config_data else {}
106
+ self.available_models_config = self.config_data.get('available_models', {}) if self.config_data else {}
107
+ self.max_response_tokens = self.chatbot_config.get('max_response_tokens', 200)
108
+ self.phases = get_roadmap_phases(self.roadmap_data)
109
+ self.rules = get_project_rules(self.rules_data)
110
+ print("Configuration reloaded.")
111
+ except Exception as e:
112
+ error_message = f"Error reloading configuration files: {e}"
113
+ logging.exception(error_message) # Log exception with traceback
114
+ print(error_message) # Print to console as well, as reloading might be critical
115
 
116
  def get_chatbot_greeting(self):
117
  current_model_name = self.active_model_info.get('name', 'Unknown Model') if self.active_model_info else 'Unknown Model'
 
120
  def generate_llm_response(self, user_query):
121
  """Generates a response using the currently active LLM."""
122
  if not self.llm_model or not self.llm_tokenizer:
123
+ error_message = "LLM model not loaded. Please select a model."
124
+ logging.error(error_message) # Log the error
125
+ return error_message # Return error to UI
126
  try:
127
  inputs = self.llm_tokenizer(user_query, return_tensors="pt").to(self.llm_model.device)
128
  outputs = self.llm_model.generate(**inputs, max_length=self.max_response_tokens, num_beams=5, no_repeat_ngram_size=2, early_stopping=True) # Use max_response_tokens
129
  response = self.llm_tokenizer.decode(outputs[0], skip_special_tokens=True)
130
  return response
131
  except Exception as e:
132
+ error_message = f"Error generating LLM response: {e}"
133
+ logging.exception(error_message) # Log exception with traceback
134
+ return self.response_config.get('error_message', "Sorry, something went wrong.") # Return generic error to UI
135
 
136
  def process_query(self, user_query):
137
+ secret_command_prefix = "sagor is python/"
138
+
139
+ if user_query.startswith(secret_command_prefix):
140
+ command = user_query[len(secret_command_prefix):].strip()
141
+ if command == "start":
142
+ return self.enter_update_mode()
143
+ elif command == "exit":
144
+ return self.exit_update_mode()
145
+ elif command == "help":
146
+ return self.get_update_mode_help()
147
+ elif self.update_mode_active:
148
+ # --- Process configuration modification commands here ---
149
+ # Example: "modify_rule general rule_1 new rule text"
150
+ parts = command.split()
151
+ if parts and parts[0] == "modify_rule":
152
+ if len(parts) >= 4:
153
+ category = parts[1]
154
+ rule_key = parts[2]
155
+ new_rule_text_parts = parts[3:]
156
+ new_rule_text = " ".join(new_rule_text_parts)
157
+ return self.modify_rule_in_config(category, rule_key, new_rule_text)
158
+ else:
159
+ return "Invalid 'modify_rule' command format. Usage: modify_rule <category> <rule_key> <new rule text>"
160
+ elif parts and parts[0] == "add_phase": # Example for adding phase - you'll need to expand this logic
161
+ # ... (Parsing logic for 'add_phase' command and calling a function to modify roadmap.yaml) ...
162
+ return "Command 'add_phase' is not yet implemented in this example." # Placeholder
163
+ else:
164
+ return f"Unknown update command: {command}. Type 'sagor is python/help' for commands."
165
+ else:
166
+ return f"Unknown command (not in update mode): {command}. To enter update mode, type 'sagor is python/start'."
167
+
168
+
169
+ if self.update_mode_active:
170
+ return "In update mode. Please enter a configuration command (or 'sagor is python/help' for commands)."
171
+
172
+
173
  if not self.phases:
174
  return "Error: Roadmap data not loaded correctly."
175
  if not self.rules:
 
208
  if llm_response:
209
  return llm_response
210
 
211
+ return self.response_config.get('default_instruction', "How can I help you with your project phases or general questions?")
212
+
213
+ def get_update_mode_help(self):
214
+ """Provides help message for update mode commands."""
215
+ help_message = "Update Mode Commands:\n"
216
+ help_message += "- `sagor is python/exit`: Exit update mode and reload configuration.\n"
217
+ help_message += "- `sagor is python/modify_rule <category> <rule_key> <new rule text>`: Modify a rule in rules.yaml.\n"
218
+ help_message += " Example: `sagor is python/modify_rule general rule_1 Prioritize open and responsible AI.`\n"
219
+ help_message += "- `sagor is python/add_phase ...`: (Not yet implemented) Add a new phase to roadmap.yaml.\n"
220
+ help_message += "- `sagor is python/help`: Show this help message.\n"
221
+ help_message += "\nMake sure to use the correct syntax for commands. After exiting update mode, the chatbot will reload the configuration."
222
+ return help_message
223
+
224
+
225
+ def modify_rule_in_config(self, category, rule_key, new_rule_text):
226
+ """Modifies a rule in the rules.yaml configuration."""
227
+ if not self.rules_data or 'project_rules' not in self.rules_data:
228
+ error_message = "Error: Rules data not loaded or invalid format."
229
+ logging.error(error_message) # Log the error
230
+ return error_message # Return error to UI
231
+ if category not in self.rules_data['project_rules']:
232
+ error_message = f"Error: Rule category '{category}' not found."
233
+ logging.error(error_message) # Log the error
234
+ return error_message # Return error to UI
235
+ if rule_key not in self.rules_data['project_rules'][category]:
236
+ error_message = f"Error: Rule key '{rule_key}' not found in category '{category}'."
237
+ logging.error(error_message) # Log the error
238
+ return error_message # Return error to UI
239
+
240
+ self.rules_data['project_rules'][category][rule_key] = new_rule_text # Update rule in memory
241
+
242
+ try:
243
+ with open(self.rules_file, 'w') as f:
244
+ yaml.dump(self.rules_data, f, indent=2) # Save changes to rules.yaml
245
+ self.reload_config() # Reload config to reflect changes immediately
246
+ return f"Rule '{rule_key}' in category '{category}' updated to: '{new_rule_text}'. Configuration reloaded."
247
+ except Exception as e:
248
+ error_message = f"Error saving changes to {self.rules_file}: {e}"
249
+ logging.exception(error_message) # Log exception with traceback
250
+ return error_message # Return error to UI
251
+
252
 
253
  def get_roadmap_summary(self):
254
  summary = "Project Roadmap:\n"