Add contact name filter to SMS search tool + misc improvements

- sms search tool: accept contact name, trim/validate, skip when
  contact_id is set, pass to API client
- sms_client: new contact field in SmsSearchParams, URL-encode on wire
- Tool description clarifies contact_id takes precedence when both given
- Add parse_title_body helper for LLM response parsing
- llamacpp backend improvements
This commit is contained in:
Cameron Cordes
2026-05-25 21:46:18 -04:00
parent b9175e2718
commit 0a627f4880
4 changed files with 165 additions and 67 deletions
+4 -29
View File
@@ -817,7 +817,8 @@ impl InsightChatService {
let mut amended_insight_id: Option<i32> = None;
if req.amend {
let title = self.generate_title(&backend, &final_content).await?;
let (title, body) = crate::ai::insight_generator::parse_title_body(&final_content);
let final_content = body;
// Amended rows intentionally do not inherit the parent's
// `fewshot_source_ids`. The parent's few-shot influence is still
@@ -1001,7 +1002,7 @@ impl InsightChatService {
final_content,
} = outcome;
let title = self.generate_title(&backend, &final_content).await?;
let (title, body) = crate::ai::insight_generator::parse_title_body(&final_content);
let json = serde_json::to_string(&messages)
.map_err(|e| anyhow!("failed to serialize chat history: {}", e))?;
@@ -1009,7 +1010,7 @@ impl InsightChatService {
library_id: req.library_id,
file_path: normalized.clone(),
title,
summary: final_content,
summary: body,
generated_at: Utc::now().timestamp(),
model_version: model_used.clone(),
is_current: true,
@@ -1045,32 +1046,6 @@ impl InsightChatService {
Ok(())
}
/// Generate a short title via the same chat backend so voice stays
/// consistent with the body. Mirrors generate_agentic_insight_for_photo's
/// titling pass.
async fn generate_title(
&self,
backend: &ResolvedBackend,
final_content: &str,
) -> Result<String> {
let title_prompt = format!(
"Create a short title (maximum 8 words) for the following journal entry:\n\n{}\n\n\
Capture the key moment or theme. Return ONLY the title, nothing else.",
final_content
);
let title_raw = backend
.chat()
.generate(
&title_prompt,
Some(
"You are my long term memory assistant. Use only the information provided. Do not invent details.",
),
None,
)
.await?;
Ok(title_raw.trim().trim_matches('"').to_string())
}
/// Drive the agentic loop with streaming SSE events. Shared between
/// bootstrap and continuation. Mutates `messages` in place (response
/// turns + tool results are appended) and returns counters + the