[build-system] requires = ["setuptools>=68"] build-backend = "setuptools.build_meta" [project] name = "agronaut" version = "1.4.0" description = "Cited aquatic design and experimental field irrigation tools with farm records and a conversational agent" readme = "README.md" requires-python = ">=3.11" license = "MIT" authors = [{ name = "Abdoul Rachid Ouédraogo", email = "abdoulrachid03@gmail.com" }] keywords = ["aquaponics", "hydroponics", "agriculture", "food security", "digital public good"] # The sidebar on a PyPI page is how someone decides whether to trust a package they have # never heard of: it is where they read the licence, the Python floor, and who it is for. # An empty one makes a real project look abandoned. No "License ::" classifier: PEP 639 # supersedes it with the SPDX `license` field above, and setuptools now errors on both. classifiers = [ "Development Status :: 4 - Beta", "Intended Audience :: Science/Research", "Intended Audience :: End Users/Desktop", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14", "Topic :: Scientific/Engineering", "Topic :: Scientific/Engineering :: Hydrology", "Topic :: Scientific/Engineering :: Bio-Informatics", "Environment :: Console", ] dynamic = ["dependencies"] [project.optional-dependencies] # Full-content tracing to a local Arize Phoenix (agronaut_agent/otel_phoenix.py). Client side # only: the Phoenix server is ~600 MB and is installed on its own (`uv tool install arize-phoenix`). phoenix = ["arize-phoenix-otel", "openinference-instrumentation-langchain"] [project.urls] Homepage = "https://github.com/Rekin226/Agronaut" Source = "https://github.com/Rekin226/Agronaut" Issues = "https://github.com/Rekin226/Agronaut/issues" Changelog = "https://github.com/Rekin226/Agronaut/releases" [project.scripts] agronaut = "agronaut_agent.cli:main" [tool.setuptools.dynamic] # requirement.txt stays the single source of truth — it is what the Dockerfile and CI install. dependencies = { file = ["requirement.txt"] } [tool.setuptools] # bot.py and app.py sit at the project root as scripts, not inside a package; `agronaut bot` # and `agronaut web` need them installed alongside the packages. py-modules = ["bot", "app", "whatsapp"] # Explicitly off. Left on, it combines with a stale agronaut.egg-info/SOURCES.txt in the # working tree to sweep everything under a package dir into the wheel — that is how 54 test # files ended up shipped to site-packages. include-package-data = false [tool.setuptools.packages.find] include = ["agronaut_agent*", "agent*", "aqua_model*", "agro_model*", "srcs*", "skills*", "scripts*"] # Tests are for the checkout, not for site-packages. exclude = ["*.tests", "*.tests.*"] # The cited knowledge base is not optional decoration — without it every answer comes back # KNOWLEDGE_UNAVAILABLE while the assistant still sounds confident. It lives at the repo # root rather than inside a package, so it ships as data files and agronaut_agent/paths.py # looks for it under sys.prefix when the source tree is not there. [tool.setuptools.data-files] "share/agronaut" = ["urls.txt"] "share/agronaut/knowledge" = ["knowledge/*.md"] # Directly selected draft translations; kept outside the English retrieval index. "share/agronaut/field_guides" = ["field_guides/fr.json", "field_guides/zh-Hant.json", "field_guides/planning_questions.json"] "share/agronaut/examples" = ["examples/*.json"] # The reference tables aqua_model and the price tools read at runtime. Listed one by one on # purpose: data/ in a checkout also holds the memory database, the analytics log and the # fetched-page cache, and a glob would ship a developer's own state to strangers. # The golden sets and published eval reports `agronaut eval` reads (paths.eval_root). Without # them a pip install can run none of its own quality checks. "share/agronaut/eval/retrieval_eval" = [ "docs/dpg/retrieval_eval/golden_set.json", "docs/dpg/retrieval_eval/golden_set_multilingual.json", "docs/dpg/retrieval_eval/baseline_tuned_2026_09.json", "docs/dpg/retrieval_eval/baseline_all_field_guides_2026_10.json", "docs/dpg/retrieval_eval/golden_set_field_guidance.json", ] "share/agronaut/eval/safety_eval" = [ "docs/dpg/safety_eval/golden_set.json", "docs/dpg/safety_eval/field_set.json", ] "share/agronaut/eval/faithfulness_eval" = [ "docs/dpg/faithfulness_eval/2026-09-30_baseline.json", "docs/dpg/faithfulness_eval/2026-10-06_run.json", "docs/dpg/faithfulness_eval/human_labels.json", ] "share/agronaut/data" = [ "data/coefficient_sources.json", "data/dataset_registry.json", "data/empirical_envelope.json", "data/price_book.json", "data/reference_systems.json", "data/tgc_calibration.json", "data/twin_validation.json", ] [tool.ruff] # Pinned here rather than passed on the CI command line, so a local `ruff check` # and the blocking CI job cannot disagree about what "clean" means. line-length = 95 [tool.ruff.lint] # The set the tree is actually kept green under (#76). Ruff's own defaults drift # between releases — 0.16 reports ~275 findings here under no explicit selection — # so the list is spelled out and widened deliberately, never by upgrading ruff. # E4/E7/E9 pycodestyle errors, F pyflakes, I import order select = ["E4", "E7", "E9", "F", "I"]