feature/persona-fk-and-guard #90
@@ -1558,7 +1558,7 @@ Return ONLY the summary, nothing else."#,
|
|||||||
) -> String {
|
) -> String {
|
||||||
let result = match tool_name {
|
let result = match tool_name {
|
||||||
"search_rag" => self.tool_search_rag(arguments, ollama, cx).await,
|
"search_rag" => self.tool_search_rag(arguments, ollama, cx).await,
|
||||||
"search_messages" => self.tool_search_messages(arguments).await,
|
"search_messages" => self.tool_search_messages(arguments, cx).await,
|
||||||
"get_sms_messages" => self.tool_get_sms_messages(arguments, cx).await,
|
"get_sms_messages" => self.tool_get_sms_messages(arguments, cx).await,
|
||||||
"get_calendar_events" => self.tool_get_calendar_events(arguments, cx).await,
|
"get_calendar_events" => self.tool_get_calendar_events(arguments, cx).await,
|
||||||
"get_location_history" => self.tool_get_location_history(arguments, cx).await,
|
"get_location_history" => self.tool_get_location_history(arguments, cx).await,
|
||||||
@@ -1807,15 +1807,43 @@ Return ONLY the summary, nothing else."#,
|
|||||||
/// Tool: search_messages — keyword / semantic / hybrid search over all
|
/// Tool: search_messages — keyword / semantic / hybrid search over all
|
||||||
/// SMS message bodies via the Django FTS5 + embeddings pipeline. Now
|
/// SMS message bodies via the Django FTS5 + embeddings pipeline. Now
|
||||||
/// supports optional `contact_id`, `start_ts`, `end_ts` filters.
|
/// supports optional `contact_id`, `start_ts`, `end_ts` filters.
|
||||||
async fn tool_search_messages(&self, args: &serde_json::Value) -> String {
|
async fn tool_search_messages(&self, args: &serde_json::Value, cx: &opentelemetry::Context) -> String {
|
||||||
let query = match args.get("query").and_then(|v| v.as_str()) {
|
let query = match args.get("query").and_then(|v| v.as_str()) {
|
||||||
Some(q) if !q.trim().is_empty() => q.trim(),
|
Some(q) if !q.trim().is_empty() => q.trim(),
|
||||||
_ => {
|
_ => {
|
||||||
let has_date = args.get("date").is_some()
|
// Common LLM mistake: calling search_messages with
|
||||||
|| args.get("start_ts").is_some()
|
// { date, ... } as if it were date-browsing. The two
|
||||||
|| args.get("end_ts").is_some();
|
// tools share the "messages" word, and search_messages
|
||||||
let has_contact = args.get("contact").is_some() || args.get("contact_id").is_some();
|
// sounds like the natural verb. Instead of returning
|
||||||
if has_date || has_contact {
|
// an error and burning a turn, transparently route to
|
||||||
|
// get_sms_messages when there's a `date` (and a
|
||||||
|
// contact-name string, optional). The LLM gets real
|
||||||
|
// data on its first try; the result is logged with a
|
||||||
|
// routing note so a human reading the trace can see
|
||||||
|
// what happened.
|
||||||
|
let has_date_str = args
|
||||||
|
.get("date")
|
||||||
|
.and_then(|v| v.as_str())
|
||||||
|
.map(|s| !s.trim().is_empty())
|
||||||
|
.unwrap_or(false);
|
||||||
|
let has_numeric_contact = args.get("contact_id").is_some();
|
||||||
|
let has_ts_window =
|
||||||
|
args.get("start_ts").is_some() || args.get("end_ts").is_some();
|
||||||
|
if has_date_str && !has_numeric_contact && !has_ts_window {
|
||||||
|
log::info!(
|
||||||
|
"search_messages with `date` and no `query` — routing to get_sms_messages"
|
||||||
|
);
|
||||||
|
let routed = self.tool_get_sms_messages(args, cx).await;
|
||||||
|
return format!(
|
||||||
|
"(Note: routed to get_sms_messages — search_messages requires a \
|
||||||
|
`query`; date-only browsing belongs on get_sms_messages. Prefer \
|
||||||
|
get_sms_messages directly next time.)\n\n{}",
|
||||||
|
routed
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let has_contact_name =
|
||||||
|
args.get("contact").and_then(|v| v.as_str()).is_some();
|
||||||
|
if has_ts_window || has_numeric_contact || has_contact_name {
|
||||||
return "Error: search_messages needs a 'query' (keywords/phrase). \
|
return "Error: search_messages needs a 'query' (keywords/phrase). \
|
||||||
To fetch messages around a date or from a contact without keywords, \
|
To fetch messages around a date or from a contact without keywords, \
|
||||||
call get_sms_messages with { date, contact? } instead."
|
call get_sms_messages with { date, contact? } instead."
|
||||||
|
|||||||
Reference in New Issue
Block a user