Skip to content

Commit 42d51bb

Browse files
Introduced Undo Functionality & AI Agent (for connected environment)
1 parent 99bf6ec commit 42d51bb

File tree

12 files changed

+902
-233
lines changed

12 files changed

+902
-233
lines changed

.env

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ EMBEDDING_MODEL="text-embedding-3-small"
55
EMBEDDING_API_VERSION="2023-05-15"
66
ENDPOINT="https://ai4se-openai.openai.azure.com/"
77
AZURE_OPENAI_API_KEY="VDfaCeEbTyAyPRC3C02mZyyANPxZGBxODmWOpWechSlv7GQ8zmmuJQQJ99AKACI8hq2XJ3w3AAABACOGPYeE"
8+
MONGODB_URI="mongodb://localhost:27017/"

README.md

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
- Classifies input as "General" or "Scenario" intelligently.
1111
- Generates detailed scenarios and concise summaries using GPT models.
1212
- Converts extracted domain structures into **PlantUML** diagrams.
13-
- Stores and manages data using **MongoDB**.
1413
- Includes a full test suite for backend routes with **pytest**.
1514

1615
---
@@ -19,11 +18,10 @@
1918

2019
- **Python 3.9+**
2120
- **Flask** (Web Framework)
22-
- **OpenAI API** (Azure-compatible)
23-
- **MongoDB** (Database)
24-
- **PlantUML** (Diagram rendering)
25-
- **dotenv** (Environment configuration)
21+
- **OpenAI API** (Azure variant support)
22+
- **PlantUML** (Diagram generation)
2623
- **pytest** (Testing)
24+
- **dotenv** (Environment management)
2725

2826
---
2927

