[build-system] requires = ["setuptools>=68"] build-backend = "setuptools.build_meta" [project] name = "arborist" version = "0.0.1" description = "An arborist for trees and forests of cross-linked information" readme = "README.md" license = { text = "AGPL-3.0-only" } requires-python = ">=3.10" authors = [ { name = "Russell Ballestrini", email = "russell@unturf.com" }, { name = "foxhop" }, { name = "TimeHexOn" }, ] dependencies = [ "httpx>=0.27", "zstandard>=0.22", "cryptography>=42", ] [project.optional-dependencies] html = [ "selectolax>=0.3", ] wikitext = [ "mwparserfromhell>=0.6", ] mesh = [ # httpx is already in core deps; mesh wire only depends on stdlib + # cryptography (also core). This extras block exists as the documented # opt-in surface even though no extra packages are required today. ] math = [ # Symbolic algebra/calculus π* substrate (ticket #000030). SymPy is # ~30 MB installed; pulling it into core deps would inflate every # fresh checkout. Tests skip via pytest.importorskip when absent. "sympy>=1.13", ] hessian = [ # Phi_alignment_probe (ticket #000034 Phase 1a). Lanczos top-k + # bottom-k eigendecomposition for measuring whether v7's frozen # linear projection W aligns with the loss Hessian's low-eigenvalue # subspace. Numpy + scipy together ~80 MB; gated separately from # core to keep the default install lightweight. Tests skip via # pytest.importorskip when absent. Install with: # pip install 'arborist[hessian]' "numpy>=1.26", "scipy>=1.11", ] crawler = [ # Verbatim lift from agents.ai.unturf.com/core. Off by default — the # default test suite never imports the crawler. Install with: # pip install 'arborist[crawler]' # then run `make test-crawler`. "aiohttp>=3.8", "beautifulsoup4>=4.11", "lxml>=4.9", "html5lib>=1.1", "html2text>=2024.2.26", "miniuri>=1.1", "feedparser>=6.0", "Pillow>=10.0", "cairosvg>=2.7", "pypdf>=4.0", ] vec = [ # Optional sqlite-vec semantic retrieval backend (ticket #000039). # sqlite-vec ships only the loadable SQLite extension (~1 MB); # fastembed pulls onnxruntime + tokenizers + huggingface-hub # (~150 MB) and downloads the bge-small-en-v1.5 ONNX model # (~130 MB) on first use. Gated separately so a fresh checkout # stays python3.12 + venv + sqlite3. CLI surfaces `arborist embed` # / `--backend vec` only when `sqlite_vec` imports. Install with: # pip install 'arborist[vec]' # (sentence-transformers is the heavier "official" embedder path # the ticket §5 names; fastembed is the lightweight ONNX one.) "sqlite-vec>=0.1.9", "fastembed>=0.4", ] nli = [ # Sentence-pair NLI for the #000049 Phase-2 *shadow* path # (arborist/qa/nli/) — measures whether a clause-level contradiction # veto would demote a weakly-grounded answer; never touches # audit_mode. transformers + a CPU torch is ~600 MB installed, so it # is gated hard out of core / dev — a fresh checkout stays # python3.12 + venv + sqlite3, and the default test suite skips the # NLI tests via pytest.importorskip when this extra is absent. # Install with: # pip install 'arborist[nli]' # `optimum[onnxruntime]` gives the ONNX-export + int8-quantize path # (`bench/scripts/export_nli_onnx.py`, `make export-nli-onnx`): # `onnxruntime` on a quantized cross-encoder is ~2-4x faster on CPU # than the torch forward path; `ShadowNLI._ensure_loaded` auto-prefers # an export if it finds one. torch is still here because `optimum`'s # exporter uses it, and it's the fallback when no export exists; a # Phase-3 runtime could ship an `[nli-onnx]`-only extra (onnxruntime, # no torch) once the export is committed/distributed (cf. [vec]). "transformers>=4.40", "torch>=2.2", "sentencepiece>=0.2", "protobuf>=4.0", "optimum[onnxruntime]>=1.20", ] bucket = [ # SPV-style bucket-direct queries (arborist/wallet/bucket.py): open a # shard `.db` file in place on a bucket via SQLite HTTP-range VFS, no # intermediate server, no local DB. Uses apsw because Python's stdlib # sqlite3 doesn't expose the VFS API; apsw is a thin C wrapper that # does. Gated separately so a fresh checkout stays python3.12 + venv # + sqlite3; tests skip via pytest.importorskip when absent. Install # with: # pip install 'arborist[bucket]' "apsw>=3.45", ] object-store = [ # Cold-object eviction tier (ticket #000061). Pushes chunk bodies to an # S3-compatible bucket keyed by leaf_hash so the corpus can grow past # one machine while the Merkle tree stays intact. One backend covers # AWS S3, DigitalOcean Spaces, Cloudflare R2, Backblaze B2, GCS # (S3 interop), and MinIO — boto3 with a per-provider endpoint_url. # Gated separately so a fresh checkout stays python3.12 + venv + # sqlite3; tests skip via pytest.importorskip when absent. Install with: # pip install 'arborist[object-store]' # Credentials use boto3's standard discovery (env vars, # ~/.aws/credentials, IAM role); never read into arborist code. The # wire-level test gated additionally on `moto`. "boto3>=1.34", ] mt = [ # Local machine-translation engine for the #000056 "Operation # Sandwich" cross-language grounding edges (arborist/qa/mt/): # translate the query es->en (retrieval-side) and render the # *verified English* answer en->es for display only. Helsinki-NLP # opus-mt (MarianMT) is Apache-2.0, hash-pinnable by HF revision # (reproducible — provenance-critical for a Merkle-replay system), # and es<->en is its best-resourced pair. Hard out of core/dev like # [nli]: a fresh checkout stays python3.12 + venv + sqlite3, and the # default suite drives the sandwich via a deterministic # StubTranslator so it never needs these weights. Install with: # pip install 'arborist[mt]' # Weights are NOT in the repo; they cache under # ~/.arborist/models/mt/. Never Hermes-3-8B (8B unfit for # human-language translation); never an external API (zero egress / # Operation Voyeur; opaque API "versions" are provenance-hostile). "transformers>=4.40", "torch>=2.2", "sentencepiece>=0.2", "protobuf>=4.0", "sacremoses>=0.1", ] dev = [ "pytest>=8", "pytest-asyncio>=0.23", "pytest-xdist>=3.5", "arborist[html]", "arborist[wikitext]", "arborist[mesh]", "arborist[crawler]", "arborist[math]", "arborist[hessian]", "arborist[vec]", "arborist[object-store]", "arborist[bucket]", # moto is the wire-level boto3 test stub; only needed to run # tests/test_cold_object_boto3.py (the default suite uses MemoryBackend). "moto>=5.0", ] [project.scripts] arborist = "arborist.cli:main" [tool.setuptools.packages.find] where = ["."] include = ["arborist*"]