distinct / pyproject.toml
User1342's picture
Measure GPU and CPU energy from hardware counters and sum them; drop the modelled fallback
26a7c18
Raw
History Blame
3.35 kB
[build-system]
requires = ["setuptools>=75", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "distinct-server"
version = "0.1.0"
description = "Session-only Gradio control plane for community-run open-weight LLM agents"
requires-python = ">=3.10"
# WHAT A PLAIN `pip install -e .` HAS TO GIVE YOU: A WORKING WORKER.
#
# These were all behind the `[agent]` extra, which meant `pip install -e .`
# produced a worker that paired, ran, and then died the first time somebody
# asked for its dashboard — an ImportError for a package the install had
# quietly decided was optional. Optional to whom? Everybody who installs this
# repository outside the Space is installing it to run a worker.
#
# Costing the server nothing is what makes this free: HuggingFace Spaces
# installs `requirements.txt` and the SDK version in README.md, and never
# runs `pip install .` at all, so nothing here reaches the deployment.
dependencies = [
"gradio[oauth]==6.24.0",
# Ed25519, for the detached snapshot signature. A direct requirement, not
# a transitive one: `distinct_protocol.handshake` imports it and refuses
# to fall back to HMAC, so an install that happens to miss it fails at the
# moment a worker pairs rather than at install time.
"cryptography>=42",
"gradio_client==2.6.0",
"pyRAPL==0.2.3.1; sys_platform == 'linux'",
# NVIDIA GPU energy. For inference on a graphics card this is nearly all of
# the energy a run costs, so it is a base dependency rather than an extra:
# a worker that silently measured only its CPU package would understate a
# GPU run by roughly an order of magnitude while still calling the figure
# measured. The library is a thin ctypes binding to the driver's own NVML
# and installs on machines with no NVIDIA hardware, where it simply reports
# that there is none.
"nvidia-ml-py>=12.535",
# The worker's own screen. Pinned rather than ranged because the frozen
# build has to be reproducible, and because a Textual minor release can
# change how a widget lays out, which is a visual regression no test in
# this repository would catch.
"textual==8.2.8",
]
[project.optional-dependencies]
# The DSPy RLM harness only. It is a large install and the worker degrades to
# the structured harness without it, saying so on start, so it is the one
# thing here that is genuinely optional.
agent = [
"dspy[deno]==3.3.0",
]
dev = [
"pytest==8.4.2",
"ruff==0.12.11",
]
[tool.setuptools.packages.find]
include = [
"distinct_agent*", "distinct_mcp*", "distinct_protocol*",
"distinct_server*", "distinct_skills*", "distinct_tools*",
]
# A skill in `distinct_skills` is a directory of text, not a module: SKILL.md,
# tool.json and the templates beside them. Without this they are left out of a
# wheel, the digest table finds nothing on disk, and the repository degrades to
# empty in exactly the build where nobody is watching a test run.
[tool.setuptools.package-data]
distinct_skills = ["NOTICE.md", "skills/**/*.md", "skills/**/*.json"]
distinct_agent = ["deno.lock"]
[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = "-q"
[tool.ruff]
target-version = "py310"
line-length = 110
exclude = [".venv", "Measure-PcPower.ps1", "measure_pc_energy.py"]
[tool.ruff.lint]
select = ["E4", "E7", "E9", "F", "I", "B"]