Compare commits
2 Commits
5901254405
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7021a12a36 | ||
|
|
d9fc7d4b61 |
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
__pycache__
|
||||||
|
build/
|
||||||
|
dist/
|
||||||
|
*.spec
|
||||||
|
bin/*.exe
|
||||||
|
.DS_Store
|
||||||
26
README.md
26
README.md
@@ -1,19 +1,21 @@
|
|||||||
**Background Vision Agent (Windows)**
|
**Background Vision Agent (Windows)**
|
||||||
|
|
||||||
|
PROOF OF CONCEPT.
|
||||||
|
|
||||||
- One-command setup/run: `powershell -ExecutionPolicy Bypass -File .\run.ps1`
|
- One-command setup/run: `powershell -ExecutionPolicy Bypass -File .\run.ps1`
|
||||||
- Requires Python 3.11+ for source-based run. Configure your API key in `bg_agent/config.py` or via the `OPENAI_API_KEY` env var.
|
- Requires Python 3.11+ for source-based run. Configure your API key in `bg_agent/config.py` or via the `OPENAI_API_KEY` env var.
|
||||||
- Runs hidden (uses `pythonw.exe`) and listens for global hotkeys.
|
- Runs hidden (uses `pythonw.exe`) and listens for global hotkeys.
|
||||||
|
|
||||||
**Hotkeys**
|
**Hotkeys**
|
||||||
|
|
||||||
- Alt+Shift+1 — Capture active window (added to input buffer)
|
- Ctrl+Shift+1 — Capture active window (added to input buffer)
|
||||||
- Alt+Shift+2 — Send payload (buffered images + prompt) to OpenAI; save response
|
- Ctrl+Shift+2 — Send payload (buffered images + prompt) to OpenAI; save response
|
||||||
- Alt+Shift+3 — Action 3 (depends on mode)
|
- Ctrl+Shift+3 — Action 3 (depends on mode)
|
||||||
- Mode 1: Type response char-by-char into current input field
|
- Mode 1: Type response char-by-char into current input field
|
||||||
- Mode 2: Clipboard mode: primes clipboard with first char; every Ctrl+V advances to next char
|
- Mode 2: Clipboard mode: primes clipboard with first char; every Ctrl+V advances to next char
|
||||||
- Alt+Shift+4 — Reset program state (clears buffers and captured files)
|
- Ctrl+Shift+4 — Reset program state (clears buffers and captured files)
|
||||||
- Alt+Shift+5 — Quit permanently (press 3x within 2 seconds); also deletes app data directory
|
- Ctrl+Shift+5 — Quit permanently (press 3x within 2 seconds); also deletes app data directory
|
||||||
- Alt+Shift+6 — Switch Action 3 mode (toggle between Mode 1 and Mode 2)
|
- Ctrl+Shift+6 — Switch Action 3 mode (toggle between Mode 1 and Mode 2)
|
||||||
|
|
||||||
**Customize**
|
**Customize**
|
||||||
|
|
||||||
@@ -22,6 +24,14 @@
|
|||||||
- `endpoint_base` (e.g., `https://api.openai.com/v1`)
|
- `endpoint_base` (e.g., `https://api.openai.com/v1`)
|
||||||
- `api_key` (set here if you don’t want to use env vars)
|
- `api_key` (set here if you don’t want to use env vars)
|
||||||
- Or set env vars instead: `OPENAI_API_KEY` and optionally `OPENAI_BASE_URL`.
|
- Or set env vars instead: `OPENAI_API_KEY` and optionally `OPENAI_BASE_URL`.
|
||||||
|
- Hotkeys are easily customizable via env vars (override at launch):
|
||||||
|
- `BG_AGENT_SHORTCUT_CAPTURE` (default `ctrl+shift+1`)
|
||||||
|
- `BG_AGENT_SHORTCUT_SEND` (default `ctrl+shift+2`)
|
||||||
|
- `BG_AGENT_SHORTCUT_ACTION3` (default `ctrl+shift+3`)
|
||||||
|
- `BG_AGENT_SHORTCUT_RESET` (default `ctrl+shift+4`)
|
||||||
|
- `BG_AGENT_SHORTCUT_QUIT` (default `ctrl+shift+5`)
|
||||||
|
- `BG_AGENT_SHORTCUT_TOGGLE_MODE` (default `ctrl+shift+6`)
|
||||||
|
- Example (PowerShell): `$env:BG_AGENT_SHORTCUT_SEND='ctrl+shift+enter'`
|
||||||
- App data directory (captures, response, logs): `%LOCALAPPDATA%\BgVisionAgent`.
|
- App data directory (captures, response, logs): `%LOCALAPPDATA%\BgVisionAgent`.
|
||||||
|
|
||||||
**Debug Logging**
|
**Debug Logging**
|
||||||
@@ -33,6 +43,10 @@
|
|||||||
- Additionally, the agent saves full OpenAI HTTP request/response JSON files (URL, headers, payload, status, headers, body) in `%LOCALAPPDATA%\BgVisionAgent\http`. Filenames include timestamps and attempt numbers. Secrets are redacted from headers.
|
- Additionally, the agent saves full OpenAI HTTP request/response JSON files (URL, headers, payload, status, headers, body) in `%LOCALAPPDATA%\BgVisionAgent\http`. Filenames include timestamps and attempt numbers. Secrets are redacted from headers.
|
||||||
- When not enabled, only warnings/errors go to stderr; no log file is written.
|
- When not enabled, only warnings/errors go to stderr; no log file is written.
|
||||||
|
|
||||||
|
Hotkey behavior
|
||||||
|
- Global hotkeys are registered with `suppress=True` by default to avoid OS/app conflicts and ensure chords are detected reliably.
|
||||||
|
- To disable suppression (let the key chord also pass through), set `BG_AGENT_SUPPRESS_HOTKEYS=0` before launch.
|
||||||
|
|
||||||
**Notes**
|
**Notes**
|
||||||
|
|
||||||
- Windows is supported now; code is structured to later add macOS/Linux window capture backends.
|
- Windows is supported now; code is structured to later add macOS/Linux window capture backends.
|
||||||
|
|||||||
@@ -346,20 +346,22 @@ def cleanup_and_exit(state: State):
|
|||||||
|
|
||||||
def _bind_hotkeys(state: State):
|
def _bind_hotkeys(state: State):
|
||||||
logging.debug(
|
logging.debug(
|
||||||
"Binding hotkeys: capture=%s send=%s action3=%s reset=%s quit=%s toggle_mode=%s",
|
"Binding hotkeys: capture=%s send=%s action3=%s reset=%s quit=%s toggle_mode=%s suppress=%s",
|
||||||
state.cfg.shortcut_capture,
|
state.cfg.shortcut_capture,
|
||||||
state.cfg.shortcut_send,
|
state.cfg.shortcut_send,
|
||||||
state.cfg.shortcut_action3,
|
state.cfg.shortcut_action3,
|
||||||
state.cfg.shortcut_reset,
|
state.cfg.shortcut_reset,
|
||||||
state.cfg.shortcut_quit,
|
state.cfg.shortcut_quit,
|
||||||
state.cfg.shortcut_toggle_mode,
|
state.cfg.shortcut_toggle_mode,
|
||||||
|
getattr(state.cfg, 'suppress_hotkeys', True),
|
||||||
)
|
)
|
||||||
keyboard.add_hotkey(state.cfg.shortcut_capture, lambda: capture_active_window(state))
|
suppress = getattr(state.cfg, 'suppress_hotkeys', True)
|
||||||
keyboard.add_hotkey(state.cfg.shortcut_send, lambda: threading.Thread(target=send_to_openai, args=(state,), daemon=True).start())
|
keyboard.add_hotkey(state.cfg.shortcut_capture, lambda: capture_active_window(state), suppress=suppress)
|
||||||
keyboard.add_hotkey(state.cfg.shortcut_action3, lambda: threading.Thread(target=handle_action3, args=(state,), daemon=True).start())
|
keyboard.add_hotkey(state.cfg.shortcut_send, lambda: threading.Thread(target=send_to_openai, args=(state,), daemon=True).start(), suppress=suppress)
|
||||||
keyboard.add_hotkey(state.cfg.shortcut_reset, lambda: reset_state(state))
|
keyboard.add_hotkey(state.cfg.shortcut_action3, lambda: threading.Thread(target=handle_action3, args=(state,), daemon=True).start(), suppress=suppress)
|
||||||
keyboard.add_hotkey(state.cfg.shortcut_quit, lambda: maybe_quit(state))
|
keyboard.add_hotkey(state.cfg.shortcut_reset, lambda: reset_state(state), suppress=suppress)
|
||||||
keyboard.add_hotkey(state.cfg.shortcut_toggle_mode, lambda: toggle_mode(state))
|
keyboard.add_hotkey(state.cfg.shortcut_quit, lambda: maybe_quit(state), suppress=suppress)
|
||||||
|
keyboard.add_hotkey(state.cfg.shortcut_toggle_mode, lambda: toggle_mode(state), suppress=suppress)
|
||||||
# Ctrl+V listener (do not suppress paste)
|
# Ctrl+V listener (do not suppress paste)
|
||||||
keyboard.add_hotkey("ctrl+v", lambda: on_paste_event(state), suppress=False)
|
keyboard.add_hotkey("ctrl+v", lambda: on_paste_event(state), suppress=False)
|
||||||
|
|
||||||
|
|||||||
@@ -5,12 +5,12 @@ from dataclasses import dataclass
|
|||||||
@dataclass
|
@dataclass
|
||||||
class Settings:
|
class Settings:
|
||||||
# Hotkeys (Windows format for `keyboard` lib)
|
# Hotkeys (Windows format for `keyboard` lib)
|
||||||
shortcut_capture: str = "alt+shift+1"
|
shortcut_capture: str = "ctrl+shift+1"
|
||||||
shortcut_send: str = "alt+shift+2"
|
shortcut_send: str = "ctrl+shift+2"
|
||||||
shortcut_action3: str = "alt+shift+3"
|
shortcut_action3: str = "ctrl+shift+3"
|
||||||
shortcut_reset: str = "alt+shift+4"
|
shortcut_reset: str = "ctrl+shift+4"
|
||||||
shortcut_quit: str = "alt+shift+5"
|
shortcut_quit: str = "ctrl+shift+5"
|
||||||
shortcut_toggle_mode: str = "alt+shift+6"
|
shortcut_toggle_mode: str = "ctrl+shift+6"
|
||||||
|
|
||||||
# OpenAI
|
# OpenAI
|
||||||
model: str = "Google Gemini_2.5"
|
model: str = "Google Gemini_2.5"
|
||||||
@@ -35,6 +35,29 @@ class Settings:
|
|||||||
captures_dir_name: str = "captures"
|
captures_dir_name: str = "captures"
|
||||||
response_file_name: str = "response.txt"
|
response_file_name: str = "response.txt"
|
||||||
log_file_name: str = "agent.log"
|
log_file_name: str = "agent.log"
|
||||||
|
suppress_hotkeys: bool = True
|
||||||
|
|
||||||
|
def __post_init__(self):
|
||||||
|
# Allow hotkey overrides via environment variables for easy customization
|
||||||
|
# Example: set BG_AGENT_SHORTCUT_SEND="ctrl+shift+enter"
|
||||||
|
env_map = {
|
||||||
|
"BG_AGENT_SHORTCUT_CAPTURE": "shortcut_capture",
|
||||||
|
"BG_AGENT_SHORTCUT_SEND": "shortcut_send",
|
||||||
|
"BG_AGENT_SHORTCUT_ACTION3": "shortcut_action3",
|
||||||
|
"BG_AGENT_SHORTCUT_RESET": "shortcut_reset",
|
||||||
|
"BG_AGENT_SHORTCUT_QUIT": "shortcut_quit",
|
||||||
|
"BG_AGENT_SHORTCUT_TOGGLE_MODE": "shortcut_toggle_mode",
|
||||||
|
}
|
||||||
|
for env, attr in env_map.items():
|
||||||
|
val = os.environ.get(env)
|
||||||
|
if val:
|
||||||
|
setattr(self, attr, val)
|
||||||
|
|
||||||
|
# Optional: allow disabling suppression via env
|
||||||
|
sup = os.environ.get("BG_AGENT_SUPPRESS_HOTKEYS")
|
||||||
|
if sup is not None:
|
||||||
|
v = str(sup).strip().lower()
|
||||||
|
self.suppress_hotkeys = v in {"1", "true", "yes", "on"}
|
||||||
|
|
||||||
|
|
||||||
def ensure_dirs(cfg: Settings) -> None:
|
def ensure_dirs(cfg: Settings) -> None:
|
||||||
|
|||||||
@@ -24,12 +24,12 @@ function Start-Binary {
|
|||||||
Write-Host "Launching BgVisionAgent.exe ..." -ForegroundColor Green
|
Write-Host "Launching BgVisionAgent.exe ..." -ForegroundColor Green
|
||||||
Start-Process -FilePath $exePath -WindowStyle Hidden
|
Start-Process -FilePath $exePath -WindowStyle Hidden
|
||||||
Write-Host "Agent started. Hotkeys:" -ForegroundColor Green
|
Write-Host "Agent started. Hotkeys:" -ForegroundColor Green
|
||||||
Write-Host " Alt+Shift+1 -> Capture active window"
|
Write-Host " Ctrl+Shift+1 -> Capture active window"
|
||||||
Write-Host " Alt+Shift+2 -> Send to OpenAI"
|
Write-Host " Ctrl+Shift+2 -> Send to OpenAI"
|
||||||
Write-Host " Alt+Shift+3 -> Action 3 (type or clipboard mode)"
|
Write-Host " Ctrl+Shift+3 -> Action 3 (type or clipboard mode)"
|
||||||
Write-Host " Alt+Shift+4 -> Reset state"
|
Write-Host " Ctrl+Shift+4 -> Reset state"
|
||||||
Write-Host " Alt+Shift+5 -> Quit (press 3 times quickly)"
|
Write-Host " Ctrl+Shift+5 -> Quit (press 3 times quickly)"
|
||||||
Write-Host " Alt+Shift+6 -> Switch modes for Action 3"
|
Write-Host " Ctrl+Shift+6 -> Switch modes for Action 3"
|
||||||
Write-Host "Configure API key in bg_agent/config.py (if using source) or set OPENAI_API_KEY env var." -ForegroundColor Yellow
|
Write-Host "Configure API key in bg_agent/config.py (if using source) or set OPENAI_API_KEY env var." -ForegroundColor Yellow
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
12
run.ps1
12
run.ps1
@@ -34,11 +34,11 @@ Write-Host "Starting agent in background (hidden)..." -ForegroundColor DarkCyan
|
|||||||
Start-Process -FilePath $pythonw -ArgumentList "-m","bg_agent" -WindowStyle Hidden
|
Start-Process -FilePath $pythonw -ArgumentList "-m","bg_agent" -WindowStyle Hidden
|
||||||
|
|
||||||
Write-Host "Agent started. Use the hotkeys below:" -ForegroundColor Green
|
Write-Host "Agent started. Use the hotkeys below:" -ForegroundColor Green
|
||||||
Write-Host " Alt+Shift+1 -> Capture active window"
|
Write-Host " Ctrl+Shift+1 -> Capture active window"
|
||||||
Write-Host " Alt+Shift+2 -> Send to OpenAI"
|
Write-Host " Ctrl+Shift+2 -> Send to OpenAI"
|
||||||
Write-Host " Alt+Shift+3 -> Action 3 (type or clipboard mode)"
|
Write-Host " Ctrl+Shift+3 -> Action 3 (type or clipboard mode)"
|
||||||
Write-Host " Alt+Shift+4 -> Reset state"
|
Write-Host " Ctrl+Shift+4 -> Reset state"
|
||||||
Write-Host " Alt+Shift+5 -> Quit (press 3 times quickly)"
|
Write-Host " Ctrl+Shift+5 -> Quit (press 3 times quickly)"
|
||||||
Write-Host " Alt+Shift+6 -> Switch modes for Action 3"
|
Write-Host " Ctrl+Shift+6 -> Switch modes for Action 3"
|
||||||
|
|
||||||
Write-Host "Configure API key in bg_agent/config.py or set OPENAI_API_KEY env var." -ForegroundColor Yellow
|
Write-Host "Configure API key in bg_agent/config.py or set OPENAI_API_KEY env var." -ForegroundColor Yellow
|
||||||
|
|||||||
Reference in New Issue
Block a user