Skip to content

Release 2.3.0: advisor plugins and advice protocol v2 - #45

Open
egno wants to merge 5 commits into
mainfrom
refactor/advisor-plugins
Open

egno wants to merge 5 commits into
mainfrom
refactor/advisor-plugins

Conversation

@egno

@egno egno commented Nov 5, 2026 •

Copy link
Copy Markdown
Owner

What

Replaces the built-in AI coach with a general advice system, and makes the advice evidence-based.

  • Advisor plugins. An advisor (rules, local model, LLM) is a function from an AdvisorContext to a LessonAdvice. Plugins register through the keystrike.advisors entry point and import only keystrike.plugin_api. The core validates every advice and applies it as a bounded tie-breaker. It never delays an unlock, names a locked key, or moves weights out of bounds.
  • Default advisor. A local rules advisor. The LLM advisor moves to a separate package, packages/keystrike-ai (uv workspace). It sends data off the device, so Keystrike asks for a one-time confirmation.
  • Advice protocol v2 (plugin API version 2). Typed recommendations (focus, focus_pair, emphasize, ease, contrast) with a reason and evidence. Evidence floor, a key budget, one key per recommendation, and a summary written by the core. A contrast needs 3 events in 2 sessions and favours words with both keys of a mixed-up pair.
  • Timing from raw keystroke files. Speed is judged on the median of clean presses (no rollover, no first press of a session, none after an error or a space), not the mean.
  • Recency decay. Session i weighs recency_decay ** i (default 0.85, in advisors.toml). Exact counts stay the evidence.
  • Fix: errors counted once per position. The cursor stays on a character after a mistake, so retries are not new mistypes.
  • Practice screen. Shows the stored advice as soon as it opens, names the advisor on the first line, and says when advice will come.
  • Session header and raw files. advice_source and advice_kinds in the header. Each raw keystroke file starts with a header line (layout, start, end).
  • Dev tooling. scripts/replay_advice.py (read-only; --decay compares recency settings).
  • Docs, a new Advisors wiki page, and the CHANGELOG are updated. Version 2.3.0.

Notes for review

  • Design: docs/ADVISOR-PLUGINS.md (plugin architecture) and docs/ADVICE-PROTOCOL.md (protocol v2, including the corrections found by an independent two-model review).
  • Behaviour change: the default advisor is now rules, so existing users get rules-based advice. Off is one select away. An old ai.toml is read once as the llm advisor's settings (already confirmed).
  • keystrike-ai is not on PyPI and publish.yml builds only the main package. The docs say "install from a clone".
  • The macOS snapshot job failed on the first push: an idle advice panel took one blank row on the practice screen (it dates from the AI coach commits already on this branch). Fixed in the second commit by hiding the panel while it has nothing to show. The snapshot baseline is unchanged and passes.

Checks

1000 tests, ruff and pyright pass locally. The wheel and sdist build for both packages.

After merge: tag v2.3.0 and publish the GitHub release (that runs publish.yml and uploads to PyPI).

🤖 Generated with Claude Code

egno and others added 5 commits November 4, 2026 20:54
- Coach focus picks only among the engine's current-stage candidates, so
  unlocks are never delayed; FocusReason.coach marks its picks ("ai wk").
- One analysis at a time; sessions finished meanwhile fold into one
  follow-up request instead of cancelling the slow one.
- Last good analysis kept per layout (cache/ai_coach.json) across failures
  and restarts.
- Clients moved to infrastructure/ai_clients.py: Ollama and new
  OpenAI-compatible client, both with structured JSON output.
- Richer prompt: goal, unlocked/newest key, error-rate ranking, confidence,
  mistypes and per-finger errors from the raw keystroke archive.
- AI settings in a local, unsynced ai.toml with a Settings-screen section
  and Ctrl+T connection test; API key from KEYSTRIKE_AI_API_KEY only.
- Raw keystrokes kept only for each layout's confidence window and deleted
  when the coach is off.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Proposes replacing the built-in AI coach with a general advice system:
advisors (rules, local ML, LLM) are functions registered through a
registry + entry-point loader, while the core keeps validation, the
tie-breaker rule, scheduling, persistence, privacy controls and all UI.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Advisor plugins and advice protocol v2.

- Replace the built-in AI coach with a general advice system. An advisor
  (rules, local model, LLM) is a function from an AdvisorContext to a
  LessonAdvice. The core validates every advice, applies it as a bounded
  tie-breaker, and never lets it delay an unlock. Plugins register through
  the keystrike.advisors entry point and import only keystrike.plugin_api.
- Add a local rules advisor as the default; move the LLM advisor to the
  separate package packages/keystrike-ai (uv workspace).
- Advice protocol v2 (plugin API version 2): typed recommendations (focus,
  focus_pair, emphasize, ease, contrast) with a reason and evidence, an
  evidence floor, a key budget, one key per recommendation, and a summary
  written by the core. A contrast needs 3 events in 2 sessions and favours
  words with both keys of a mixed-up pair.
- Timing from the raw keystroke files: the median of clean presses (no
  rollover, no first press of a session, none after an error or a space),
  judged on recent sessions. Speed advice no longer follows the mean, which
  a few long pauses pull up. Space timing is reported on its own.
- Recency decay: session i weighs recency_decay ** i (default 0.85, in
  advisors.toml). Exact counts stay the evidence; recency ranks and scales.
- Count errors once per position in keystroke insights: the cursor stays on
  a character after a mistake, so retries are not new mistypes.
- Practice screen: show the stored advice as soon as it opens, name the
  advisor on the first line of the panel, and say when advice will come.
- Record advice_source and advice_kinds in the session header; write a header
  line (layout, start, end) at the top of each raw keystroke file.
- Ctrl+T in Settings tests the selected advisor on sample data (which now
  has timing); the LLM plugin judges speed on the same median rule.
- Add scripts/replay_advice.py (read-only; --decay compares recency settings).
- Refresh README and the wiki (new Advisors page), the design docs and the
  CHANGELOG; bump to 2.3.0.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
An idle advice panel still took one blank row on the practice screen, so the
practice-screen snapshot differed from main (the AI coach commits added the
panel without updating it). Hide the panel in the idle state; it shows again
for waiting, thinking and advice. With the advisor off the layout is the same
as before, and the snapshot baseline is unchanged.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant