[build-system] requires = ["hatchling"] build-backend = "hatchling.build" [project] name = "inferrail" version = "0.4.3" description = "Self-hosted, OpenAI- and Anthropic-compatible LLM gateway that turns every request into a payload-free, attributable cost receipt -- know what your AI work costs, without keeping what it said." readme = "README.md" requires-python = ">=3.11" license = { text = "Apache-2.0" } authors = [{ name = "Inferrail contributors" }] keywords = [ "llm", "openai", "llm-gateway", "openai-compatible", "inference-gateway", "cost-attribution", "cost-tracking", "llm-observability", "self-hosted", "developer-tools", "mcp", "accounts-payable", "invoice-processing", "exception-handling", "ap-automation", ] classifiers = [ "Development Status :: 3 - Alpha", "License :: OSI Approved :: Apache Software License", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", ] dependencies = [ "fastapi>=0.110", "uvicorn>=0.27", "httpx>=0.27", "pydantic>=2.5", "pyyaml>=6.0", "python-dotenv>=1.0", ] [project.urls] Repository = "https://github.com/domondi1/inferrail" Issues = "https://github.com/domondi1/inferrail/issues" [project.optional-dependencies] dev = [ "pytest>=8.0", "pytest-asyncio>=0.23", "ruff>=0.4", "mypy>=1.9", "types-PyYAML", # Only needed to unit-test hatch_build.py's own logic (mocked-npm # skip paths) -- already an implicit build-time dependency via # [build-system].requires, just not otherwise importable in a normal # dev/test environment (pip's PEP 517 build isolation keeps it out). "hatchling>=1.18", ] mcp = [ "mcp>=1.0", ] # Only needed for inferrail.ap.adapters.OpenAIRetryAdapter -- the AP # decision engine, SDK, and CLI have no dependency on this by default # (see src/inferrail/ap/adapters.py's module docstring). ap = [ "openai>=1.0", ] # Only needed to run/test hosted/work_economics/ and # hosted/a2a_economic_authority/ locally -- not part of the `inferrail` # package's own dependencies (see docs/adr/0010). Pinned to match # hosted/work_economics/requirements.txt and # hosted/a2a_economic_authority/requirements.txt exactly. hosted = [ "cdp-sdk==1.48.1", "x402[evm,fastapi,httpx,extensions]==2.22.0", "a2a-sdk[fastapi]==1.1.2", ] [project.scripts] inferrail = "inferrail.cli.main:main" inferrail-mcp = "inferrail_mcp.server:main" [tool.hatch.build.targets.wheel] packages = ["src/inferrail", "inferrail-mcp/src/inferrail_mcp"] [tool.hatch.build.targets.sdist] # Pre-existing gap, found and fixed alongside this same wheel-packaging # work: hatchling's default sdist does not respect app/.gitignore, so a # plain `python -m build` was including app/node_modules (real, sizable # dependency bloat) and any locally-built app/dist in the source # tarball. Both are excluded explicitly rather than relying on # gitignore-based inference. exclude = ["app/node_modules", "app/dist"] [tool.hatch.build.hooks.custom] # Bundles the dashboard into the wheel when Node is available; a no-op, # never-fatal skip otherwise -- see hatch_build.py and # docs/adr/0017-dashboard-in-app-directory.md. path = "hatch_build.py" [tool.pytest.ini_options] testpaths = ["tests"] asyncio_mode = "auto" markers = [ "integration: requires real, explicitly-provided provider credentials", "real_env_gate: exercises the real usage_ping environment-disable gate, unpatched", ] [tool.ruff] line-length = 100 target-version = "py311" [tool.ruff.lint] select = ["E", "F", "I", "UP", "B"] [tool.mypy] python_version = "3.11" packages = ["inferrail", "inferrail_mcp"] mypy_path = "src:inferrail-mcp/src" strict = true disallow_untyped_defs = true warn_unused_ignores = true # `openai` is an optional dependency (the `ap` extra, for # inferrail.ap.adapters.OpenAIRetryAdapter only) -- this override lets # mypy pass whether or not it happens to be installed, without an inline # ignore comment that would be "unused" in one of the two states. [[tool.mypy.overrides]] module = "openai.*" ignore_missing_imports = true