Co-authored-by: Sharang Parnerkar <parnerkarsharang@gmail.com> Reviewed-on: #10
108 lines
3.4 KiB
Rust
108 lines
3.4 KiB
Rust
use serde::{Deserialize, Serialize};
|
|
|
|
/// The role of a participant in a chat conversation.
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
pub enum ChatRole {
|
|
/// Message sent by the human user
|
|
User,
|
|
/// Message generated by the AI assistant
|
|
Assistant,
|
|
/// System-level instruction (not displayed in UI)
|
|
System,
|
|
}
|
|
|
|
/// Namespace for grouping chat sessions in the sidebar.
|
|
///
|
|
/// Sessions are visually separated in the chat sidebar by namespace,
|
|
/// with `News` sessions appearing under a dedicated "News Chats" header.
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
|
|
pub enum ChatNamespace {
|
|
/// General user-initiated chat conversations.
|
|
#[default]
|
|
General,
|
|
/// Chats originating from news article follow-ups on the dashboard.
|
|
News,
|
|
}
|
|
|
|
/// The type of file attached to a chat message.
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
pub enum AttachmentKind {
|
|
/// Image file (png, jpg, webp, etc.)
|
|
Image,
|
|
/// Document file (pdf, docx, txt, etc.)
|
|
Document,
|
|
/// Source code file
|
|
Code,
|
|
}
|
|
|
|
/// A file attachment on a chat message.
|
|
///
|
|
/// # Fields
|
|
///
|
|
/// * `name` - Original filename
|
|
/// * `kind` - Type of attachment for rendering
|
|
/// * `size_bytes` - File size in bytes
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
pub struct Attachment {
|
|
pub name: String,
|
|
pub kind: AttachmentKind,
|
|
pub size_bytes: u64,
|
|
}
|
|
|
|
/// A persisted chat session stored in MongoDB.
|
|
///
|
|
/// Messages are stored separately in the `chat_messages` collection
|
|
/// and loaded on demand when the user opens a session.
|
|
///
|
|
/// # Fields
|
|
///
|
|
/// * `id` - MongoDB document ID (hex string)
|
|
/// * `user_sub` - Keycloak subject ID (session owner)
|
|
/// * `title` - Display title (auto-generated or user-renamed)
|
|
/// * `namespace` - Grouping for sidebar sections
|
|
/// * `provider` - LLM provider used (e.g. "ollama", "openai")
|
|
/// * `model` - Model ID used (e.g. "llama3.1:8b")
|
|
/// * `created_at` - ISO 8601 creation timestamp
|
|
/// * `updated_at` - ISO 8601 last-activity timestamp
|
|
/// * `article_url` - Source article URL (for News namespace sessions)
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
pub struct ChatSession {
|
|
#[serde(default, alias = "_id", skip_serializing_if = "String::is_empty")]
|
|
pub id: String,
|
|
pub user_sub: String,
|
|
pub title: String,
|
|
#[serde(default)]
|
|
pub namespace: ChatNamespace,
|
|
pub provider: String,
|
|
pub model: String,
|
|
pub created_at: String,
|
|
pub updated_at: String,
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub article_url: Option<String>,
|
|
}
|
|
|
|
/// A single persisted message within a chat session.
|
|
///
|
|
/// Stored in the `chat_messages` MongoDB collection, linked to a
|
|
/// `ChatSession` via `session_id`.
|
|
///
|
|
/// # Fields
|
|
///
|
|
/// * `id` - MongoDB document ID (hex string)
|
|
/// * `session_id` - Foreign key to `ChatSession.id`
|
|
/// * `role` - Who sent this message
|
|
/// * `content` - Message text content (may contain markdown)
|
|
/// * `attachments` - File attachments (Phase 2, currently empty)
|
|
/// * `timestamp` - ISO 8601 timestamp
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
pub struct ChatMessage {
|
|
#[serde(default, alias = "_id", skip_serializing_if = "String::is_empty")]
|
|
pub id: String,
|
|
pub session_id: String,
|
|
pub role: ChatRole,
|
|
pub content: String,
|
|
#[serde(default)]
|
|
pub attachments: Vec<Attachment>,
|
|
pub timestamp: String,
|
|
}
|