local lang = jarvis.context.language local feed = lang == "en" and "https://feeds.bbci.co.uk/news/rss.xml" or "https://lenta.ru/rss/news" local res = jarvis.http.get(feed) if not res.ok then jarvis.system.notify("News", "Не получил RSS: " .. tostring(res.status)) jarvis.audio.play_error() return { chain = false } end local titles = {} for title in res.body:gmatch("%s*<!%[CDATA%[(.-)%]%]>%s*") do if title ~= "" and title:lower():find("rss") == nil and title:lower():find("новости") ~= 1 then table.insert(titles, title) end if #titles >= 7 then break end end if #titles == 0 then for title in res.body:gmatch("%s*(.-)%s*") do if title ~= "" then table.insert(titles, title) end if #titles >= 7 then break end end end if #titles <= 1 then jarvis.system.notify("News", lang == "ru" and "Не получилось распарсить" or "Could not parse feed") jarvis.audio.play_error() return { chain = false } end local top = {} for i = 2, math.min(6, #titles) do table.insert(top, titles[i]) end local joined = table.concat(top, " | ") jarvis.system.clipboard.set(joined) jarvis.system.notify(lang == "ru" and "Новости" or "News", joined:sub(1, 280)) local token = jarvis.system.env("GROQ_TOKEN") local say_text if token and token ~= "" 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 "Ты диктор. Дам список заголовков новостей. Сжато перескажи 3 главные темы простым языком, 2-3 предложения суммарно. Не упоминай номера и не повторяй заголовки дословно." or "You are a news anchor. Summarise the top 3 headlines in 2-3 sentences. No numbering, no verbatim repeats." local payload = { model = model, messages = { { role = "system", content = sys }, { role = "user", content = joined }, }, max_tokens = 220, temperature = 0.4, } 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('\\\\', '\\') say_text = c end end end if not say_text then say_text = (lang == "ru" and "Главные новости: " or "Top news: ") .. (top[1] or "") .. ". " .. (top[2] or "") .. ". " .. (top[3] or "") end 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 }