[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"]