local lang = jarvis.context.language local phrase = (jarvis.context.phrase or ""):lower() local triggers = { "найди в википедии про", "википедия про", "расскажи про", "кто такая", "кто такой", "что такое", "tell me about", "wikipedia about", "who is", "what is", "розкажи про", "хто такий", "що таке", } local query = phrase for _, t in ipairs(triggers) do local s, e = string.find(query, t, 1, true) if s == 1 then query = query:sub(e + 1) break end end query = query:gsub("^%s+", ""):gsub("%s+$", "") if query == "" then jarvis.system.notify("Wiki", lang == "ru" and "О чём рассказать?" or "What to look up?") jarvis.audio.play_error() return { chain = false } end local function url_encode(s) return (s:gsub("([^%w%-_%.~])", function(c) return string.format("%%%02X", string.byte(c)) end)) end local host = lang == "en" and "en.wikipedia.org" or "ru.wikipedia.org" local search_url = string.format( "https://%s/w/api.php?action=opensearch&search=%s&limit=1&format=json", host, url_encode(query) ) local search = jarvis.http.get(search_url) if not search.ok then jarvis.system.notify("Wiki", "Поиск не удался") jarvis.audio.play_error() return { chain = false } end local title = search.body:match('%["[^"]+",%s*%["([^"]+)"') if not title or title == "" then jarvis.system.notify("Wiki", (lang == "ru" and "Не нашёл: " or "Not found: ") .. query) jarvis.audio.play_not_found() return { chain = false } end local summary_url = string.format( "https://%s/api/rest_v1/page/summary/%s", host, url_encode(title) ) local summary = jarvis.http.json(summary_url) if not summary or type(summary) ~= "table" or not summary.extract then jarvis.system.notify("Wiki", "Не получил конспект") jarvis.audio.play_error() return { chain = false } end local extract = summary.extract local article_title = summary.title or title local token = jarvis.system.env("GROQ_TOKEN") local say_text = extract:sub(1, 400) if token and token ~= "" and #extract > 350 then local base = jarvis.system.env("GROQ_BASE_URL"); if not base or base == "" then base = "https://api.groq.com/openai/v1" end local model = jarvis.system.env("GROQ_MODEL"); if not model or model == "" then model = "llama-3.3-70b-versatile" end local sys = lang == "ru" and "Тебе дана статья из Википедии. Перескажи суть простым разговорным языком в 2-3 предложения. Без 'википедия гласит' и подобных вступлений." or "Summarise this Wikipedia text in 2-3 plain-language sentences. No 'wikipedia says' preambles." local payload = { model = model, messages = { { role = "system", content = sys }, { role = "user", content = extract:sub(1, 2500) }, }, max_tokens = 220, temperature = 0.3, } local lr = jarvis.http.post_json(base .. "/chat/completions", payload, { Authorization = "Bearer " .. token }) if lr.ok then local c = (lr.body or ""):match('"content"%s*:%s*"(.-[^\\])"') if c then c = c:gsub('\\n', ' '):gsub('\\"', '"'):gsub('\\\\', '\\'):gsub("%s+", " ") say_text = c:gsub("^%s+", ""):gsub("%s+$", "") end end end jarvis.system.clipboard.set(article_title .. "\n\n" .. extract) jarvis.system.notify(article_title, say_text:sub(1, 240)) local sapi = say_text:gsub("'", "''"):gsub("\r?\n", " ") local ps = string.format( [[Add-Type -AssemblyName System.Speech; $s = New-Object System.Speech.Synthesis.SpeechSynthesizer; foreach ($v in $s.GetInstalledVoices()) { if ($v.VoiceInfo.Culture.TwoLetterISOLanguageName -eq 'ru') { try { $s.SelectVoice($v.VoiceInfo.Name); break } catch {} } } $s.Speak('%s')]], sapi ) jarvis.system.exec(string.format('powershell -NoProfile -Command "%s"', ps:gsub('"', '\\"'))) jarvis.audio.play_ok() return { chain = false }