Skip to content

Match surrounding text when dictating at the caret - #8

Merged
Kuberwastaken merged 3 commits into
mainfrom
feat/caret-context
Jul 21, 2026
Merged

Match surrounding text when dictating at the caret#8
Kuberwastaken merged 3 commits into
mainfrom
feat/caret-context

Conversation

@Kuberwastaken

Copy link
Copy Markdown
Owner

Course correction: dictating mid-sentence no longer produces wrong capitalization at the seam.

  • AppContext.textBeforeCaret: ≤240 chars before the caret from the focused element (AX value + selected range), surrogate-pair-safe; nil for secure fields (role AND subrole checked), empty values, or caret at 0.
  • Cleanup prompt gains a one-line hint whose directive is decided in Swift (caretContinuesSentence): continue lowercase mid-sentence vs start a new sentence.
  • Key finding: the small model was not reliable at the seam from prompts alone — casing and dedup are guaranteed by deterministic, unit-tested post-passes (stripRepeatedCaretPrefix, harmonizeCaseWithCaretContext), both gated on caret context being present.
  • Baseline-verified: without caret context, output is byte-for-byte identical to current main.

Live-validated on-device (3/3 stable): "I think we should" + "definitely ship it" → stays lowercase; "Check the logs." + "we might need to roll back" → capitalized; proper nouns and "I" survive lowercasing.

Verified on macOS 26.5 (arm64): make test passes, full build clean. Manual QA: quirky AX trees (Electron) degrade to nil → unchanged behavior.

All eight feature PRs register tests in Tests/AppContextServiceTests.swift and some extend the Makefile test list, so each merge after the first needs a trivial conflict resolution there. Suggested merge order: dictionary-ranking → formality-dial → caret-context → transforms → scratch-that → raw-undo → rebindable-cancel → mouse-ptt.

Capture up to 240 characters immediately before the caret in the focused
editable element (AX value + selected-text-range; secure fields are never
read) and carry it through AppContext and SmartCleanupRequest into the
smart cleanup prompt. The hint tells the on-device model whether the
dictation continues a sentence (lowercase, no leading period) or starts a
new one (capitalized), decided deterministically in Swift because the
small model follows a concrete directive far better than a conditional
rule. The cleanup result is then post-processed deterministically: a
repeated before-caret prefix is stripped and the first letter's case is
harmonized with the seam, preserving proper nouns via the speaker's own
transcript casing.
@Kuberwastaken
Kuberwastaken merged commit 1aa86f4 into main Jul 21, 2026
1 check passed
@Kuberwastaken
Kuberwastaken deleted the feat/caret-context branch July 21, 2026 09:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant