Files
OpenJarvis/pyproject.toml
T
Elliot SluskyandGitHub 9b7b3681f6 ci: parallelize the test suite and cut install/coverage overhead (#580)
Run pytest with -n auto (pytest-xdist) and COVERAGE_CORE=sysmon, enable the uv cache, and switch test output to -q. Cuts the test job from ~40min to ~4min without changing what's tested or the 60% coverage gate.
2026-06-22 13:58:46 -07:00

238 lines
8.0 KiB
TOML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
[build-system]
requires = ["hatchling", "hatch-vcs"]
build-backend = "hatchling.build"
[project]
name = "OpenJarvis"
dynamic = ["version"]
description = "OpenJarvis — modular AI assistant backend with composable intelligence primitives"
readme = "README.md"
# Upper bound: numpy 2.2.x (pinned transitively via datasets/pandas) ships no
# cp314 Windows wheel, so under Python 3.14 uv would compile numpy from source
# (Meson) and fail on Windows boxes without a C toolchain (#350). Cap to the
# range that has prebuilt wheels; matches the classifiers (3.103.13).
requires-python = ">=3.10,<3.14"
license = {text = "Apache-2.0"}
authors = [
{name = "Open Jarvis Contributors"},
]
classifiers = [
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
"License :: OSI Approved :: Apache Software License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Topic :: Scientific/Engineering :: Artificial Intelligence",
]
dependencies = [
"click>=8",
"datasets>=4.5.0",
"ddgs>=9.11.4",
"httpx>=0.27",
"openai>=1.30",
"nvidia-ml-py>=12.560.30",
"posthog>=3.0",
"python-telegram-bot>=22.6",
"rich>=13",
"tomli>=2.0; python_version < '3.11'",
"tomlkit>=0.12",
"websockets>=15.0.1",
]
[project.optional-dependencies]
dev = [
"maturin>=1.12.6",
"pytest>=8",
"pytest-asyncio>=0.24",
"pytest-cov>=5",
"pytest-xdist>=3",
"respx>=0.22",
"ruff>=0.4",
"pre-commit>=3.0",
]
inference-mlx = ["mlx-lm>=0.31.1; sys_platform == 'darwin'"]
inference-vllm = ["vllm>=0.16.0"]
inference-cloud = [
"openai>=1.30",
"anthropic>=0.30",
]
inference-google = [
"google-genai>=1.0",
]
inference-litellm = ["litellm>=1.40"]
inference-gemma = ["pygemma>=0.1.3"]
tools-search = [
"tavily-python>=0.3",
"ddgs>=9.11.4",
]
memory-faiss = [
"faiss-cpu>=1.7",
"sentence-transformers>=2.2",
"numpy>=1.24",
]
memory-colbert = [
"colbert-ai>=0.2",
"torch>=2.0",
]
memory-pdf = ["pdfplumber>=0.10"]
memory-bm25 = ["rank-bm25>=0.2.2"]
server = [
"fastapi>=0.110",
"uvicorn>=0.30",
"pydantic>=2.0",
"python-multipart>=0.0.9",
]
desktop = [
"fastapi>=0.110",
"uvicorn>=0.30",
"pydantic>=2.0",
"python-multipart>=0.0.9",
"faster-whisper>=1.0",
]
openhands = ["openhands-sdk>=1.0; python_version >= '3.12'"]
gpu-metrics = ["pynvml>=12.0"]
energy-amd = ["amdsmi>=6.1"]
energy-apple = ["zeus-ml[apple]"]
energy-all = ["pynvml>=12.0", "amdsmi>=6.1", "zeus-ml[apple]"]
orchestrator-training = ["torch>=2.0", "transformers>=4.40"]
learning-dspy = ["dspy>=2.6"]
learning-gepa = ["gepa>=0.1"]
channel-telegram = ["python-telegram-bot>=21.0"]
channel-discord = ["discord.py>=2.3"]
channel-slack = ["slack-sdk>=3.27"]
channel-line = ["line-bot-sdk>=3.0"]
channel-viber = ["viberbot>=1.0"]
channel-messenger = ["pymessenger>=0.0.7"]
channel-reddit = ["praw>=7.0"]
channel-mastodon = ["Mastodon.py>=1.8"]
channel-xmpp = ["slixmpp>=1.8"]
channel-rocketchat = ["rocketchat-API>=1.30"]
channel-zulip = ["zulip>=0.9"]
channel-twitter = ["httpx>=0.27"]
channel-twitch = ["twitchio>=2.6"]
channel-nostr = ["pynostr>=0.6"]
channel-twilio = ["twilio>=9.0"]
channel-gmail = [
"google-api-python-client>=2.0",
"google-auth-oauthlib>=1.0",
"google-auth-httplib2>=0.2",
]
browser = ["playwright>=1.40"]
media = ["openai>=1.30"]
mining-pearl-vllm = ["docker>=7.0", "httpx>=0.27"]
pdf = ["pdfplumber>=0.10"]
scheduler = ["croniter>=2.0"]
security-signing = ["cryptography>=43"]
sandbox-wasm = ["wasmtime>=25"]
sandbox-docker = ["docker>=7.0"]
dashboard = ["textual>=0.80"]
speech = ["faster-whisper>=1.0"]
speech-deepgram = ["deepgram-sdk>=3.0"]
eval-wandb = ["wandb>=0.17"]
eval-sheets = ["gspread>=6.0", "google-auth>=2.0"]
mining-pearl-cpu = [
# Pearl Python packages (py-pearl-mining, miner-base, pearl-gateway) are
# not on PyPI yet. They are installed at first `mine init` via the
# build-from-pin path in src/openjarvis/mining/_install.py:build_from_pin().
# When Pearl publishes wheels, replace the line below with version pins.
#
# The extra remains as a feature-flag namespace so users can run
# `uv sync --extra mining-pearl-cpu` to opt-in (it succeeds with no
# additional resolution today; the actual install happens on demand).
]
framework-comparison = ["polars>=1.0"]
docs = [
"mkdocs>=1.6",
"mkdocs-material>=9.5",
"mkdocstrings[python]>=0.25",
"mkdocs-gen-files>=0.5",
"mkdocs-literate-nav>=0.6",
]
[project.urls]
Homepage = "https://github.com/open-jarvis/OpenJarvis"
Documentation = "https://open-jarvis.github.io/OpenJarvis/"
Repository = "https://github.com/open-jarvis/OpenJarvis"
Issues = "https://github.com/open-jarvis/OpenJarvis/issues"
[project.scripts]
jarvis = "openjarvis.cli:main"
openjarvis-eval = "openjarvis.evals.cli:main"
# Version is derived from git tags by hatch-vcs (see #526). For source/editable
# checkouts this yields the true `git describe` version (e.g. 1.0.3.dev109+g<sha>)
# rather than a stale static string. CI release builds override this with
# SETUPTOOLS_SCM_PRETEND_VERSION so the published version equals the pushed tag.
#
# setuptools_scm cannot bump custom `.devN` tags (only `.dev0`), so the autotag
# `vX.Y.Z.devN` tags are deliberately EXCLUDED from version derivation here; the
# base is taken from the latest plain release tag (vX.Y.Z) and the dev distance
# is computed from commit count since that release.
[tool.hatch.version]
source = "vcs"
[tool.hatch.version.raw-options]
tag_regex = '^v(?P<version>[0-9]+\.[0-9]+\.[0-9]+)$'
git_describe_command = [
"git", "describe", "--dirty", "--tags", "--long",
"--match", "v[0-9]*", "--exclude", "*dev*", "--exclude", "*rc*", "--exclude", "desktop-*",
]
# Builds without a git checkout (e.g. the `COPY src/ src/` Docker stages, which
# never include .git) can't run `git describe`. Without a fallback that would
# hard-fail the build. Mirror the runtime sentinel in src/openjarvis/__init__.py.
# Such builds can inject the real version via SETUPTOOLS_SCM_PRETEND_VERSION.
fallback_version = "0.0.0+unknown"
[tool.hatch.build.targets.wheel]
packages = ["src/openjarvis"]
[tool.hatch.build.targets.wheel.force-include]
"src/openjarvis/agents/claude_code_runner" = "_node_modules/claude_code_runner"
"src/openjarvis/channels/whatsapp_baileys_bridge" = "_node_modules/whatsapp_baileys_bridge"
"scripts/install" = "_install_scripts"
"deploy/windows" = "_deploy/windows"
[tool.pytest.ini_options]
testpaths = ["tests"]
markers = [
"amd: requires AMD GPU",
"apple: requires Apple Silicon",
"cloud: requires cloud API keys",
"docker: requires a working Docker daemon (no GPU required)",
"live: requires running inference engine",
"macos15: requires macOS 15+ (Sequoia) for Apple FM",
"live_channel: requires real channel credentials (env vars)",
"nvidia: requires NVIDIA GPU",
"slow: long-running test",
"hub: downloads real datasets from the HuggingFace Hub at runtime; excluded from the default CI lane (run with -m hub)",
"live_external: requires HERMES_AGENT_PATH and OPENCLAW_PATH; spawns real foreign-framework subprocesses",
"modal: requires Modal token + network; runs real swebench harness on Modal",
]
[tool.ruff]
target-version = "py310"
src = ["src", "tests"]
[tool.ruff.lint]
select = ["E", "F", "I", "W"]
[tool.ruff.lint.per-file-ignores]
"src/openjarvis/evals/datasets/*.py" = ["E501"]
"src/openjarvis/evals/scorers/*.py" = ["E501"]
# hybrid/ is research code with long prompt strings and paradigm-specific
# config dicts — same relaxation as evals research code above. The ``**`` glob
# also covers subpackages (e.g. hybrid/skillorchestra/), which the prior
# ``hybrid/*.py`` glob missed.
"src/openjarvis/agents/hybrid/**/*.py" = ["E501"]
# research_loop.py carries long prompt strings too (documented in CLAUDE.md);
# the ignore was missing here.
"src/openjarvis/agents/research_loop.py" = ["E501"]
[dependency-groups]
dev = [
"maturin>=1.12.6",
]