codetether_agent/session/
title.rs1use anyhow::Result;
4use chrono::Utc;
5
6use super::helper::text::truncate_with_ellipsis;
7use super::types::Session;
8
9impl Session {
10 pub async fn generate_title(&mut self) -> Result<()> {
13 if self.title.is_some() {
14 return Ok(());
15 }
16 self.set_title_from_first_user_message();
17 Ok(())
18 }
19
20 pub async fn regenerate_title(&mut self) -> Result<()> {
23 self.set_title_from_first_user_message();
24 Ok(())
25 }
26
27 fn set_title_from_first_user_message(&mut self) {
28 let Some(msg) = self
29 .messages
30 .iter()
31 .find(|m| m.role == crate::provider::Role::User)
32 else {
33 return;
34 };
35 let text: String = msg
36 .content
37 .iter()
38 .filter_map(|p| match p {
39 crate::provider::ContentPart::Text { text } => Some(text.clone()),
40 _ => None,
41 })
42 .collect::<Vec<_>>()
43 .join(" ");
44 self.title = Some(truncate_with_ellipsis(&text, 47));
45 }
46
47 pub fn set_title(&mut self, title: impl Into<String>) {
49 self.title = Some(title.into());
50 self.updated_at = Utc::now();
51 }
52
53 pub fn clear_title(&mut self) {
56 self.title = None;
57 self.updated_at = Utc::now();
58 }
59
60 pub async fn on_context_change(&mut self, regenerate_title: bool) -> Result<()> {
63 self.updated_at = Utc::now();
64 if regenerate_title {
65 self.regenerate_title().await?;
66 }
67 Ok(())
68 }
69}