Commit graph

5 commits

Author SHA1 Message Date
Bossiara13
94edb73f26 feat: Python parity for Wave 6-8 — memory admin / cooking / leftoff / trivia / routines
New module `wave68_handlers.py` (~270 lines) covering the Rust packs that
were Rust-only after Waves 6-8:

  - memory_admin: do_memory_count/list/wipe (with full RU plural decl.)
  - cooking: do_cooking + reusable match_recipe(phrase) for the 15-dish
    preset table. Schedules a "ready!" reminder via scheduler_store.
  - leftoff: do_leftoff stitches memory + scheduled tasks + last reply
    into a one-paragraph recap. Offline.
  - trivia: do_trivia random one-liner from RU/EN MCU pools.
  - routines: do_good_night (sleep profile + cancel one-shots),
    do_good_morning (default profile + agenda hint),
    do_coffee_break (5-min check-in via scheduler).

memory_store: new clear_all() returning removed count, atomic via _save.

extensions.py: imports + set_speak wiring + 9 proxy do_* fns.
main.py: 9 new dispatch elifs.
commands.yaml: 9 new entries (now 196 total).

tests/test_wave68_handlers.py: 15 unit tests covering each handler.
Test helper `_rewire()` re-imports state modules via the existing
isolated_state fixture then re-binds the wave68_handlers module-level
refs — fixes the gotcha where module-level imports cache the OLD
memory_store / scheduler_store instances from process startup.

Tests: 81 → 96 (+15).
2026-05-16 14:55:47 +03:00
Bossiara13
5265cb0fbe feat: Wave 5 Python parity — outlook COM + time tracker
Some checks are pending
Python CI / pytest (ubuntu-latest) (push) Waiting to run
Python CI / pytest (windows-latest) (push) Waiting to run
Python CI / ruff (push) Waiting to run
Outlook COM (`outlook_handlers.py`, agent):
- 4 handlers mirroring Rust pack: unread_count, latest, send_clipboard,
  summarize_inbox. Uses `win32com.client` with lazy import so the module
  loads even when pywin32 is missing — handlers degrade gracefully and
  speak a "Outlook недоступен" reply.
- `requirements.txt`: pywin32>=305 (optional).
- 7 unit tests mock `_outlook_session` via unittest.mock.

Time tracker (`time_tracker_handlers.py`, agent):
- 5 handlers: start, stop, today, week, reset. JSON store at
  `<here>/time_tracker.json`, atomic write-then-rename.
- Same shape as the Rust pack's `jarvis.state` blob: current_session_start
  + sessions[{start,end}]. Local-calendar today boundary.
- Full Russian pluralisation (час/часа/часов, минута/минуты/минут).
- 14 unit tests using the existing `isolated_state` fixture in conftest.py.

`extensions.py` + `main.py`: imports + 9 new proxy do_* functions + 9
new dispatch elifs. `commands.yaml`: 9 new entries.

Tests: 60 → 81 (+14 tracker + 7 outlook).
2026-05-16 14:34:44 +03:00
Bossiara13
45d9425ed7 feat: personality pack — Python parity
Some checks are pending
Python CI / pytest (ubuntu-latest) (push) Waiting to run
Python CI / pytest (windows-latest) (push) Waiting to run
Python CI / ruff (push) Waiting to run
Python parity for the 5 personality voice commands shipped on the
Rust side:

- New `personality_handlers.py` (~150 lines): do_personality_{greet,
  thanks, compliment, how_are_you, tony_quote}. Each picks one of
  7-10 phrases per language (RU/EN) at random; greet additionally
  buckets by time-of-day (morning/midday/evening/night).
- `extensions.py`: imports + 5 proxy `do_personality_*` functions
  pointing at the new module, plus set_speak wiring so handlers can
  TTS via the runtime's voice.
- `main.py`: 5 new dispatch elifs feeding the new action types.
- `commands.yaml`: 5 new entries (`personality_*`) mapping voice
  phrases to action types.
- `tests/test_personality_handlers.py`: 6 unit tests confirming
  each handler returns a non-empty string from the expected pool.
