J.A.R.V.I.S-rust/resources/commands/mood_log/recap.lua

34 lines
1.3 KiB
Lua
Raw Permalink Normal View History

refactor: maintainability pass — dedup, central env config, cmd helpers, tests, ARCHITECTURE.md User asked the code stays easy to fix/extend as the feature surface grows. This commit refactors what was duplicated, centralises what was scattered, adds tests where there were none, and writes the architecture doc that contributors will need. Deduplication - tts::play_wav extracted to tts/mod.rs as pub(crate). Was identical in piper.rs and silero.rs (~25 lines × 2). Both backends now call super::play_wav. Centralised env config - new crates/jarvis-core/src/runtime_config.rs — single doc-file for every JARVIS_* / GROQ_* / OLLAMA_* env var. Includes: - ENV_* constants with doc comments - get(name) / get_bool(name, default) / get_parse(name, default) helpers - feature-flag wrappers: llm_tts_enabled(), llm_router_enabled(), llm_router_threshold() - log_effective_config() prints active values on startup - migrated llm_fallback (JARVIS_LLM_TTS), llm_router (JARVIS_LLM_ROUTER, JARVIS_LLM_ROUTER_THRESHOLD) to use the new helpers. Pattern set for future migrations. Lua boilerplate killer - new crates/jarvis-core/src/lua/api/cmd.rs exposing: jarvis.cmd.ok(msg?) — play_ok + speak + {chain=false} jarvis.cmd.chain_ok(msg?) — same but chain=true jarvis.cmd.error(msg?) — play_error + speak + {chain=false} jarvis.cmd.not_found(msg?) — play_not_found + speak + {chain=false} jarvis.cmd.silent_ok / silent_error - refactored 5 packs (daily_briefing/off, memory_pack/list, pomodoro/stop, habit_nudge/stop_all, scheduler/clear) — each lost 3-4 lines of repetitive play_*/speak/return boilerplate. Pattern for future packs documented in ARCHITECTURE.md. Tests (was 32, now 49) - long_term_memory: 8 new tests for normalize_key, search_in (rank, limit, empty), build_context_from (empty + populated), serde round-trips for MemoryRecord and Store. Extracted pure logic (search_in, build_context_from) into pub(crate) functions to enable testing without global state. - profiles: 6 new tests for Profile::allows_command (empty/whitelist/blacklist/ deny-wins-over-allow), serde round-trip with all fields + minimal-fields tolerance via #[serde(default)]. - runtime_config: 2 tests for get_bool / get_parse defaults. - All 49 tests pass. New mood/energy log pack - resources/commands/mood_log/ with 2 commands: mood.record "запиши настроение 7" / "сегодня мне грустно" → stores timestamped entry via jarvis.memory.remember mood.recap "как прошла неделя" → LLM summarises last 30 entries - Showcase: composes memory + llm + cmd helpers in <30 lines per script. ARCHITECTURE.md (new, 250 lines) - Crate layout, data flow diagram (mic→action 10 steps), per-module responsibility table, configuration layers, TTS pipeline diagram, Lua sandbox details with API quick-ref, background-services overview, "how to add a pack/feature/TTS backend" recipes, test coverage map, build instructions with MSVC env, git workflow with Forgejo NO_PROXY trick. - Aimed at someone who just cloned the repo and needs to fix a bug fast. Build: cargo build --release -p jarvis-app -p jarvis-gui both green. Tests: 49/49 jarvis-core unit tests pass.
2026-05-15 16:06:18 +03:00
-- Pull all mood_* entries, ask LLM to summarize trends.
local all = jarvis.memory.all()
local moods = {}
for _, rec in ipairs(all) do
if rec.key:sub(1, 5) == "mood_" then
table.insert(moods, rec.value)
end
end
if #moods == 0 then
return jarvis.cmd.not_found("Записей о настроении пока нет.")
end
-- Trim to most-recent-ish 30 entries (memory.all isn't ordered, but mood_<ts> keys sort)
table.sort(moods)
local recent = {}
local start = math.max(1, #moods - 30 + 1)
for i = start, #moods do
table.insert(recent, moods[i])
end
local joined = table.concat(recent, "\n")
local summary = jarvis.llm({
{ role = "system", content = "Ты — психотерапевт-помощник. На основе записей пользователя о настроении дай короткую сводку (3-5 предложений) на русском: общий тон, тренды, выдели хороший/плохой день. Без банальностей, без советов." },
{ role = "user", content = "Записи:\n" .. joined }
}, { max_tokens = 250, temperature = 0.5 })
if not summary or summary == "" then
return jarvis.cmd.error("Не получилось обобщить. Возможно, нет связи с LLM.")
end
return jarvis.cmd.ok(summary)