first commit

This commit is contained in:
2025-11-06 11:08:59 +01:00
commit 3c5117c2c3
85 changed files with 13275 additions and 0 deletions
+356
View File
@@ -0,0 +1,356 @@
const { Conversation, Message, Plan, User } = require('../models');
const logger = require('../utils/logger');
const model1Service = require('../services/model1Service');
const chatRouter = require('../services/chatRouter');
const createConversation = async (req, res) => {
try {
const { title } = req.body;
const userId = req.user.userId;
const conversation = await Conversation.create({
user_id: userId,
title: title || 'New Conversation',
status: 'active'
});
logger.info(`New conversation created: ${conversation.id}`);
res.status(201).json({
success: true,
data: { conversation }
});
} catch (error) {
logger.error('Create conversation error:', error);
res.status(500).json({
success: false,
error: 'Internal server error'
});
}
};
const getConversations = async (req, res) => {
try {
const userId = req.user.userId;
const { page = 1, limit = 10, status } = req.query;
const whereClause = { user_id: userId };
if (status) whereClause.status = status;
const conversations = await Conversation.findAndCountAll({
where: whereClause,
include: [
{
model: Message,
limit: 1,
order: [['created_at', 'DESC']]
}
],
order: [['created_at', 'DESC']],
limit: parseInt(limit),
offset: (parseInt(page) - 1) * parseInt(limit)
});
res.json({
success: true,
data: {
conversations: conversations.rows,
pagination: {
page: parseInt(page),
limit: parseInt(limit),
total: conversations.count,
pages: Math.ceil(conversations.count / limit)
}
}
});
} catch (error) {
logger.error('Get conversations error:', error);
res.status(500).json({
success: false,
error: 'Internal server error'
});
}
};
const getConversation = async (req, res) => {
try {
const { conversationId } = req.params;
const userId = req.user.userId;
const conversation = await Conversation.findOne({
where: {
id: conversationId,
user_id: userId
},
include: [
{
model: Message,
order: [['created_at', 'ASC']]
},
{
model: Plan,
order: [['created_at', 'DESC']]
}
]
});
if (!conversation) {
return res.status(404).json({
success: false,
error: 'Conversation not found'
});
}
res.json({
success: true,
data: { conversation }
});
} catch (error) {
logger.error('Get conversation error:', error);
res.status(500).json({
success: false,
error: 'Internal server error'
});
}
};
const sendMessage = async (req, res) => {
try {
const { conversationId, content, messageType = 'text' } = req.body;
const userId = req.user.userId;
// Verify conversation belongs to user
const conversation = await Conversation.findOne({
where: {
id: conversationId,
user_id: userId
}
});
if (!conversation) {
return res.status(404).json({
success: false,
error: 'Conversation not found'
});
}
// Create user message
const userMessage = await Message.create({
conversation_id: conversationId,
role: 'user',
content,
message_type: messageType
});
// Get conversation history for context
const conversationHistory = await Message.findAll({
where: { conversation_id: conversationId },
order: [['created_at', 'DESC']],
limit: 20 // Last 20 messages for context
});
// Create properly ordered conversation history for context
const orderedHistory = conversationHistory.reverse().map(msg => ({
role: msg.role,
content: msg.content,
message_type: msg.message_type,
timestamp: msg.created_at
}));
// Route the message to determine response type
const routingDecision = await chatRouter.routeMessage(content, {
conversationId,
userId,
timestamp: new Date().toISOString(),
conversationHistory: orderedHistory
});
let assistantMessage;
if (routingDecision.responseType === 'plan_needed' && routingDecision.isEngineeringQuestion) {
// Generate engineering plan using MODEL1
try {
const planData = await model1Service.generatePlan(content, {
conversationId,
userId,
timestamp: new Date().toISOString()
});
// Save the plan to database
const plan = await Plan.create({
conversation_id: conversationId,
title: planData.title,
description: planData.description,
steps: planData.steps,
status: 'draft',
tools_required: planData.toolsRequired || [],
estimated_duration: planData.estimatedDuration,
complexity_score: planData.complexityScore,
metadata: {
safetyConsiderations: planData.safetyConsiderations,
qualityChecks: planData.qualityChecks,
processingTime: planData.processingTime,
tokensUsed: planData.tokensUsed,
model: planData.model
}
});
// Create assistant message with plan
assistantMessage = await Message.create({
conversation_id: conversationId,
plan_id: plan.id,
role: 'assistant',
content: planData.rawContent || `# ${planData.title}\n\n${planData.description}\n\n## Steps:\n${planData.steps.map((step, index) => `${index + 1}. ${step}`).join('\n')}`,
message_type: 'plan',
metadata: {
modelType: 'MODEL1',
processingTime: planData.processingTime,
tokensUsed: planData.tokensUsed,
routingDecision: routingDecision.reasoning
}
});
logger.info(`MODEL1 plan generated: ${plan.id} for conversation: ${conversationId}`);
} catch (error) {
logger.error('MODEL1 plan generation failed:', error);
// Fallback to simple response if plan generation fails
const fallbackResponse = await chatRouter.generateSimpleResponse(content, {
conversationHistory: orderedHistory
});
assistantMessage = await Message.create({
conversation_id: conversationId,
role: 'assistant',
content: fallbackResponse,
message_type: 'text',
metadata: {
error: error.message,
modelType: 'FALLBACK',
routingDecision: routingDecision.reasoning
}
});
}
} else {
// Generate simple conversational response
const responseContent = routingDecision.response || await chatRouter.generateSimpleResponse(content, {
conversationHistory: orderedHistory
});
assistantMessage = await Message.create({
conversation_id: conversationId,
role: 'assistant',
content: responseContent,
message_type: 'text',
metadata: {
modelType: 'REASONAI',
routingDecision: routingDecision.reasoning,
responseType: routingDecision.responseType
}
});
logger.info(`Simple response generated for conversation: ${conversationId}`, {
responseType: routingDecision.responseType,
reasoning: routingDecision.reasoning
});
}
logger.info(`Message sent in conversation: ${conversationId}`);
res.json({
success: true,
data: { userMessage, assistantMessage }
});
} catch (error) {
logger.error('Send message error:', error);
res.status(500).json({
success: false,
error: 'Internal server error'
});
}
};
const updateConversation = async (req, res) => {
try {
const { conversationId } = req.params;
const { title, status } = req.body;
const userId = req.user.userId;
const conversation = await Conversation.findOne({
where: {
id: conversationId,
user_id: userId
}
});
if (!conversation) {
return res.status(404).json({
success: false,
error: 'Conversation not found'
});
}
const updateData = {};
if (title) updateData.title = title;
if (status) updateData.status = status;
await conversation.update(updateData);
logger.info(`Conversation updated: ${conversationId}`);
res.json({
success: true,
data: { conversation }
});
} catch (error) {
logger.error('Update conversation error:', error);
res.status(500).json({
success: false,
error: 'Internal server error'
});
}
};
const deleteConversation = async (req, res) => {
try {
const { conversationId } = req.params;
const userId = req.user.userId;
const conversation = await Conversation.findOne({
where: {
id: conversationId,
user_id: userId
}
});
if (!conversation) {
return res.status(404).json({
success: false,
error: 'Conversation not found'
});
}
await conversation.destroy();
logger.info(`Conversation deleted: ${conversationId}`);
res.json({
success: true,
message: 'Conversation deleted successfully'
});
} catch (error) {
logger.error('Delete conversation error:', error);
res.status(500).json({
success: false,
error: 'Internal server error'
});
}
};
module.exports = {
createConversation,
getConversations,
getConversation,
sendMessage,
updateConversation,
deleteConversation
};