[build-system] requires = ["setuptools>=78.1.1", "wheel"] # setuptools>=78.1.1 fixes PYSEC-2025-49 build-backend = "setuptools.build_meta" [project] name = "askrex-assistant" version = "1.4.1" description = "AskRex Assistant Python package — library, console scripts, and Electron bridge scripts for developers/operators (end-user artifact: Electron desktop installer)" readme = "README.md" requires-python = ">=3.11,<3.12" license = {text = "MIT"} authors = [ {name = "AskRex Assistant Contributors"} ] keywords = ["ai", "assistant", "voice", "speech", "llm"] classifiers = [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.11", ] dependencies = [ # Core Web & API "flask>=3.1.3", # CVE-2026-27205 fixed in 3.1.3 "flask-cors>=6.0.0", # CVE-2024-6839, CVE-2024-6844, CVE-2024-6866 fixed in 6.0.0 "flask-limiter>=3.5.0", "flask-sock>=0.7.0", # mobile WebSocket chat (issue #323); pure-Python, validated on Windows/Py3.11 "requests>=2.32.0", # CVE-2024-35195 fixed in 2.32.0 "websocket-client>=1.9.0,<2", # OpenClaw read-only Gateway capability discovery # Configuration & Validation "pydantic>=2.0.0", # Upgraded to v2 for security and performance "python-dotenv>=1.0.1", "tzdata>=2024.1", # IANA timezone database for Windows (zoneinfo has no OS database there) # Web Scraping "beautifulsoup4>=4.12.0", # Security-Critical Dependencies (minimum versions with CVE fixes) "cryptography>=46.0.5", # CVE-2026-26007 fixed in 46.0.5 "setuptools>=78.1.1", # Fixes: PYSEC-2025-49 (path traversal) "werkzeug>=3.1.6", # CVE-2024-34069, CVE-2024-49766, CVE-2024-49767, CVE-2025-66221, CVE-2026-21860, CVE-2026-27199 fixed in 3.1.x "jinja2>=3.1.6", # CVE-2024-56201, CVE-2024-56326, CVE-2025-27516 fixed in 3.1.6 "pillow>=12.1.1", # CVE-2026-25990 fixed in 12.1.1 "idna>=3.15", # CVE-2026-45409 fixed in 3.15 "urllib3>=2.7.0", # CVE-2025-50181, CVE-2025-50182, CVE-2025-66418, CVE-2025-66471, CVE-2026-21441 fixed in 2.6.x; PYSEC-2026-141, PYSEC-2026-142 fixed in 2.7.0 "certifi>=2024.2.2", # Certificate validation fixes "aiosqlite>=0.20.0", # Auth "bcrypt>=4.0.0", "PyJWT>=2.8.0", # TTS backends (lightweight, cross-platform) "edge-tts>=6.1.9", "pyttsx3>=2.90", # Windows-only OS-backed credential vault (S4): DPAPI via pywin32. # No effect on macOS/Linux installs (see rex/credential_vault.py). "pywin32>=311; sys_platform == 'win32'", ] [project.optional-dependencies] audio = [ "numpy>=1.24.0,<2.0.0", "sounddevice>=0.4.6", "soundfile>=0.12.0", # simpleaudio has build issues on Windows - keep optional "simpleaudio>=1.0.4; platform_system!='Windows'", ] ml = [ # AI / ML Models - CPU-only by default (GPU versions via requirements-gpu*.txt) # Note: torch 2.6.0 has local DoS CVEs (GHSA-3749-ghw9-m3mg, GHSA-887c-mr87-cxwp), fixed in 2.8.0 "torch>=2.6.0,<2.13.0", "torchvision>=0.17.0,<0.28.0", "torchaudio>=2.6.0,<2.13.0", "transformers>=4.38.0", "TTS==0.22.0", "openai>=1.3.0", "ollama>=0.4.0", "openai-whisper>=20230124", "openwakeword>=0.6.0", ] dev = [ "pytest>=8.0.0", "pytest-cov>=4.1.0", "pytest-asyncio>=0.23.0", "responses>=0.25.0", "build>=1.0.0", "black>=26.3.1", "ruff>=0.1.0", "mypy>=1.8.0", "numpy>=1.24.0,<2.0.0", # US-046 controlled acoustic reliability test uses the real optional detector. "openwakeword==0.6.0", "pre-commit>=3.0.0", "detect-secrets>=1.5.0", "pip-audit>=2.10.0", "types-requests>=2.32.0.20250328", ] test = [ "pytest>=8.0.0", "pytest-cov>=4.1.0", "pytest-asyncio>=0.23.0", "detect-secrets>=1.5.0", "pip-audit>=2.10.0", ] sms = [ "twilio>=9.0.0", ] voice-id = [ # Heavy speaker recognition libraries -- optional only. # Do NOT add these to default dependencies or Pipfile. "speechbrain>=1.0.0", "resemblyzer>=0.1.3", ] devtools = [ "build>=1.0.0", "black>=26.3.1", "ruff>=0.1.0", "mypy>=1.8.0", ] full = [ # audio "numpy>=1.24.0,<2.0.0", "sounddevice>=0.4.6", "soundfile>=0.12.0", "simpleaudio>=1.0.4; platform_system!='Windows'", # ml / voice "torch>=2.6.0,<2.13.0", "torchvision>=0.17.0,<0.28.0", "torchaudio>=2.6.0,<2.13.0", "transformers>=4.38.0", "TTS==0.22.0", "openai>=1.3.0", "ollama>=0.4.0", "openai-whisper>=20230124", "openwakeword>=0.6.0", # integrations "twilio>=9.0.0", ] # GPU-accelerated PyTorch: use requirements-gpu-cu124.txt or requirements-gpu.txt # instead of extras, because CUDA wheels require --extra-index-url from PyTorch. [project.scripts] rex = "rex.cli:main" rex-config = "rex.config:cli" rex-speak-api = "rex_speak_api:main" rex-agent = "rex.computers.agent_server:main" rex-gui = "rex.gui_app:main" rex-tool-server = "rex.openclaw.tool_server:main" [project.urls] Homepage = "https://github.com/Blueibear/AskRex-Assistant" Repository = "https://github.com/Blueibear/AskRex-Assistant" Issues = "https://github.com/Blueibear/AskRex-Assistant/issues" [tool.setuptools] packages = {find = {include = ["rex*", "utils*"]}} # Top-level modules are specified in setup.py (pyproject.toml doesn't support py_modules) [tool.setuptools.package-data] rex = ["py.typed"] [tool.pytest.ini_options] minversion = "8.0" testpaths = ["tests"] pythonpath = [".", "bridge"] python_files = ["test_*.py"] python_classes = ["Test*"] python_functions = ["test_*"] addopts = [ "-v", "--strict-markers", "--tb=short", ] markers = [ "asyncio_mode_not_required: mark tests that must run without pytest-asyncio strict-mode requirements", "unit: Unit tests that don't require external dependencies", "integration: Integration tests that may require external services", "slow: Tests that take significant time to run", "audio: Tests requiring audio hardware or ASR/TTS models", "gpu: Tests that require GPU acceleration", "network: Tests that require network access", "asyncio: mark a test as using asyncio", "anyio: mark a test as using anyio", "smoke: Smoke tests that verify critical paths against a running local instance", ] [tool.coverage.run] source = ["rex"] omit = [ "*/tests/*", "*/test_*.py", "*/__pycache__/*", "rex/mqtt_audio_router.py", "rex/mqtt_client.py", "rex/voice_loop_optimized.py", ] [tool.coverage.report] fail_under = 75 exclude_lines = [ "pragma: no cover", "def __repr__", "raise AssertionError", "raise NotImplementedError", "if __name__ == .__main__.:", "if TYPE_CHECKING:", "@abstractmethod", ] [tool.black] line-length = 100 target-version = ["py311"] include = '\.pyi?$' exclude = ''' /( \.git | \.venv | build | dist | __pycache__ | archived )/ ''' [tool.ruff] line-length = 100 target-version = "py311" exclude = [ "archived", # retired files; not maintained ] [tool.ruff.lint] select = [ "E", # pycodestyle errors "W", # pycodestyle warnings "F", # pyflakes "I", # isort "B", # flake8-bugbear "C4", # flake8-comprehensions "UP", # pyupgrade ] ignore = [ "E501", # line too long (handled by black) "B008", # do not perform function calls in argument defaults "B904", # raise from within except (would require too many changes) ] [tool.ruff.lint.per-file-ignores] "__init__.py" = ["F401"] # Allow unused imports in __init__.py [tool.mypy] python_version = "3.11" exclude = '(^build[\\/]|^dist[\\/]|^\.venv[\\/])' warn_return_any = true warn_unused_configs = true disallow_untyped_defs = false disallow_incomplete_defs = false check_untyped_defs = true no_implicit_optional = true warn_redundant_casts = true warn_unused_ignores = true warn_no_return = true disable_error_code = ["import-untyped", "import-not-found"] # Optional dependencies without type stubs — suppress import errors [[tool.mypy.overrides]] module = "aiomqtt" ignore_missing_imports = true [[tool.mypy.overrides]] module = "edge_tts" ignore_missing_imports = true [[tool.mypy.overrides]] module = "pyttsx3" ignore_missing_imports = true [[tool.mypy.overrides]] module = "whisper" ignore_missing_imports = true [[tool.mypy.overrides]] module = "nltk" ignore_missing_imports = true [[tool.mypy.overrides]] module = "nltk.*" ignore_missing_imports = true [[tool.mypy.overrides]] module = "openwakeword.*" ignore_missing_imports = true [[tool.mypy.overrides]] module = "simpleaudio" ignore_missing_imports = true [[tool.mypy.overrides]] module = "sounddevice" ignore_missing_imports = true [[tool.mypy.overrides]] module = "speechbrain" ignore_missing_imports = true [[tool.mypy.overrides]] module = "speechbrain.*" ignore_missing_imports = true [[tool.mypy.overrides]] module = "resemblyzer" ignore_missing_imports = true [[tool.mypy.overrides]] module = "transformers" ignore_missing_imports = true [[tool.mypy.overrides]] module = "transformers.*" ignore_missing_imports = true [[tool.mypy.overrides]] module = "servicemanager" ignore_missing_imports = true [[tool.mypy.overrides]] module = "win32event" ignore_missing_imports = true [[tool.mypy.overrides]] module = "win32service" ignore_missing_imports = true [[tool.mypy.overrides]] module = "win32serviceutil" ignore_missing_imports = true [[tool.mypy.overrides]] module = "plyer" ignore_missing_imports = true [[tool.mypy.overrides]] module = "twilio.*" ignore_missing_imports = true [[tool.mypy.overrides]] module = "playwright.*" ignore_missing_imports = true [[tool.mypy.overrides]] module = "TTS.*" ignore_missing_imports = true [[tool.mypy.overrides]] module = "psutil" ignore_missing_imports = true [[tool.mypy.overrides]] module = "icalendar" ignore_missing_imports = true [[tool.mypy.overrides]] module = "bs4" ignore_missing_imports = true [[tool.mypy.overrides]] module = "bs4.*" ignore_missing_imports = true [[tool.mypy.overrides]] module = "torch" ignore_missing_imports = true [[tool.mypy.overrides]] module = "torch.*" ignore_missing_imports = true [[tool.mypy.overrides]] module = [ "_pytest", "_pytest.*", "flask_cors", "flask_limiter", "flask_limiter.*", "flask_sock", "playsound", "pytest", "setuptools", "soundfile", "tomli", ] ignore_missing_imports = true # US-REM-014: ignore_errors = true block removed. # All 12 previously-suppressed modules were verified to pass mypy with no errors. # rex.cli, rex.voice_loop, and rex.gui_app were never in this block and remain # included in full mypy checking. # Pre-existing mypy errors exist in: rex/assistant.py, rex/audio_config.py, # rex/compat/transformers_shims.py, rex/mqtt_client.py, rex/plugin_loader.py, # rex/response/builder.py, rex/voice_loop.py, rex/wakeword/listener.py. # These are tracked as technical debt; fixing them is out of scope for US-REM-014.