J.A.R.V.I.S-rust/resources/commands/wikipedia/summary.lua
Bossiara13 b243e67870 feat: Tauri backend commands + wikipedia rewrite + github PR review pack
GUI integration
  - crates/jarvis-gui/src/tauri_commands/backends.rs — 5 new Tauri commands:
      get_active_backends()  -> {tts, llm, llm_model, profile}
      set_llm_backend(name)  -> swap LLM hot, persists to DB
      set_tts_backend(name)  -> persist choice (effective on jarvis-app restart)
      llm_reset_context()    -> clear conversation history
      llm_get_last_reply()   -> last assistant message or null
  - Registered in main.rs invoke_handler. Svelte side can now read active
    backend + swap from a settings page / footer without env-var gymnastics.

Wikipedia pack rewritten (resources/commands/wikipedia/)
  - Old `wiki/wiki.lua` (104 lines, hand-rolled Groq HTTP + inline SAPI PS) deleted.
  - Replacement `wikipedia/summary.lua` (87 lines):
    * REST summary endpoint (cleaner than opensearch+summary chain).
    * Russian first, English fallback with LLM translation.
    * Pure LLM fallback if Wikipedia has no article.
    * Uses jarvis.cmd.{ok,error,not_found} + jarvis.llm + jarvis.speak (no
      inline PowerShell SAPI). Phrases kept compatible with old pack.

GitHub PR voice review (resources/commands/github_pr/, 3 commands)
  - "текущий репо bossiara13/J.A.R.V.I.S-rust"  → github.set_repo
    Persists repo via jarvis.memory.
  - "какие пиары" / "открытые пиары"            → github.list_prs
    Calls `gh pr list --json number,title,author,createdAt --limit 10`.
    Parses count + first 3 titles by regex from JSON.
  - "разбери последний пиар" / "что в pr"       → github.summarize_pr
    `gh pr view N --json title,body,additions,deletions,changedFiles,author`,
    sends to LLM with "senior reviewer" system prompt, speaks 3-5 sentence
    review focusing on changes, risks, merge-readiness.
  - Requires gh CLI installed and `gh auth login` done.

Tests: 52/52 jarvis-core unit tests pass (Wikipedia pack TOML/script auto-checked).
Build: cargo build --release -p jarvis-app -p jarvis-gui green.
2026-05-15 16:31:54 +03:00

105 lines
3.6 KiB
Lua
Raw Permalink 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.

-- "Википедия Эйнштейн" → fetch ru.wikipedia.org/api/rest_v1/page/summary/<topic>
-- Falls back to LLM if Wikipedia doesn't have the article.
local phrase = (jarvis.context.phrase or "")
local query = jarvis.text.strip_trigger(phrase:lower(), {
"найди в википедии про",
"найди в википедии",
"что говорит википедия",
"поищи в википедии",
"статья из википедии",
"википедия про",
"википедия о",
"википедия",
"расскажи про",
"что такое",
"кто такая",
"кто такой",
"look up in wikipedia",
"wikipedia article on",
"wikipedia about",
"wikipedia",
"tell me about",
"what is",
"who is",
"знайди у вікіпедії",
"вікіпедія",
"що таке",
"хто такий",
"розкажи про",
})
query = query:gsub("^[%s,:%.]+", ""):gsub("%s+$", "")
if query == "" then
return jarvis.cmd.error("Какая статья?")
end
-- Wikipedia title needs underscores for spaces. Capitalize first letter of each word
-- to match canonical titles (good enough heuristic).
local title = query:gsub("(%S+)", function(w)
-- Capitalize first byte (works for ASCII; for cyrillic, leave alone).
local first = w:sub(1, 1)
if first:match("[%a]") then
return first:upper() .. w:sub(2)
end
return w
end):gsub(" ", "_")
local function urlencode(s)
return (s:gsub("[^A-Za-z0-9%-_%.~]", function(c)
return string.format("%%%02X", string.byte(c))
end))
end
-- Try Russian first, fall back to English.
local lang_chain = { "ru", "en" }
local data, source_lang
for _, lang in ipairs(lang_chain) do
local url = string.format("https://%s.wikipedia.org/api/rest_v1/page/summary/%s",
lang, urlencode(title))
local d = jarvis.http.json(url)
if d and d.extract and d.extract ~= "" then
data = d
source_lang = lang
break
end
end
if not data then
-- last resort: ask LLM directly
local llm_answer = jarvis.llm({
{ role = "system", content = "Кратко (2-3 предложения) на русском объясни тему. Если не знаешь — скажи." },
{ role = "user", content = "Расскажи про: " .. query }
}, { max_tokens = 200, temperature = 0.3 })
if llm_answer and llm_answer ~= "" then
return jarvis.cmd.ok(llm_answer)
end
return jarvis.cmd.not_found("В Википедии нет статьи про " .. query .. ".")
end
local extract = data.extract
local title_actual = data.title or query
-- Truncate extract to ~3 sentences for spoken output
local sentences = {}
for sentence in extract:gmatch("[^%.%!%?]+[%.%!%?]") do
table.insert(sentences, sentence)
if #sentences >= 3 then break end
end
local spoken = #sentences > 0 and table.concat(sentences) or extract:sub(1, 400)
if source_lang == "en" then
-- Translate English extract to Russian via LLM (no point in speaking English
-- through a Russian voice).
local translated = jarvis.llm({
{ role = "system", content = "Переведи английский текст на русский, без вводных и комментариев." },
{ role = "user", content = spoken }
}, { max_tokens = 300, temperature = 0.0 })
if translated and translated ~= "" then
spoken = translated
end
end
jarvis.system.notify("Wikipedia: " .. title_actual, spoken:sub(1, 200))
return jarvis.cmd.ok(spoken)