feat: expand insight tool result caps and render timestamps in local time

Doubled default row caps for search_rag/get_sms_messages/get_calendar_events/recall_entities and exposed an optional `limit` parameter on each so the agent can tune per call. Render all LLM-facing timestamps as server-local time with explicit offset so smaller models stop misreading UTC as wall-clock time.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Cameron
2026-04-19 20:17:12 -04:00
committed by cameron
parent 3027a3ffda
commit a35b45fd36

View File

@@ -440,7 +440,11 @@ impl InsightGenerator {
.iter()
.map(|e| {
let date = DateTime::from_timestamp(e.start_time, 0)
.map(|dt| dt.format("%Y-%m-%d %H:%M").to_string())
.map(|dt| {
dt.with_timezone(&Local)
.format("%Y-%m-%d %H:%M %:z")
.to_string()
})
.unwrap_or_else(|| "unknown".to_string());
let attendees = e
@@ -1354,7 +1358,11 @@ Return ONLY the summary, nothing else."#,
.map(|m| {
let sender = if m.is_sent { "Me" } else { &m.contact };
let timestamp = chrono::DateTime::from_timestamp(m.timestamp, 0)
.map(|dt| dt.format("%Y-%m-%d %H:%M").to_string())
.map(|dt| {
dt.with_timezone(&Local)
.format("%Y-%m-%d %H:%M %:z")
.to_string()
})
.unwrap_or_else(|| "unknown time".to_string());
format!("[{}] {}: {}", timestamp, sender, m.body)
})
@@ -1449,16 +1457,22 @@ Return ONLY the summary, nothing else."#,
.get("contact")
.and_then(|v| v.as_str())
.map(|s| s.to_string());
let limit = args
.get("limit")
.and_then(|v| v.as_i64())
.unwrap_or(10)
.clamp(1, 25) as usize;
log::info!(
"tool_search_rag: query='{}', date={}, contact={:?}",
"tool_search_rag: query='{}', date={}, contact={:?}, limit={}",
query,
date,
contact
contact,
limit
);
match self
.find_relevant_messages_rag(date, None, contact.as_deref(), None, 5, Some(&query))
.find_relevant_messages_rag(date, None, contact.as_deref(), None, limit, Some(&query))
.await
{
Ok(results) if !results.is_empty() => results.join("\n\n"),
@@ -1485,6 +1499,11 @@ Return ONLY the summary, nothing else."#,
.get("days_radius")
.and_then(|v| v.as_i64())
.unwrap_or(4);
let limit = args
.get("limit")
.and_then(|v| v.as_i64())
.unwrap_or(60)
.clamp(1, 150) as usize;
let date = match NaiveDate::parse_from_str(date_str, "%Y-%m-%d") {
Ok(d) => d,
@@ -1493,10 +1512,11 @@ Return ONLY the summary, nothing else."#,
let timestamp = date.and_hms_opt(12, 0, 0).unwrap().and_utc().timestamp();
log::info!(
"tool_get_sms_messages: date={}, contact={:?}, days_radius={}",
"tool_get_sms_messages: date={}, contact={:?}, days_radius={}, limit={}",
date,
contact,
days_radius
days_radius,
limit
);
match self
@@ -1507,11 +1527,15 @@ Return ONLY the summary, nothing else."#,
Ok(messages) if !messages.is_empty() => {
let formatted: Vec<String> = messages
.iter()
.take(30)
.take(limit)
.map(|m| {
let sender = if m.is_sent { "Me" } else { &m.contact };
let ts = DateTime::from_timestamp(m.timestamp, 0)
.map(|dt| dt.format("%Y-%m-%d %H:%M").to_string())
.map(|dt| {
dt.with_timezone(&Local)
.format("%Y-%m-%d %H:%M %:z")
.to_string()
})
.unwrap_or_else(|| "unknown".to_string());
format!("[{}] {}: {}", ts, sender, m.body)
})
@@ -1544,6 +1568,11 @@ Return ONLY the summary, nothing else."#,
.get("days_radius")
.and_then(|v| v.as_i64())
.unwrap_or(7);
let limit = args
.get("limit")
.and_then(|v| v.as_i64())
.unwrap_or(20)
.clamp(1, 50) as usize;
let date = match NaiveDate::parse_from_str(date_str, "%Y-%m-%d") {
Ok(d) => d,
@@ -1552,9 +1581,10 @@ Return ONLY the summary, nothing else."#,
let timestamp = date.and_hms_opt(12, 0, 0).unwrap().and_utc().timestamp();
log::info!(
"tool_get_calendar_events: date={}, days_radius={}",
"tool_get_calendar_events: date={}, days_radius={}, limit={}",
date,
days_radius
days_radius,
limit
);
let events = {
@@ -1562,7 +1592,7 @@ Return ONLY the summary, nothing else."#,
.calendar_dao
.lock()
.expect("Unable to lock CalendarEventDao");
dao.find_relevant_events_hybrid(cx, timestamp, days_radius, None, 10)
dao.find_relevant_events_hybrid(cx, timestamp, days_radius, None, limit)
.ok()
};
@@ -1572,7 +1602,11 @@ Return ONLY the summary, nothing else."#,
.iter()
.map(|e| {
let dt = DateTime::from_timestamp(e.start_time, 0)
.map(|dt| dt.format("%Y-%m-%d %H:%M").to_string())
.map(|dt| {
dt.with_timezone(&Local)
.format("%Y-%m-%d %H:%M %:z")
.to_string()
})
.unwrap_or_else(|| "unknown".to_string());
let loc = e
.location
@@ -1644,7 +1678,11 @@ Return ONLY the summary, nothing else."#,
.take(20)
.map(|loc| {
let dt = DateTime::from_timestamp(loc.timestamp, 0)
.map(|dt| dt.format("%Y-%m-%d %H:%M").to_string())
.map(|dt| {
dt.with_timezone(&Local)
.format("%Y-%m-%d %H:%M %:z")
.to_string()
})
.unwrap_or_else(|| "unknown".to_string());
let activity = loc
.activity
@@ -1753,7 +1791,11 @@ Return ONLY the summary, nothing else."#,
.get("entity_type")
.and_then(|v| v.as_str())
.map(|s| s.to_string());
let limit = args.get("limit").and_then(|v| v.as_i64()).unwrap_or(10);
let limit = args
.get("limit")
.and_then(|v| v.as_i64())
.unwrap_or(20)
.clamp(1, 50);
log::info!(
"tool_recall_entities: name={:?}, type={:?}, limit={}",
@@ -2106,6 +2148,10 @@ Return ONLY the summary, nothing else."#,
"contact": {
"type": "string",
"description": "Optional contact name to filter results"
},
"limit": {
"type": "integer",
"description": "Maximum number of results to return (default: 10, max: 25)"
}
}
}),
@@ -2128,6 +2174,10 @@ Return ONLY the summary, nothing else."#,
"days_radius": {
"type": "integer",
"description": "Number of days before and after the date to search (default: 4)"
},
"limit": {
"type": "integer",
"description": "Maximum number of messages to return (default: 60, max: 150)"
}
}
}),
@@ -2146,6 +2196,10 @@ Return ONLY the summary, nothing else."#,
"days_radius": {
"type": "integer",
"description": "Number of days before and after the date to search (default: 7)"
},
"limit": {
"type": "integer",
"description": "Maximum number of events to return (default: 20, max: 50)"
}
}
}),
@@ -2221,7 +2275,7 @@ Return ONLY the summary, nothing else."#,
},
"limit": {
"type": "integer",
"description": "Maximum number of results to return (default: 10)"
"description": "Maximum number of results to return (default: 20, max: 50)"
}
}
}),