From a4171ec6b14ea4338e2333caa890435035a8bf35 Mon Sep 17 00:00:00 2001 From: Bossiara13 <236771060+DmitryBykov-ISPO@users.noreply.github.com> Date: Mon, 27 Apr 2026 20:06:26 +0300 Subject: [PATCH] feat(url): optional browser field (yandex/chrome/firefox/edge) Adds optional 'browser' field to url-action; runtime resolves it via config.BROWSER_PATHS (subprocess.Popen with the chosen exe). When omitted, falls back to webbrowser.open (system default). Constructor GUI gains a browser dropdown on URL action and on multi-step URL. Existing open_browser/youtube/google updated to use yandex by default since user prefers Yandex Browser. --- commands.yaml | 10 ++++---- config.py | 8 +++++-- main.py | 6 +++++ tools/command_builder/schema.py | 14 ++++++++++-- tools/command_builder/web/app.js | 39 +++++++++++++++++++++++++++++--- 5 files changed, 65 insertions(+), 12 deletions(-) diff --git a/commands.yaml b/commands.yaml index 554fea0..a80d0e3 100644 --- a/commands.yaml +++ b/commands.yaml @@ -2,23 +2,23 @@ open_browser: phrases: - открой браузер - запусти браузер - - открой гугл хром - - гугл хром - action: {type: exe, file: "Run browser.exe"} + - открой яндекс + - яндекс браузер + action: {type: url, href: "about:blank", browser: "yandex"} open_youtube: phrases: - открой ютуб - ютуб - запусти ютуб - action: {type: exe, file: "Run youtube.exe"} + action: {type: url, href: "https://www.youtube.com", browser: "yandex"} open_google: phrases: - открой гугл - гугл - запусти гугл - action: {type: exe, file: "Run google.exe"} + action: {type: url, href: "https://www.google.com", browser: "yandex"} music: phrases: diff --git a/config.py b/config.py index 6df76a6..c32cccf 100644 --- a/config.py +++ b/config.py @@ -19,8 +19,12 @@ WAKE_WORDS = ('jarvis', 'джарвис') # -1 это стандартное записывающее устройство MICROPHONE_INDEX = -1 -# Путь к браузеру Google Chrome -CHROME_PATH = 'C:/Program Files (x86)/Google/Chrome/Application/chrome.exe %s' +BROWSER_PATHS = { + 'yandex': 'C:/Program Files/Yandex/YandexBrowser/Application/browser.exe', + 'chrome': 'C:/Program Files/Google/Chrome/Application/chrome.exe', + 'firefox': 'C:/Program Files/Mozilla Firefox/firefox.exe', + 'edge': 'C:/Program Files (x86)/Microsoft/Edge/Application/msedge.exe', +} # Токен Groq GROQ_TOKEN = os.getenv('GROQ_TOKEN') diff --git a/main.py b/main.py index 56909f4..dbb75a7 100644 --- a/main.py +++ b/main.py @@ -252,6 +252,12 @@ def run_action(action): else: subprocess.Popen(action['cmd'], shell=True) elif t == 'url': + browser = action.get('browser') + if browser: + exe = config.BROWSER_PATHS.get(browser) + if exe and os.path.isfile(exe): + subprocess.Popen([exe, action['href']]) + return webbrowser.open(action['href']) elif t == 'keys': import pyautogui diff --git a/tools/command_builder/schema.py b/tools/command_builder/schema.py index 60c0e5f..99dfa2d 100644 --- a/tools/command_builder/schema.py +++ b/tools/command_builder/schema.py @@ -65,13 +65,20 @@ class ShellAction: return out +KNOWN_BROWSERS = ("yandex", "chrome", "firefox", "edge") + + @dataclass class UrlAction: href: str + browser: Optional[str] = None type: str = "url" def to_dict(self) -> dict: - return {"type": "url", "href": self.href} + out: dict = {"type": "url", "href": self.href} + if self.browser: + out["browser"] = self.browser + return out @dataclass @@ -157,7 +164,10 @@ def action_from_dict(data: Any) -> Action: href = data.get("href") if not href or not isinstance(href, str): raise SchemaError("url action requires non-empty 'href' string") - return UrlAction(href=href) + browser = data.get("browser") + if browser is not None and browser not in KNOWN_BROWSERS: + raise SchemaError(f"url.browser must be one of {KNOWN_BROWSERS} or omitted") + return UrlAction(href=href, browser=browser) if t == "keys": sequence = data.get("sequence") text = data.get("text") diff --git a/tools/command_builder/web/app.js b/tools/command_builder/web/app.js index ce35e8e..278a669 100644 --- a/tools/command_builder/web/app.js +++ b/tools/command_builder/web/app.js @@ -191,10 +191,25 @@ +