Fixed multi-turn conversation support and improved conversation preview in /ai/conversations list. Users can now ask follow-up questions in the same conversation. Fixed multi-turn conversation support and improved conversation preview in /ai/conversations list. Users can now ask follow-up questions in the same conversation.
Issues Fixed:
What Was Happening:
Impact:
What Was Happening:
Example of Old View:
Conversation #1234
Status: active
Messages: 2
Created: 2025-12-27 01:15
[Preview text - possibly just AI response]
Example of New View:
What is machine learning?
Status: active
Messages: 4
Created: 2025-12-27 01:15
Q: What is machine learning? | A: Machine learning is a subset of...
1. Accept conversation_id parameter:
my $conversation_id = $json_data->{conversation_id} ||
$c->request->params->{conversation_id};
2. Reuse existing conversation OR create new:
unless ($final_conversation_id) {
# Create new conversation (first message)
my $conversation = $schema->resultset('AiConversation')->create({...});
$final_conversation_id = $conversation->id;
} else {
# Reuse existing conversation (follow-up message)
# Just log and continue
}
3. Add messages to the same conversation:
# Both user and AI messages use the SAME conversation_id
$schema->resultset('AiMessage')->create({
conversation_id => $final_conversation_id,
role => 'user',
content => $prompt,
...
});
$schema->resultset('AiMessage')->create({
conversation_id => $final_conversation_id,
role => 'assistant',
content => $ai_response,
...
});
1. Track current conversation ID:
let currentConversationId = null;
2. Include conversation_id in requests:
const requestBody = {
prompt: prompt,
model: selectedModel,
history: conversationHistory.slice(-10)
};
if (currentConversationId) {
requestBody.conversation_id = currentConversationId;
}
3. Update conversation ID when response received:
if (data.conversation_id) {
currentConversationId = data.conversation_id;
// Display it and show "saved" notification
}
4. Display current conversation ID:
document.getElementById('conversation-id-display').textContent =
data.conversation_id;
document.getElementById('conversation-info').style.display = 'block';
Updated the conversations action to generate better preview text:
# Get all messages for conversation
my @messages = $conv->ai_messages->all;
# Find first user message (question) and AI response (answer)
foreach my $msg (@messages) {
if ($msg->role eq 'user' && !$user_msg) {
$user_msg = $msg->content;
}
if ($msg->role eq 'assistant' && !$ai_msg) {
$ai_msg = $msg->content;
}
}
# Create readable preview
$preview = "Q: " . substr($user_msg, 0, 60) . "...";
$preview .= " | A: " . substr($ai_msg, 0, 40) . "...";
Result Format:
Q: What is the difference between AI and machine learning? | A: AI is the broader field, while machine learning is...
Step 1: First Message
conversation_id: 42Step 2: Follow-Up Question (Same Conversation)
conversation_id: 42Step 3: View Conversation
| File | Changes |
|---|---|
Controller/AI.pm |
- Added conversation_id parameter parsing - Modified conversation saving logic to support reuse - Updated conversations action preview generation |
root/ai/index.tt |
- Added currentConversationId state variable - Updated fetch request to include conversation_id - Added conversation ID display in header - Show "saved" notification on first message |
/ai/chat Request (NEW):
{
"prompt": "What is Python?",
"model": "qwen2.5-coder:1.5b-base",
"history": [...],
"conversation_id": 42 // ← NEW: Include for follow-up
}
/ai/chat Response (SAME):
{
"success": true,
"response": "Python is a high-level programming language...",
"model": "qwen2.5-coder:1.5b-base",
"conversation_id": 42 // ← Still returned (now reused)
}
| Test | Expected Behavior | Result |
|---|---|---|
| First message saved | Notification shows conversation ID | ✅ |
| Follow-up in same conversation | Same conversation ID, no new notification | ✅ |
| Conversation list preview | Shows Q & A format, not just numbers | ✅ |
| View full conversation | Shows all message pairs in order | ✅ |