[project]
name = "delia"
version = "1.0.0"
description = "Local LLM delegation via Model Context Protocol"
readme = "README.md"
requires-python = ">=3.11"
license = {file = "LICENSE"}
authors = [{name = "zbrdc"}]
keywords = ["mcp", "llm", "ollama", "local-ai", "delia", "delegation"]
classifiers = [
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
]
dependencies = [
"mcp>=1.23.0", # CVE-2025-66416 fix
"httpx>=0.28.1",
"pydantic>=2.12.5",
"fastmcp>=2.13.3",
"pygments>=2.18.0",
"tenacity>=9.0.0",
"tiktoken>=0.8.0",
"structlog>=24.4.0",
"aiofiles>=24.1.0",
"humanize>=4.10.0",
# Semantic routing & NLP
"numpy>=1.26.0",
"sentence-transformers>=3.0.0", # Semantic intent detection
"chromadb>=0.5.0", # Vector database for semantic search
# Authentication (FastAPI-Users)
"fastapi-users[oauth,sqlalchemy]>=15.0.2", # CVE-2025-68481 fix
"aiosqlite>=0.20.0",
"python-jose[cryptography]>=3.5.0", # Uses cryptography backend, not vulnerable ecdsa
"jinja2>=3.1.6",
"google-generativeai>=0.8.5",
# Rate limiting
"limits>=3.13.0",
# CLI
"typer>=0.15.0",
"duckduckgo-search>=8.1.1",
"prompt-toolkit>=3.0.43",
# Use wsproto instead of websockets legacy API (websockets 15+ deprecated legacy)
"wsproto>=1.2.0",
"zeroconf>=0.141.0",
"pygls>=1.3.1",
# Security patches
"filelock>=3.20.1", # CVE-2025-68146 fix
"datasets>=4.4.2",
"psutil>=7.1.3",
"pyright>=1.1.407",
]
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"
[tool.setuptools]
package-dir = {"" = "src"}
[tool.setuptools.packages.find]
where = ["src"]
exclude = ["dashboard*", "node_modules*", "tests*"]
[dependency-groups]
dev = [
"pytest>=9.0.2",
"pytest-asyncio>=1.3.0",
"pytest-cov>=4.1.0",
"hypothesis>=6.100.0",
"mypy>=1.14.0",
# Linting
"ruff>=0.8.0", # Fast linter (replaces flake8, isort, pyupgrade)
# Security
"bandit>=1.8.0", # Security vulnerability scanner
"pip-audit>=2.7.0", # Dependency vulnerability scanner
# Type stubs
"types-aiofiles>=24.1.0",
]
[project.urls]
Repository = "https://github.com/zbrdc/delia"
[project.scripts]
delia = "delia.cli:app"
delia-setup-auth = "delia.setup_auth:main"
[project.optional-dependencies]
rich = ["rich>=13.0.0"] # Pretty CLI output
sandbox = ["llm-sandbox[docker]>=0.1.0"] # Sandboxed code execution
faiss = ["faiss-cpu>=1.7.4"] # Fast vector search for semantic indexing
test = [
"pytest>=9.0.2",
"pytest-asyncio>=1.3.0",
"pytest-cov>=4.1.0",
"hypothesis>=6.100.0",
]
[tool.pytest.ini_options]
pythonpath = ["src"]
testpaths = ["tests"]
markers = [
"integration: marks tests as integration tests (deselect with '-m \"not integration\"')",
"fuzz: marks tests as fuzz tests using hypothesis",
]
[tool.mypy]
python_version = "3.11"
# Gradual strict mode - enable incrementally
warn_return_any = false # Too noisy for structlog
warn_unused_ignores = true
disallow_untyped_defs = false # Enable per-file as types are added
disallow_incomplete_defs = false
check_untyped_defs = true
no_implicit_optional = true
warn_redundant_casts = true
warn_unused_configs = true
plugins = ["pydantic.mypy"]
[[tool.mypy.overrides]]
module = [
"mcp.*",
"fastmcp.*",
"fastmcp.tools.*",
"tiktoken.*",
"structlog.*",
"tenacity.*",
"humanize.*",
"aiofiles.*",
"google.generativeai.*",
"google.ai.*",
"fastapi_users.*",
"limits.*",
"pygments.*",
"jose.*",
"httpx_oauth.*",
"sentence_transformers.*",
]
ignore_missing_imports = true
# ============================================================
# PYRIGHT - Static Type Checker
# ============================================================
[tool.pyright]
pythonVersion = "3.11"
pythonPlatform = "Linux"
venvPath = "."
venv = ".venv"
include = ["src", "tests"]
exclude = ["**/node_modules", "**/__pycache__", "**/.*", "build", "dist"]
typeCheckingMode = "basic"
# ============================================================
# RUFF - Fast Python Linter (replaces flake8, isort, pyupgrade)
# ============================================================
[tool.ruff]
target-version = "py311"
line-length = 120
src = ["src", "tests"]
[tool.ruff.lint]
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"F", # pyflakes
"I", # isort
"B", # flake8-bugbear
"C4", # flake8-comprehensions
"UP", # pyupgrade
"S", # flake8-bandit (security)
"T20", # flake8-print
"SIM", # flake8-simplify
"RUF", # ruff-specific rules
]
ignore = [
"E501", # line too long (handled by formatter)
"B008", # function call in default argument (common in FastAPI)
"S101", # assert usage (fine in tests)
"S104", # binding to 0.0.0.0 (intentional for server)
"S603", # subprocess without shell=True check (handled manually)
"S607", # partial executable path (handled manually)
]
[tool.ruff.lint.per-file-ignores]
"tests/*" = ["S101", "S106"] # Allow assert and hardcoded passwords in tests
"src/delia/setup_auth.py" = ["S311", "T201"] # Allow random and print for CLI tool
"src/delia/melon_messages.py" = ["S311"] # Allow random for fun messages
"src/delia/mcp_server.py" = ["E402"] # Allow late imports for conditional loading
"src/delia/auth.py" = ["E402"] # Allow late imports for conditional sections
"src/delia/config.py" = ["E402"] # Allow late imports for section organization
"src/delia/backend_manager.py" = ["E402"] # Allow late imports
[tool.ruff.lint.isort]
known-first-party = ["delia"]
# ============================================================
# BANDIT - Security Scanner
# ============================================================
[tool.bandit]
exclude_dirs = ["tests", "venv", ".venv"]
skips = [
"B101", # assert_used (fine for type checks)
"B104", # hardcoded_bind_all_interfaces (intentional for server)
"B110", # try_except_pass (intentional for fallback/transport detection)
"B311", # random (used only for non-security fun messages)
]
# ============================================================
# PIP-AUDIT - Dependency Vulnerability Scanner
# ============================================================
# Run with: uv run pip-audit