nexus-5/core/models/chat.py
2026-01-26 11:09:40 -05:00

95 lines
2.8 KiB
Python

"""
Chat models for AI assistant conversations.
"""
from django.db import models
from core.models.base import BaseModel
class ChatConversation(BaseModel):
"""
A chat conversation between a team member and the AI assistant.
Conversations persist across browser sessions and can be resumed.
"""
team_profile = models.ForeignKey(
'TeamProfile',
on_delete=models.CASCADE,
related_name='chat_conversations',
help_text="The team member who owns this conversation"
)
title = models.CharField(
max_length=255,
blank=True,
help_text="Auto-generated title based on conversation content"
)
is_active = models.BooleanField(
default=True,
help_text="Whether this conversation is active (not archived)"
)
class Meta:
ordering = ('-updated_at',)
verbose_name = 'Chat Conversation'
verbose_name_plural = 'Chat Conversations'
def __str__(self):
return f"{self.team_profile}: {self.title or 'Untitled'}"
def generate_title(self) -> str:
"""
Generate a title from the first user message.
Returns the first 50 characters of the first user message.
"""
first_message = self.messages.filter(role='user').first()
if first_message:
content = first_message.content[:50]
if len(first_message.content) > 50:
content += '...'
return content
return 'New Conversation'
class ChatMessage(BaseModel):
"""
Individual message in a chat conversation.
Stores both user messages and assistant responses, including tool calls.
"""
ROLE_CHOICES = [
('user', 'User'),
('assistant', 'Assistant'),
]
conversation = models.ForeignKey(
ChatConversation,
on_delete=models.CASCADE,
related_name='messages',
help_text="The conversation this message belongs to"
)
role = models.CharField(
max_length=20,
choices=ROLE_CHOICES,
help_text="Whether this message is from the user or assistant"
)
content = models.TextField(
blank=True,
help_text="The text content of the message"
)
tool_calls = models.JSONField(
default=list,
blank=True,
help_text="List of MCP tool calls made during this message"
)
tool_results = models.JSONField(
default=list,
blank=True,
help_text="Results from MCP tool executions"
)
class Meta:
ordering = ('created_at',)
verbose_name = 'Chat Message'
verbose_name_plural = 'Chat Messages'
def __str__(self):
preview = self.content[:50] + '...' if len(self.content) > 50 else self.content
return f"[{self.role}] {preview}"