diff --git a/.gitignore b/.gitignore
index 525719c..6570c24 100644
--- a/.gitignore
+++ b/.gitignore
@@ -185,4 +185,9 @@ fabric.properties
.idea/caches/build_file_checksums.ser
# idea folder, uncomment if you don't need it
-# .idea
\ No newline at end of file
+# .idea
+# Local secrets (real keys go here, not in dev.env.example)
+dev.env
+
+# Misc artifacts
+.git-filter-redactions.txt
diff --git a/README.md b/README.md
index b655b5b..56be979 100644
--- a/README.md
+++ b/README.md
@@ -1,30 +1,57 @@
-# Kesha v3.0 very early (aka Jarvis update)
-Simple Voice Assistant made as an experiment using [Silero](https://github.com/snakers4/silero-models) & [Vosk](https://pypi.org/project/vosk/).
-
Later on [Picovoice Porcupine Wake Word Detection](https://picovoice.ai/platform/porcupine/) & [ChatGPT](https://chat.openai.com/) was added.
+# J.A.R.V.I.S (Python) — Bossiara13's fork
-
+Голосовой ассистент для Windows с wake-word **«jarvis»**. Распознаёт речь локально через Vosk (русская модель), отвечает голосом через Silero TTS, а свободные вопросы (фразы, начинающиеся со слова «скажи …») отправляет в LLM на Groq и зачитывает ответ.
-`The code has NOT been polished and is provided "as is". There are a lot of code that are redundant and there are tons of improvements that can be made.`
+## Это форк
-# Installation
-First, install the requirements, the `requirements.txt` file is just an output of `pip freeze` from my test venv 'k.
-Second, check `config.py` and set required values (api key, device index).
-Next, run the `main.py` script and Voilà, as simple as that.
+Форк репозитория [Priler/jarvis](https://github.com/Priler/jarvis) (автор оригинала — Abraham Tugalov, 2022). Лицензия наследуется: **CC BY-NC-SA 4.0** (см. [LICENSE.txt](LICENSE.txt)).
-And don't forget to put models of Vosk to main folder.
-You can get the latest from the [official website.](https://alphacephei.com/vosk/models)
-
The one I was using is `small`.
-
p.s. If you don't understand how to install or where to put the Vosk model, I've made a [screenshot](https://i.imgur.com/N3bu2lC.png) for you.
+## Что отличается от оригинала
-# Python version
-I was using Python `3.8.3`, but it should work on any newer version.
+- Из истории удалены случайно закоммиченные секреты.
+- Бэкенд LLM переключён с OpenAI на Groq (бесплатный тариф) через openai-совместимый API.
+- Код обновлён под новую версию SDK `openai` (>=1.0); старый pre-1.0 интерфейс был сломан.
+- Обновлена ветка/тэги (`dev`, `v0.0.1-import`), причёсан README и `requirements.txt`.
-# ToDo
-- Адекватная архитектура кода, собрать всё и переписать from the ground up.
-- Задержка воспроизведения звука на основе реальной длительности .wav файла (прогружать при запуске?)
-- Speech to intent?
-- Отключать self listening protection во время воспроизведения с наушников.
-- Указание из списка или по имени будет реализовано позже.
+## Установка
-# Author
-(2022) Abraham Tugalov
\ No newline at end of file
+Требуется **Python 3.11** (на 3.13 ряд зависимостей пока ставится с бубном).
+
+```bash
+git clone https://github.com/DmitryBykov-ISPO/J.A.R.V.I.S-py.git
+cd J.A.R.V.I.S-py
+py -3.11 -m venv .venv
+.venv\Scripts\activate
+pip install --upgrade pip
+pip install -r requirements.txt
+```
+
+Скопируйте `dev.env` и заполните ключи:
+
+- `PICOVOICE_TOKEN` — бесплатно на [console.picovoice.ai](https://console.picovoice.ai/).
+- `GROQ_TOKEN` — бесплатно на [console.groq.com](https://console.groq.com/).
+
+Vosk-модель для русского языка лежит в `model_small/` (уже в репозитории). Запуск:
+
+```bash
+python main.py
+```
+
+## Конфигурация
+
+- `config.py`:
+ - `MICROPHONE_INDEX = -1` — индекс микрофона (`-1` означает устройство по умолчанию). Если микрофонов несколько и берётся не тот, поменяйте число.
+ - `GROQ_MODEL` — имя модели Groq (по умолчанию `llama-3.3-70b-versatile`).
+- `commands.yaml` — набор голосовых команд и их вариантов для fuzzy-матчинга.
+- `custom-commands/` — скомпилированные AHK-скрипты под конкретный сетап автора оригинала (переключение мониторов, управление Яндекс.Музыкой и т.п.). На вашей машине большая часть из них работать не будет, но ассистент запустится в любом случае.
+
+## Использование
+
+1. Скажите **«Джарвис»** (или **«jarvis»**) — ассистент даст звуковой сигнал готовности.
+2. В течение 10 секунд произнесите команду:
+ - либо одну из фраз из `commands.yaml` (открыть браузер, выключить звук и т.д.);
+ - либо начните со слова **«скажи …»** — остаток фразы уйдёт в Groq, ответ будет зачитан вслух.
+
+## Лицензия
+
+CC BY-NC-SA 4.0 — см. [LICENSE.txt](LICENSE.txt). Авторство оригинала — Abraham Tugalov / Priler. Изменения в этом форке — Bossiara13 (Dmitry Bykov), 2026.
diff --git a/config.py b/config.py
index cac005f..28a9710 100644
--- a/config.py
+++ b/config.py
@@ -6,7 +6,7 @@ load_dotenv("dev.env")
# Конфигурация
VA_NAME = 'Jarvis'
-VA_VER = "3.0"
+VA_VER = "0.1.0"
VA_ALIAS = ('джарвис',)
VA_TBR = ('скажи', 'покажи', 'ответь', 'произнеси', 'расскажи', 'сколько', 'слушай')
@@ -20,5 +20,7 @@ CHROME_PATH = 'C:/Program Files (x86)/Google/Chrome/Application/chrome.exe %s'
# Токен Picovoice
PICOVOICE_TOKEN = os.getenv('PICOVOICE_TOKEN')
-# Токен OpenAI
-OPENAI_TOKEN = os.getenv('OPENAI_TOKEN')
+# Токен Groq
+GROQ_TOKEN = os.getenv('GROQ_TOKEN')
+GROQ_BASE_URL = "https://api.groq.com/openai/v1"
+GROQ_MODEL = "llama-3.3-70b-versatile"
diff --git a/dev.env b/dev.env.example
similarity index 54%
rename from dev.env
rename to dev.env.example
index 4f357f2..36d9b7b 100644
--- a/dev.env
+++ b/dev.env.example
@@ -1,2 +1,2 @@
PICOVOICE_TOKEN=<тут ключ-picovoice>
-OPENAI_TOKEN=<тут ключ-openai>
\ No newline at end of file
+GROQ_TOKEN=<тут ключ-groq>
diff --git a/main.py b/main.py
index 7204464..dc7208c 100644
--- a/main.py
+++ b/main.py
@@ -10,7 +10,7 @@ import time
from ctypes import POINTER, cast
import openai
-from openai import error
+from openai import OpenAI
import pvporcupine
import simpleaudio as sa
import vosk
@@ -37,8 +37,7 @@ VA_CMD_LIST = yaml.safe_load(
system_message = {"role": "system", "content": "Ты голосовой ассистент из железного человека."}
message_log = [system_message]
-# init openai
-openai.api_key = config.OPENAI_TOKEN
+client = OpenAI(api_key=config.GROQ_TOKEN, base_url=config.GROQ_BASE_URL)
# PORCUPINE
porcupine = pvporcupine.create(
@@ -59,33 +58,29 @@ q = queue.Queue()
def gpt_answer():
global message_log
- model_engine = "gpt-3.5-turbo"
- max_tokens = 256 # default 1024
try:
- response = openai.ChatCompletion.create(
- model=model_engine,
+ response = client.chat.completions.create(
+ model=config.GROQ_MODEL,
messages=message_log,
- max_tokens=max_tokens,
+ max_tokens=256,
temperature=0.7,
top_p=1,
- stop=None
+ stop=None,
)
- except (error.TryAgain, error.ServiceUnavailableError):
- return "ChatGPT перегружен!"
- except openai.OpenAIError as ex:
- # если ошибка - это макс длина контекста, то возвращаем ответ с очищенным контекстом
- if ex.code == "context_length_exceeded":
+ except openai.BadRequestError as ex:
+ code = getattr(ex, "code", None) or ""
+ message = str(ex)
+ if code == "context_length_exceeded" or "context_length_exceeded" in message:
message_log = [system_message, message_log[-1]]
return gpt_answer()
- else:
- return "OpenAI токен не рабочий."
+ return "Запрос отклонён моделью."
+ except openai.RateLimitError:
+ return "Лимит запросов исчерпан."
+ except openai.APIConnectionError:
+ return "Не могу связаться с сервером."
+ except openai.APIError:
+ return "Groq токен не рабочий."
- # Find the first response from the chatbot that has text in it (some responses may not have text)
- for choice in response.choices:
- if "text" in choice:
- return choice.text
-
- # If no response with text is found, return the first response's content (which may be empty)
return response.choices[0].message.content
@@ -283,7 +278,7 @@ recorder = PvRecorder(device_index=config.MICROPHONE_INDEX, frame_length=porcupi
recorder.start()
print('Using device: %s' % recorder.selected_device)
-print(f"Jarvis (v3.0) начал свою работу ...")
+print(f"Jarvis (v0.1.0) начал свою работу ...")
play("run")
time.sleep(0.5)
diff --git a/requirements.txt b/requirements.txt
index 348ea58..f98b726 100644
Binary files a/requirements.txt and b/requirements.txt differ