J.A.R.V.I.S-rust/resources/commands/llm_switch/command.toml
Bossiara13 5c7245012e feat: hot-swap LLM backend + media keys + codebase Q&A + scheduler cancel-by-text + TTS pre-warm
Single biggest user-facing change: you can now switch local↔cloud LLM by voice
without restarting. Plus four new packs and a perf nudge.

Shared LLM global (crates/jarvis-core/src/llm/mod.rs)
  - GLOBAL: Lazy<RwLock<Option<Arc<LlmClient>>>>. Single source of truth.
  - init_global() / current() / swap_to(LlmBackend) / current_backend_name() / parse_backend(str).
  - llm_fallback + llm_router migrated: they no longer own a separate LlmClient,
    they read from the global on each request. Hot-swap is now LIVE — change
    backend, next chat call uses the new one.
  - parse_backend accepts both english and russian aliases:
      "groq"/"cloud"/"облако"/"клауд"        → Groq
      "ollama"/"local"/"локал"/"локальный"  → Ollama

Voice + Lua LLM switcher (resources/commands/llm_switch/, 3 commands)
  - "переключись на локальный" / "перейди на оллама"  → swap to Ollama
  - "переключись на облако" / "используй грок"        → swap to Groq
  - "какой у тебя мозг" / "облако или локально"       → status query

  Underlying Lua API (registered globally):
    jarvis.llm({messages}, opts)   -- as before, now uses global client
    jarvis.llm_status()            -> "groq" | "ollama" | "none"
    jarvis.llm_switch(name)        -> name on success, nil on failure

Media keys pack (resources/commands/media_keys/, 4 commands)
  - "пауза" / "плей"           → VK_MEDIA_PLAY_PAUSE
  - "следующий трек"           → VK_MEDIA_NEXT_TRACK
  - "предыдущий трек"          → VK_MEDIA_PREV_TRACK
  - "стоп музыка"              → VK_MEDIA_STOP
  - Helper _media.ps1 uses user32.keybd_event (P/Invoke through Add-Type).
  - Works with anything that listens to global media keys: Spotify, Yandex Music,
    YouTube (focused tab), Foobar2000, Winamp, etc. No OAuth, no API keys.

Codebase Q&A pack (resources/commands/codebase_qa/, 3 commands)
  - "укажи проект <path>"             → stores path in jarvis.memory under codebase.root
  - "какой проект сейчас"             → speaks current path
  - "что делает функция X" / "найди в коде Y" / "объясни код"
    → walks the folder (depth 3, 30 files cap, 4KB per file, 50KB total),
      filters by source extensions (rs/py/ts/lua/go/...), feeds digest to LLM
      with a "senior reviewer" system prompt, speaks 3-5 sentence answer.

Scheduler cancel-by-text (crates/jarvis-core/src/scheduler.rs)
  - new pub fn find_by_text(query, limit) -> Vec<ScheduledTask>
  - new pub fn remove_by_text(query) -> usize (count removed)
  - new pure helper find_by_text_in(tasks, query, limit) for tests
  - Lua: jarvis.scheduler.{find_by_text, remove_by_text}
  - Voice: "отмени напоминание про воду" / "удали задачу про разминку"
  - 3 new unit tests (52 total in jarvis-core).

TTS pre-warm (crates/jarvis-app/src/main.rs)
  - Call jarvis_core::tts::backend() once on startup so the first speak()
    doesn't pay Piper binary discovery + voice loading cost. Cuts first-speak
    latency by ~150-300ms depending on backend.

Build: cargo build --release -p jarvis-app -p jarvis-gui both green.
Tests: 52/52 jarvis-core unit tests pass.
2026-05-15 16:15:59 +03:00

62 lines
1.7 KiB
TOML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Switch between local (Ollama) and cloud (Groq) LLM at runtime.
[[commands]]
id = "llm.switch.local"
type = "lua"
script = "switch.lua"
sandbox = "standard"
timeout = 3000
[commands.phrases]
ru = [
"переключись на локальный",
"переключись на локальный мозг",
"включи локальный режим",
"перейди на локальный",
"используй локальный",
"перейди на оллама",
"используй оллама",
]
en = ["switch to local", "use local llm", "use ollama"]
ua = ["перейди на локальний", "використовуй локальний"]
[[commands]]
id = "llm.switch.cloud"
type = "lua"
script = "switch.lua"
sandbox = "standard"
timeout = 3000
[commands.phrases]
ru = [
"переключись на облако",
"переключись на облачный",
"переключись на грок",
"переключись на гроку",
"используй облако",
"используй грок",
"перейди на облако",
]
en = ["switch to cloud", "use cloud llm", "use groq"]
ua = ["перейди на хмару", "використовуй хмару"]
[[commands]]
id = "llm.status"
type = "lua"
script = "status.lua"
sandbox = "minimal"
timeout = 2000
[commands.phrases]
ru = [
"какой у тебя мозг",
"какой ллм",
"какой у тебя llm",
"облако или локально",
"ты сейчас где работаешь",
"что за модель",
]
en = ["which llm", "are you local or cloud", "what model"]
ua = ["який ллм", "хмара чи локально"]