oxirs_chat/
messages.rs

1//! Message types and rich content support for chat interface
2
3use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5
6/// Chat message with rich content support
7#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
8pub struct Message {
9    pub id: String,
10    pub role: MessageRole,
11    pub content: MessageContent,
12    pub timestamp: chrono::DateTime<chrono::Utc>,
13    pub metadata: Option<MessageMetadata>,
14    pub thread_id: Option<String>,
15    pub parent_message_id: Option<String>,
16    pub token_count: Option<usize>,
17    pub reactions: Vec<crate::types::MessageReaction>,
18    pub attachments: Vec<MessageAttachment>,
19    pub rich_elements: Vec<RichContentElement>,
20}
21
22/// Message role enumeration
23#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
24pub enum MessageRole {
25    User,
26    Assistant,
27    System,
28    Function,
29}
30
31/// Message content supporting both plain text and rich content
32#[derive(Debug, Clone, Serialize, Deserialize)]
33pub enum MessageContent {
34    /// Plain text content
35    Text(String),
36    /// Rich content with multiple elements
37    Rich {
38        text: String,
39        elements: Vec<RichContentElement>,
40    },
41}
42
43impl MessageContent {
44    pub fn to_text(&self) -> &str {
45        match self {
46            MessageContent::Text(text) => text,
47            MessageContent::Rich { text, .. } => text,
48        }
49    }
50
51    pub fn from_text(text: String) -> Self {
52        MessageContent::Text(text)
53    }
54
55    pub fn add_element(&mut self, element: RichContentElement) {
56        match self {
57            MessageContent::Text(text) => {
58                let text = std::mem::take(text);
59                *self = MessageContent::Rich {
60                    text,
61                    elements: vec![element],
62                };
63            }
64            MessageContent::Rich { elements, .. } => {
65                elements.push(element);
66            }
67        }
68    }
69
70    pub fn len(&self) -> usize {
71        self.to_text().len()
72    }
73
74    pub fn contains(&self, pat: char) -> bool {
75        self.to_text().contains(pat)
76    }
77
78    pub fn to_lowercase(&self) -> String {
79        self.to_text().to_lowercase()
80    }
81
82    pub fn chars(&self) -> std::str::Chars<'_> {
83        self.to_text().chars()
84    }
85
86    pub fn is_empty(&self) -> bool {
87        self.to_text().is_empty()
88    }
89}
90
91impl std::fmt::Display for MessageContent {
92    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
93        write!(f, "{}", self.to_text())
94    }
95}
96
97/// Rich content elements that can be embedded in messages
98#[derive(Debug, Clone, Serialize, Deserialize)]
99pub enum RichContentElement {
100    /// Code snippet with syntax highlighting
101    CodeBlock {
102        language: String,
103        code: String,
104        title: Option<String>,
105        line_numbers: bool,
106        highlight_lines: Vec<usize>,
107    },
108    /// SPARQL query block with execution metadata
109    SparqlQuery {
110        query: String,
111        execution_time_ms: Option<u64>,
112        result_count: Option<usize>,
113        status: QueryExecutionStatus,
114        explanation: Option<String>,
115    },
116    /// Data table with formatting options
117    Table {
118        headers: Vec<String>,
119        rows: Vec<Vec<String>>,
120        title: Option<String>,
121        pagination: Option<TablePagination>,
122        sorting: Option<TableSorting>,
123        formatting: TableFormatting,
124    },
125    /// Graph visualization configuration
126    GraphVisualization {
127        graph_type: GraphType,
128        data: GraphData,
129        layout: GraphLayout,
130        styling: GraphStyling,
131        interactive: bool,
132    },
133    /// Chart or plot
134    Chart {
135        chart_type: ChartType,
136        data: ChartData,
137        title: Option<String>,
138        axes: ChartAxes,
139        styling: ChartStyling,
140    },
141    /// File upload reference
142    FileReference {
143        file_id: String,
144        filename: String,
145        file_type: String,
146        size_bytes: u64,
147        preview: Option<FilePreview>,
148    },
149    /// Interactive widget
150    Widget {
151        widget_type: WidgetType,
152        data: serde_json::Value,
153        config: WidgetConfig,
154    },
155    /// Timeline visualization
156    Timeline {
157        events: Vec<TimelineEvent>,
158        range: TimelineRange,
159        styling: TimelineStyling,
160    },
161    /// Advanced quantum-enhanced search results visualization
162    QuantumVisualization {
163        results: Vec<crate::rag::quantum_rag::QuantumSearchResult>,
164        entanglement_map: HashMap<String, f64>,
165    },
166    /// Consciousness-aware insights from advanced AI processing
167    ConsciousnessInsights {
168        insights: Vec<crate::rag::consciousness::ConsciousInsight>,
169        awareness_level: f64,
170    },
171    /// Advanced reasoning chain visualization
172    ReasoningChain {
173        reasoning_steps: Vec<crate::rag::advanced_reasoning::ReasoningStep>,
174        confidence_score: f64,
175    },
176    /// SPARQL query results with execution details
177    SPARQLResults {
178        query: String,
179        results: Vec<HashMap<String, String>>,
180        execution_time: std::time::Duration,
181    },
182}
183
184/// Message attachment for file uploads
185#[derive(Debug, Clone, Serialize, Deserialize)]
186pub struct MessageAttachment {
187    pub id: String,
188    pub filename: String,
189    pub file_type: String,
190    pub size_bytes: u64,
191    pub url: Option<String>,
192    pub thumbnail_url: Option<String>,
193    pub metadata: AttachmentMetadata,
194    pub upload_timestamp: chrono::DateTime<chrono::Utc>,
195    pub processing_status: AttachmentProcessingStatus,
196}
197
198/// Query execution status for SPARQL queries
199#[derive(Debug, Clone, Serialize, Deserialize)]
200pub enum QueryExecutionStatus {
201    Success,
202    Error(String),
203    Timeout,
204    Cancelled,
205    ValidationError(String),
206}
207
208/// Table pagination information
209#[derive(Debug, Clone, Serialize, Deserialize)]
210pub struct TablePagination {
211    pub current_page: usize,
212    pub total_pages: usize,
213    pub page_size: usize,
214    pub total_rows: usize,
215}
216
217/// Table sorting configuration
218#[derive(Debug, Clone, Serialize, Deserialize)]
219pub struct TableSorting {
220    pub column: String,
221    pub direction: SortDirection,
222}
223
224#[derive(Debug, Clone, Serialize, Deserialize)]
225pub enum SortDirection {
226    Ascending,
227    Descending,
228}
229
230/// Table formatting options
231#[derive(Debug, Clone, Serialize, Deserialize)]
232pub struct TableFormatting {
233    pub striped_rows: bool,
234    pub borders: bool,
235    pub compact: bool,
236    pub highlight_row: Option<usize>,
237    pub column_widths: Option<Vec<String>>,
238}
239
240impl Default for TableFormatting {
241    fn default() -> Self {
242        Self {
243            striped_rows: true,
244            borders: true,
245            compact: false,
246            highlight_row: None,
247            column_widths: None,
248        }
249    }
250}
251
252/// Message metadata for additional information
253#[derive(Debug, Clone, Serialize, Deserialize)]
254pub struct MessageMetadata {
255    pub source: Option<String>,
256    pub confidence: Option<f64>,
257    pub processing_time_ms: Option<u64>,
258    pub model_used: Option<String>,
259    pub temperature: Option<f32>,
260    pub max_tokens: Option<usize>,
261    pub custom_fields: HashMap<String, serde_json::Value>,
262}
263
264// MessageReaction is now defined in types.rs and re-exported from crate root
265
266#[derive(Debug, Clone, Serialize, Deserialize)]
267pub enum ReactionType {
268    Like,
269    Dislike,
270    Helpful,
271    NotHelpful,
272    Accurate,
273    Inaccurate,
274    Custom(String),
275}
276
277/// Attachment metadata
278#[derive(Debug, Clone, Serialize, Deserialize)]
279pub struct AttachmentMetadata {
280    pub extracted_text: Option<String>,
281    pub language: Option<String>,
282    pub encoding: Option<String>,
283    pub checksum: Option<String>,
284    pub analysis_results: HashMap<String, serde_json::Value>,
285}
286
287/// Attachment processing status
288#[derive(Debug, Clone, Serialize, Deserialize)]
289pub enum AttachmentProcessingStatus {
290    Pending,
291    Processing,
292    Complete,
293    Failed(String),
294    VirusScanFailed,
295    Quarantined,
296}
297
298// Graph and Chart related types (simplified for now)
299#[derive(Debug, Clone, Serialize, Deserialize)]
300pub enum GraphType {
301    KnowledgeGraph,
302    NetworkGraph,
303    TreeGraph,
304    FlowChart,
305}
306
307#[derive(Debug, Clone, Serialize, Deserialize)]
308pub struct GraphData {
309    pub nodes: Vec<GraphNode>,
310    pub edges: Vec<GraphEdge>,
311}
312
313#[derive(Debug, Clone, Serialize, Deserialize)]
314pub struct GraphNode {
315    pub id: String,
316    pub label: String,
317    pub node_type: String,
318    pub properties: HashMap<String, serde_json::Value>,
319}
320
321#[derive(Debug, Clone, Serialize, Deserialize)]
322pub struct GraphEdge {
323    pub source: String,
324    pub target: String,
325    pub label: Option<String>,
326    pub edge_type: String,
327    pub properties: HashMap<String, serde_json::Value>,
328}
329
330#[derive(Debug, Clone, Serialize, Deserialize)]
331pub struct GraphLayout {
332    pub algorithm: String,
333    pub parameters: HashMap<String, serde_json::Value>,
334}
335
336#[derive(Debug, Clone, Serialize, Deserialize)]
337pub struct GraphStyling {
338    pub node_colors: HashMap<String, String>,
339    pub edge_colors: HashMap<String, String>,
340    pub theme: String,
341}
342
343#[derive(Debug, Clone, Serialize, Deserialize)]
344pub enum ChartType {
345    Line,
346    Bar,
347    Pie,
348    Scatter,
349    Histogram,
350    Heatmap,
351}
352
353#[derive(Debug, Clone, Serialize, Deserialize)]
354pub struct ChartData {
355    pub datasets: Vec<ChartDataset>,
356    pub labels: Vec<String>,
357}
358
359#[derive(Debug, Clone, Serialize, Deserialize)]
360pub struct ChartDataset {
361    pub label: String,
362    pub data: Vec<f64>,
363    pub color: Option<String>,
364}
365
366#[derive(Debug, Clone, Serialize, Deserialize)]
367pub struct ChartAxes {
368    pub x_axis: AxisConfig,
369    pub y_axis: AxisConfig,
370}
371
372#[derive(Debug, Clone, Serialize, Deserialize)]
373pub struct AxisConfig {
374    pub label: String,
375    pub scale: AxisScale,
376    pub range: Option<(f64, f64)>,
377}
378
379#[derive(Debug, Clone, Serialize, Deserialize)]
380pub enum AxisScale {
381    Linear,
382    Logarithmic,
383    Time,
384}
385
386#[derive(Debug, Clone, Serialize, Deserialize)]
387pub struct ChartStyling {
388    pub theme: String,
389    pub colors: Vec<String>,
390    pub font_family: String,
391    pub font_size: u32,
392}
393
394#[derive(Debug, Clone, Serialize, Deserialize)]
395pub struct FilePreview {
396    pub preview_type: PreviewType,
397    pub content: String,
398    pub thumbnail_url: Option<String>,
399}
400
401#[derive(Debug, Clone, Serialize, Deserialize)]
402pub enum PreviewType {
403    Text,
404    Image,
405    Audio,
406    Video,
407    Document,
408}
409
410#[derive(Debug, Clone, Serialize, Deserialize)]
411pub enum WidgetType {
412    Button,
413    Slider,
414    TextInput,
415    Dropdown,
416    Checkbox,
417    DatePicker,
418    Custom(String),
419}
420
421#[derive(Debug, Clone, Serialize, Deserialize)]
422pub struct WidgetConfig {
423    pub interactive: bool,
424    pub callback_url: Option<String>,
425    pub validation: Option<ValidationConfig>,
426    pub styling: HashMap<String, serde_json::Value>,
427}
428
429#[derive(Debug, Clone, Serialize, Deserialize)]
430pub struct ValidationConfig {
431    pub required: bool,
432    pub pattern: Option<String>,
433    pub min_length: Option<usize>,
434    pub max_length: Option<usize>,
435}
436
437#[derive(Debug, Clone, Serialize, Deserialize)]
438pub struct TimelineEvent {
439    pub id: String,
440    pub title: String,
441    pub description: Option<String>,
442    pub timestamp: chrono::DateTime<chrono::Utc>,
443    pub duration: Option<chrono::Duration>,
444    pub event_type: String,
445    pub metadata: HashMap<String, serde_json::Value>,
446}
447
448#[derive(Debug, Clone, Serialize, Deserialize)]
449pub struct TimelineRange {
450    pub start: chrono::DateTime<chrono::Utc>,
451    pub end: chrono::DateTime<chrono::Utc>,
452    pub zoom_level: TimelineZoom,
453}
454
455#[derive(Debug, Clone, Serialize, Deserialize)]
456pub enum TimelineZoom {
457    Minute,
458    Hour,
459    Day,
460    Week,
461    Month,
462    Year,
463}
464
465#[derive(Debug, Clone, Serialize, Deserialize)]
466pub struct TimelineStyling {
467    pub theme: String,
468    pub event_colors: HashMap<String, String>,
469    pub show_grid: bool,
470    pub compact_view: bool,
471}