Skip to main content

crabtalk_runtime/
conversation.rs

1//! Conversation — pure working-context container.
2
3use crate::ConversationHandle;
4use std::time::Instant;
5use wcore::{model::HistoryEntry, storage::ConversationMeta};
6
7/// A conversation tied to a specific agent.
8///
9/// Pure working-context container. Persistence is delegated to the
10/// Storage trait via the session handle.
11#[derive(Debug, Clone)]
12pub struct Conversation {
13    /// Unique conversation identifier (monotonic counter, runtime-only).
14    pub id: u64,
15    /// Conversation history (the working context for the LLM).
16    pub history: Vec<HistoryEntry>,
17    /// Conversation title (set by the `set_title` tool).
18    pub title: String,
19    /// Accumulated active time in seconds.
20    pub uptime_secs: u64,
21    /// When this conversation was loaded/created in this process.
22    pub created_at: Instant,
23    /// Persistent conversation identity, assigned by the storage layer.
24    /// `None` until the first persistence call — and remains `None` for
25    /// tmp chats that never enter a topic.
26    pub handle: Option<ConversationHandle>,
27    /// Topic this conversation belongs to, if any. `None` = tmp chat
28    /// (no storage, no resume). Set by `switch_topic`.
29    pub topic: Option<String>,
30}
31
32impl Conversation {
33    /// Create a new conversation with an empty history.
34    pub fn new(id: u64) -> Self {
35        Self {
36            id,
37            history: Vec::new(),
38            title: String::new(),
39            uptime_secs: 0,
40            created_at: Instant::now(),
41            handle: None,
42            topic: None,
43        }
44    }
45
46    /// Build a [`ConversationMeta`] snapshot from this conversation's
47    /// current state.
48    pub fn meta(&self, agent: &str, created_by: &str) -> ConversationMeta {
49        ConversationMeta {
50            agent: agent.to_owned(),
51            created_by: created_by.to_owned(),
52            created_at: chrono::Utc::now().to_rfc3339(),
53            title: self.title.clone(),
54            uptime_secs: self.uptime_secs,
55            topic: self.topic.clone(),
56        }
57    }
58}