- `.gitignore`: stop tracking runtime state generated by tests
  (profiles/, long_term_memory.json, schedule.json, macros.json,
  llm_backend.txt, llm_history.json) — these are user data, not
  source.

Tests: 54 → 60 (+6).
2026-05-16 13:53:44 +03:00
Bossiara13
59a1258dcc feat: Wave 3 — plugin loader + Flet GUI (parity with Rust fork)
Plugin loader (mirrors Rust #29):
- plugins_store.py walks %APPDATA%\com.priler.jarvis\plugins\<name>\
  for commands.yaml fragments and merges them into VA_CMD_LIST at
  startup. Same schema as the project root commands.yaml. Per-pack
  `disabled` flag file skips a pack without deletion. Built-in ids
  win conflicts so a malicious pack can't silently override
  open_browser. 9 unit tests (parity with the Rust tests).
- main.py: plugin merge runs after the root yaml load; logs the
  number of extra commands picked up.

Flet GUI (#27 — first parity with the Rust Tauri GUI):
- New gui/ package: __main__.py launches via `python -m gui` (or
  gui.bat). app.py routes between 7 pages (Главная / Команды /
  Макросы / Расписание / Память / Плагины / Настройки) via
  NavigationRail; dark theme matching the Tauri look.
- gui/services.py centralises every store-module call the pages
  share — single place to swap implementations later.
- One file per page in gui/pages/, all expose `build(page)` and use
  the same card layout idiom. Pages mirror the Tauri ones feature-
  for-feature: home (status + counters + launcher), commands
  (filterable list of all VA_CMD_LIST entries), macros (list +
  delete + recording banner), scheduler (list + remove), memory
  (add/forget/search), plugins (toggle/open folder), settings
  (profile + LLM hot-swap).
- requirements.txt: flet>=0.85 (optional; assistant runs without).
- 3 smoke tests verify imports + build callables; skip cleanly when
  Flet isn't installed.

README: documents both the GUI and the plugin layout in user-facing
terms. Tests: 42 → 54 (+9 plugins +3 GUI smoke).
2026-05-16 13:27:04 +03:00
Bossiara13
4e62049a98 feat+test: pytest suite + Now Playing + World Clock + Daily Quote packs (154 commands)
Adds first formal test suite for Python fork — 42 tests covering memory_store,
profiles_store, scheduler_store, macros_store, llm_backend. All pass.

Tests (tests/, ~290 lines)
  conftest.py — `isolated_state` fixture: rewires _PATH/_PROFILES_DIR etc to
                a per-test tmp_path so concurrent runs don't touch real data.
  test_memory_store.py     — 9 tests: remember/recall/forget round-trip,
                              search by key/value, limit/empty query,
                              persistence across reload, build_llm_context
  test_profiles_store.py   — 7 tests: seeded defaults, set_active persistence,
                              allows_command logic (default/work/driving)
  test_scheduler_store.py  — 12 tests: parser (daily/at/every/in, ru units,
                              bad input), add/remove/clear/remove_by_text,
                              _next_fire for each schedule kind
  test_macros_store.py     — 8 tests: is_macro_control filter, start/save
                              round-trip, control-phrase filtering, list_names
                              sorted, replay unknown raises
  test_llm_backend.py      — 6 tests: parse_backend aliases (ru + en),
                              persist round-trip, auto-detect logic

Run: cd /c/Jarvis/python && python -m pytest tests/

Three new fun packs (commands.yaml: 151 → 154)

now_playing — Windows Media Session API via PowerShell
              "что играет" / "что за песня" / "какой трек"
              Works with Spotify, YouTube, Foobar, Yandex Music, anything
              that exposes SMTC (Win10 1803+).

world_clock — worldtimeapi.org (free, no key)
              "сколько времени в Токио" / "время в Лондоне"
              21 Russian + world cities pre-mapped to IANA timezones.

daily_quote — zenquotes.io (free, no key) + LLM translation
              "цитата дня" / "вдохнови меня"
              Fetches English quote, translates to Russian via active LLM
              (Groq or Ollama), speaks "text — author."

Pack count: 151 → 154. Tests: 42 pytest + ast.parse + yaml.safe_load.
2026-05-16 00:56:02 +03:00