Skip to content

fix(quick-router): accept a leading please on home_control commands - #922

Open
galuis116 wants to merge 2 commits into
GeniePod:mainfrom
galuis116:fix/home-control-leading-please
Open

fix(quick-router): accept a leading please on home_control commands#922
galuis116 wants to merge 2 commits into
GeniePod:mainfrom
galuis116:fix/home-control-leading-please

Conversation

@galuis116

@galuis116 galuis116 commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes #919. Every home_control matcher in the quick-router is anchored at
token 0, so a single leading please shifted the anchor and the most common
polite actuation forms fell through to the LLM — even though their bare
counterparts already route. This was the last unguarded intent family: scene/
routine (#894), play_media, shopping list (#843), news (#908), and time/date
(#906) all strip a leading please already; home_control, the
highest-frequency actuation intent, did not.

utterance before after
Please turn off the kitchen lights ABSTAIN home_control{kitchen lights, turn_off}
Please turn off the lights ABSTAIN home_control{lights, turn_off}
Please turn on the bedroom lamp ABSTAIN home_control{bedroom lamp, turn_on}
Please turn on the fan ABSTAIN home_control{fan, turn_on}
Please turn off the TV ABSTAIN home_control{tv, turn_off}
Please start the dishwasher ABSTAIN home_control{dishwasher normal cycle, activate}
Please set the thermostat to 68 ABSTAIN home_control{thermostat, set_temperature, 68}
Please preheat the oven to 400 ABSTAIN home_control{oven, set_temperature, 400}

Changes

  • Strip a single leading please at the top of home_control_request,
    mirroring scene_or_routine_activation_request and play_media_request,
    which strip it for exactly this reason. A trailing please was already
    dropped by clean_control_entity.
  • Same strip in priority_home_control_request. Most of its arms are
    contains tests that survive a leading token, but run movie night and
    warm up the car are exact matches that do not — and the two entry points
    should not disagree about politeness.
  • The strip sits at the top of each function rather than inside each arm, so
    every existing guard keeps applying to the stripped text: the in <duration>
    schedule guard, the multi-clause / except / only / and abstention, and
    the known-device gate.
  • New regression test home_control_accepts_a_leading_please covering the
    eight polite forms above plus four abstention negatives.
  • Updated one assertion in scene_activation_accepts_a_leading_please. It read
    route("please turn on the lights").is_none(). Its stated point is that a
    device command must not be claimed as a scene activation — that still
    holds, and now holds more strongly, because the call falls past the scene
    matcher and lands on home_control{lights, turn_on}. The assertion now
    checks that outcome instead of the absence of any route.

Real Behavior Proof

  • I have built and run the affected code locally (or noted why I could not).
  • I have verified the change end-to-end on Jetson hardware.
  • I have NOT verified on Jetson hardware, and I explain the equivalent verification path or validation gap below.

Tested profile / hardware (check all that apply):

  • jetson
  • raspberry_pi
  • portable_sbc
  • laptop
  • mac
  • CI-only / docs-only
  • Not run locally

What I ran

x86_64 Linux laptop (Ubuntu 22.04 LTS, kernel 6.8.0-136-generic,
rustc 1.96.0 / cargo 1.96.0). No Jetson and no live Home Assistant instance
available to me — see the validation gap below.

cargo test -p genie-core
cargo clippy -p genie-core --all-targets
cargo fmt -p genie-core -- --check

Plus a temporary probe binding route() directly over the affected utterances,
to read the emitted ToolCall rather than trusting the assertions alone. The
probe was removed before committing; only the permanent regression test
remains.

What I observed

cargo test -p genie-core: 1005 lib tests passed, 0 failed, 6 ignored, and
all integration suites green. home_control_accepts_a_leading_please passes
here; on main it fails on the first case. cargo clippy --all-targets
produced no warnings; cargo fmt --check produced no diff.

Probe output on this branch:

please turn off the kitchen lights     -> home_control {"action":"turn_off","entity":"kitchen lights"}
please turn on the bedroom lamp        -> home_control {"action":"turn_on","entity":"bedroom lamp"}
please set the thermostat to 68        -> home_control {"action":"set_temperature","entity":"thermostat","value":68}
please preheat the oven to 400         -> home_control {"action":"set_temperature","entity":"oven","value":400}
please start the dishwasher            -> home_control {"action":"activate","entity":"dishwasher normal cycle"}
please turn on the lights in 5 minutes -> ABSTAIN
please turn on the infant monitor      -> ABSTAIN

Every one of the first five printed ABSTAIN on main. The last two are the
guards: the schedule guard and the known-device gate still fire on the polite
form, so stripping please does not trade one wrong answer for another.

Validation gap

I could not verify on Jetson hardware or against a live Home Assistant. The
equivalent verification path: this change is confined to
crates/genie-core/src/tools/quick.rs, a pure string→ToolCall function with
no I/O, no async, no hardware dependency, and no model involvement. Its entire
contract is which ToolCall comes out for a given utterance, which the tests
above assert directly. The emitted call is byte-identical to the one the bare
utterance already produces and already dispatches on Jetson today — so the HA
dispatch path downstream sees nothing it has not seen before. Nothing in the
diff touches audio, the dashboard, or the model prompt.

Test plan

  1. git checkout main && cargo test -p genie-core --lib home_control_accepts_a_leading_please — fails (test absent on main; cherry-pick the test alone to see it fail).
  2. Check out this branch, rerun — passes.
  3. On a Jetson with Home Assistant wired up, say "please turn off the kitchen
    lights" and confirm the light actuates without an LLM round-trip, then say
    "please turn on the lights in 5 minutes" and confirm it still falls through
    to the LLM rather than firing now.

Notes for reviewers

  • No prompt growth, no new dependencies. The 4096-token Jetson context contract
    is untouched.
  • Behavior is unchanged for every utterance that does not begin with please .
  • Only one leading please is stripped, deliberately — please please turn off the lights is not a real utterance, and a loop would be scope the bug does
    not justify.

Summary by CodeRabbit

  • New Features
    • Home automation commands now support polite variations with a "please" prefix, functioning identically to standard commands for more conversational interactions. Note: scheduled, multi-clause, and unknown-device commands are not supported.

Every home_control matcher is anchored at token 0 — the curated
exact-match device set, the starts_with arms, the `set `/`preheat `
setpoint parser, and simple_turn_request's "turn on "/"turn off "
prefixes. A single leading politeness token shifted that anchor, so the
most common polite actuation forms fell through to the LLM even though
their bare counterparts already route:

  "please turn off the kitchen lights"  -> ABSTAIN
  "please set the thermostat to 68"     -> ABSTAIN
  "please preheat the oven to 400"      -> ABSTAIN
  "please start the dishwasher"         -> ABSTAIN

Strip a single leading "please " at the two home-control entry points,
mirroring scene_or_routine_activation_request and play_media_request,
which already strip it for the same reason. A trailing "please" was
already dropped by clean_control_entity.

The strip happens before the guards rather than inside each arm, so the
"in <duration>" schedule guard, the multi-clause/except/only/and
abstention, and the known-device gate all still apply to the stripped
text — "please turn on the lights in 5 minutes" keeps abstaining rather
than actuating now.

priority_home_control_request gets the same strip: its arms are mostly
contains tests that survive a leading token, but "run movie night" and
"warm up the car" are exact matches that do not.

The scene test's negative assertion for "please turn on the lights" is
updated: it was asserting the absence of a route, and its point — that a
device command is not claimed as a scene activation — now holds by the
call landing on home_control instead.

Closes GeniePod#919
@github-actions github-actions Bot added the bug Something isn't working label Jul 30, 2026
@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: fa448209-89ea-4ce7-bc8d-6fb5a4380be9

📥 Commits

Reviewing files that changed from the base of the PR and between 1bf9e4f and 3557368.

📒 Files selected for processing (1)
  • crates/genie-core/src/tools/quick.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • crates/genie-core/src/tools/quick.rs

📝 Walkthrough

Walkthrough

The quick router removes one leading "please " from priority and ordinary home-control requests. Tests cover polite actuation and setpoint commands while confirming that guarded requests still abstain.

Changes

Home-control politeness handling

Layer / File(s) Summary
Normalize polite home-control requests
crates/genie-core/src/tools/quick.rs
priority_home_control_request and home_control_request strip one leading "please " before matching commands, parsing setpoints, and applying abstention guards.
Validate polite routing
crates/genie-core/src/tools/quick.rs
Tests cover scenes, device actions, dishwasher activation, thermostat and oven setpoints, priority movie-night activation, schedules, multi-clause requests, and unknown devices.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related issues

Possibly related PRs

Suggested reviewers: matedev01

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes accepting a leading "please" in home-control commands.
Linked Issues check ✅ Passed The changes satisfy issue #919 by covering polite routing, priority handling, preserved abstentions, and focused regression tests.
Out of Scope Changes check ✅ Passed The changes remain within the linked issue scope and modify only quick-router behavior and related regression tests.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
crates/genie-core/src/tools/quick.rs (1)

1405-1411: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add regression coverage for the priority helper.

The new tests exercise standard home_control_request cases through route(...), but do not prove that priority_home_control_request handles a leading please. Add a direct test or a route phrase unique to this helper, such as please run movie night, so this second entry point is regression-tested.

Suggested test
+#[test]
+fn priority_home_control_accepts_a_leading_please() {
+    assert_eq!(
+        priority_home_control_request("please run movie night"),
+        Some(("movie night".into(), "activate", None))
+    );
+}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/genie-core/src/tools/quick.rs` around lines 1405 - 1411, Add
regression coverage for priority_home_control_request by testing a leading
“please” input, such as “please run movie night,” and asserting it routes
identically to the bare command. Keep the test focused on this helper rather
than only covering home_control_request through route(...).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@crates/genie-core/src/tools/quick.rs`:
- Around line 1405-1411: Add regression coverage for
priority_home_control_request by testing a leading “please” input, such as
“please run movie night,” and asserting it routes identically to the bare
command. Keep the test focused on this helper rather than only covering
home_control_request through route(...).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d9be7c03-6e70-42da-bc2f-7d0d7f65c192

📥 Commits

Reviewing files that changed from the base of the PR and between 02a577d and 1bf9e4f.

📒 Files selected for processing (1)
  • crates/genie-core/src/tools/quick.rs

Follow-up to the review on GeniePod#922.

The existing tests exercise home_control_request through route(), but
nothing proved priority_home_control_request handles a leading "please".
That is the second entry point and it runs earlier in dispatch, so it
needs its own coverage rather than inheriting confidence from the other.

"please run movie night" is the case that matters: almost every arm in
that helper is a `contains` test that survives a leading token, and this
exact-match arm is the reason the strip had to be added there at all.
The test also asserts the polite call equals the bare call by name and
arguments, not merely that some route exists.

"warm up the car" is the other exact-match arm and is deliberately not
tested: it returns None on main as well, because its remote_start action
does not survive canonicalize_household_action, so a leading "please"
changes nothing there. Noted in the test comment so the omission reads
as a decision rather than an oversight.

Tests only — no behavior change.
@galuis116

Copy link
Copy Markdown
Contributor Author

Addressed in the latest commit — added priority_home_control_accepts_a_leading_please, using please run movie night as suggested. It asserts the emitted call and that the polite form equals the bare form by name and arguments.

One note on scope: warm up the car is the other exact-match arm in that helper, and I deliberately left it untested. It returns None on main too — its remote_start action does not survive canonicalize_household_action, so the if let chain in route falls through. A leading please changes nothing there, and adding an assertion would have pinned unrelated pre-existing behavior. That reasoning is in the test comment so the omission reads as a decision rather than an oversight.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[bug] quick-router: a leading "please" on any home_control command falls through to the LLM

1 participant