From dc998c112893c7b1dd3665485c99ad83f6ef14c3 Mon Sep 17 00:00:00 2001 From: Yurii214 <216080096+Yurii214@users.noreply.github.com> Date: Thu, 30 Jul 2026 04:37:33 +0000 Subject: [PATCH 1/2] fix(quick-router): route "i've got a meeting/appointment" to memory_store the appointment/meeting assertion in personal_fact_store_request accepted only "i have a"/"i have an"; the equally common contraction "i've got a" (normalized to "i ve got a") fell through to the llm, and the dentist form even misrouted to memory_recall. accept the contraction, same as "i have a". --- crates/genie-core/src/tools/quick.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/crates/genie-core/src/tools/quick.rs b/crates/genie-core/src/tools/quick.rs index c639e45f..e92e6b54 100644 --- a/crates/genie-core/src/tools/quick.rs +++ b/crates/genie-core/src/tools/quick.rs @@ -1367,6 +1367,8 @@ fn personal_fact_store_request(text: &str) -> Option<(&'static str, String)> { if let Some(rest) = text .strip_prefix("i have a ") .or_else(|| text.strip_prefix("i have an ")) + .or_else(|| text.strip_prefix("i ve got a ")) + .or_else(|| text.strip_prefix("i ve got an ")) && (rest.contains("appointment") || rest.contains("meeting")) { return Some(("reminders", format!("calendar event: {}", rest.trim()))); @@ -6446,6 +6448,31 @@ mod tests { assert_eq!(call.arguments["entity"], "please light"); } + #[test] + fn routes_ive_got_appointment_to_memory_store() { + // "i've got a meeting/appointment" is the same calendar assertion as + // "i have a meeting/appointment", which already routes — the contraction + // (normalized to "i ve got a") fell through to the LLM, and the dentist + // form even misrouted to memory_recall. + let call = route("I've got a meeting on Saturday 10AM").unwrap(); + assert_eq!(call.name, "memory_store"); + assert_eq!(call.arguments["category"], "reminders"); + assert_eq!( + call.arguments["content"], + "calendar event: meeting on saturday 10am" + ); + + let call = route("I've got a dentist appointment on Friday").unwrap(); + assert_eq!(call.name, "memory_store"); + assert_eq!( + call.arguments["content"], + "calendar event: dentist appointment on friday" + ); + + // a non-appointment "i've got" is not a calendar event and still abstains. + assert!(route("I've got a cold").is_none()); + } + #[test] fn routes_personal_write_statements_to_memory_store() { // #379: first-person fact/appointment statements the deterministic router From b4529155fbe579668e572bc8480c74b8eb76287d Mon Sep 17 00:00:00 2001 From: Yurii214 <216080096+Yurii214@users.noreply.github.com> Date: Fri, 31 Jul 2026 17:36:12 +0000 Subject: [PATCH 2/2] test(quick-router): cover the an-branch and negative abstentions adds an "i've got an appointment" case for the new "an" prefix and extends the abstention check to "i've got a question for you" and "i've got an idea", per review. behaviour unchanged; test coverage only. --- crates/genie-core/src/tools/quick.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/crates/genie-core/src/tools/quick.rs b/crates/genie-core/src/tools/quick.rs index e92e6b54..fc136bd4 100644 --- a/crates/genie-core/src/tools/quick.rs +++ b/crates/genie-core/src/tools/quick.rs @@ -6469,8 +6469,19 @@ mod tests { "calendar event: dentist appointment on friday" ); + // the "an" prefix branch must route the same as "a". + let call = route("I've got an appointment on Monday").unwrap(); + assert_eq!(call.name, "memory_store"); + assert_eq!(call.arguments["category"], "reminders"); + // a non-appointment "i've got" is not a calendar event and still abstains. - assert!(route("I've got a cold").is_none()); + for utterance in [ + "I've got a cold", + "I've got a question for you", + "I've got an idea", + ] { + assert!(route(utterance).is_none(), "{utterance:?}"); + } } #[test]