@@ -56,21 +54,10 @@ EMBEDDING_MODEL="text-embedding-3-small"
5654
EMBEDDING_API_VERSION="2023-05-15"
5755
ENDPOINT="https://your-azure-endpoint/"
5856
AZURE_OPENAI_API_KEY="your-api-key"
59-
MONGO_URI="mongodb://localhost:27017/domain_modelling"
6057
```
6158

6259
### 5. Run the application
6360
```bash
6461
python app.py
6562
```
6663
Visit: http://localhost:5000
67-
68-
### MongoDB Setup
69-
1. Install MongoDB: MongoDB Installation Guide
70-
71-
2. Start MongoDB Server:
72-
73-
```bash
74-
mongod
75-
```
76-
03. Database Connection: The app connects to MongoDB using the URI in .env (MONGO_URI). The database and collections will be created automatically.

src/controller/chat_controller.py

Lines changed: 41 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,33 @@
1-
from flask import request, jsonify, session
2-
from src.model.llm_service import LLMService
3-
from src.model.gpt2 import gpt_v2_interface
4-
from src.model.project_service import ProjectService
1+
from flask import request, jsonify
2+
from src.model.AgentChat import AgentChat
3+
from src.model.AgentDomainModelDescription import AgentDomainModelDescription
4+
from src.model.AgentDomainModelVisualization import AgentDomainModelVisualization
5+
import traceback
56

67
class ChatController:
7-
"""Controller for chat-related operations and version saving"""
8+
"""Controller for chat-related operations using agent-based architecture"""
89

910
def __init__(self):
10-
self.llm_service = LLMService()
11-
self.project_service = ProjectService()
11+
# Create agents
12+
print("Initializing ChatController with three specialized agents")
13+
self.chat_agent = AgentChat()
14+
self.domain_model_agent = AgentDomainModelDescription()
15+
self.visualization_agent = AgentDomainModelVisualization()
1216

17+
# Connect agents in a bidirectional network
18+
self.chat_agent.connect("DomainModelAgent", self.domain_model_agent)
19+
self.chat_agent.connect("VisualizationAgent", self.visualization_agent)
20+
21+
self.domain_model_agent.connect("ChatAgent", self.chat_agent)
22+
self.domain_model_agent.connect("VisualizationAgent", self.visualization_agent)
23+
24+
self.visualization_agent.connect("ChatAgent", self.chat_agent)
25+
self.visualization_agent.connect("DomainModelAgent", self.domain_model_agent)
26+
27+
print("Agent network initialized with bidirectional connections")
28+
1329
def handle_chat_request(self):
14-
"""Process user input and generate response with version saving"""
30+
"""Process user input using the ChatAgent"""
1531
try:
1632
data = request.json
1733
user_input = data.get("message", "").strip()
@@ -20,131 +36,40 @@ def handle_chat_request(self):
2036
if not user_input:
2137
return jsonify({"error": "User input is required"}), 400
2238
if not project_name:
23-
return jsonify({"error": "Project name is required to save version"}), 400
24-
25-
# Get the current state before processing new input
26-
# This ensures we always have the latest domain model and PlantUML
27-
project_result, _ = self.project_service.get_project_data(project_name)
28-
current_project_data = project_result.get("project_data", {})
39+
return jsonify({"error": "Project name is required"}), 400
2940

30-
# Get existing domain model description and PlantUML from project data
31-
# These will be used as fallbacks if nothing new is generated
32-
existing_dmd = current_project_data.get("domain_model_description", "Welcome to your new project! Start by describing your domain.")
33-
existing_plant_uml = current_project_data.get("plant_uml", "@startuml\nskinparam monochrome true\ntitle Your New Project\n\nclass ExampleEntity {\n +id: string\n +name: string\n}\n\nnote \"Start building your domain model!\" as N1\n@enduml")
41+
# Delegate handling to the ChatAgent
42+
result = self.chat_agent.handle_user_input(user_input, project_name)
3443

35-
self.llm_service.add_to_chat_history("user", user_input)
36-
updated_chat_history = self.llm_service.chat_history.get_messages()
37-
chat_history_text = "\n".join([
38-
f"{'User' if msg['role'] == 'user' else 'Assistant'}: {msg['content']}"
39-
for msg in updated_chat_history
40-
])
41-
42-
classification_result = self.llm_service.determine_input_type(chat_history_text)
43-
44-
decision = classification_result.get("decision", False)
45-
is_casual_comment = classification_result.get("is_casual_comment", False)
46-
suggestions = classification_result.get("suggestions", [])
47-
assistant_response = "\n".join(suggestions) if isinstance(suggestions, list) else suggestions
48-
49-
# Set initial state using existing values to ensure we never store nulls
50-
current_dmd = self.llm_service.get_current_domain_model_description() or existing_dmd
51-
current_plant_uml = existing_plant_uml
52-
53-
if is_casual_comment:
54-
self.llm_service.add_to_chat_history("assistant", assistant_response)
55-
56-
# Use existing domain model and PlantUML (already set above)
57-
# If DMD exists but PlantUML doesn't, generate PlantUML
58-
if current_dmd and not current_plant_uml:
59-
client = self.llm_service.client
60-
current_plant_uml = gpt_v2_interface(current_dmd, client)
44+
if "error" in result:
45+
return jsonify({"error": result["error"]}), 400
6146

62-
self.project_service.save_version(
63-
project_name,
64-
user_input,
65-
assistant_response,
66-
current_dmd,
67-
current_plant_uml
68-
)
69-
return jsonify({
70-
"response": assistant_response,
71-
"history": self.llm_service.get_chat_history(),
72-
"domain_model_description": current_dmd,
73-
"plant_uml": current_plant_uml
74-
})
75-
76-
elif decision: # Enough information for domain modeling (new or update)
77-
new_dmd = self.llm_service.generate_domain_model_description(chat_history_text)
78-
self.llm_service.add_to_chat_history("assistant", assistant_response)
79-
80-
# Generate PlantUML for the new/updated DMD
81-
client = self.llm_service.client
82-
new_plant_uml = ""
83-
if new_dmd:
84-
new_plant_uml = gpt_v2_interface(new_dmd, client)
85-
else:
86-
new_dmd = current_dmd # Fallback to existing DMD
87-
new_plant_uml = current_plant_uml # Fallback to existing PlantUML
88-
89-
self.project_service.save_version(
90-
project_name,
91-
user_input,
92-
assistant_response,
93-
new_dmd,
94-
new_plant_uml
95-
)
96-
97-
return jsonify({
98-
"domain_model_description": new_dmd,
99-
"suggestion": assistant_response,
100-
"plant_uml": new_plant_uml
101-
})
102-
103-
else: # Not enough info for domain modeling
104-
self.llm_service.add_to_chat_history("assistant", assistant_response)
105-
106-
# Use existing domain model and PlantUML
107-
# If we have a domain model but no PlantUML, generate it
108-
if current_dmd and not current_plant_uml:
109-
client = self.llm_service.client
110-
current_plant_uml = gpt_v2_interface(current_dmd, client)
111-
112-
self.project_service.save_version(
113-
project_name,
114-
user_input,
115-
assistant_response,
116-
current_dmd,
117-
current_plant_uml
118-
)
119-
120-
return jsonify({
121-
"response": assistant_response,
122-
"history": self.llm_service.get_chat_history(),
123-
"domain_model_description": current_dmd,
124-
"plant_uml": current_plant_uml
125-
})
47+
return jsonify(result)
12648

12749
except Exception as e:
12850
print(f"Error in chat request: {e}")
129-
import traceback
13051
traceback.print_exc()
13152
return jsonify({"error": "An unexpected error occurred"}), 500
13253

13354
def generate_uml(self):
134-
"""Generate UML diagram from domain model description"""
55+
"""Generate UML diagram from domain model description using VisualizationAgent"""
13556
try:
13657
domain_model_description_text = request.json.get("domainModelDescriptionText", "").strip()
13758
if not domain_model_description_text:
13859
return jsonify({"error": "Domain Model Description is required"}), 400
13960

140-
client = self.llm_service.client
141-
plant_uml = gpt_v2_interface(domain_model_description_text, client)
142-
return jsonify({"plantuml": plant_uml})
61+
# Use visualization agent to generate PlantUML
62+
result = self.visualization_agent.generate_plantuml(domain_model_description_text)
63+
64+
if "error" in result:
65+
return jsonify({"error": result["error"]}), 400
66+
67+
return jsonify({"plantuml": result["plant_uml"]})
14368
except Exception as e:
14469
print(f"Error generating UML: {e}")
14570
return jsonify({"error": "An error occurred while generating the UML"}), 500
14671

14772
def get_current_domain_model_description(self):
148-
"""Retrieve the current domain model description"""
149-
domain_model_description = self.llm_service.get_current_domain_model_description()
150-
return jsonify({"domain_model_description": domain_model_description})
73+
"""Retrieve the current domain model description from DomainModelAgent"""
74+
result = self.domain_model_agent.get_domain_model()
75+
return jsonify({"domain_model_description": result.get("domain_model_description")})

0 commit comments

Comments
 (0)