Ctrl K
ComunidadGuías…

pyproject.toml

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
[project]
name = "niles-core"
version = "0.2.16"
description = "Local AI Butler"
license = "AGPL-3.0-only"
requires-python = ">=3.14"

dependencies = [
    # Web Framework
    "fastapi>=0.129.0",
    "uvicorn[standard]>=0.41.0",

    # Async HTTP Client + Retry
    "httpx>=0.28.1",
    "tenacity>=9.0.0",

    # Database
    "asyncpg>=0.31.0",

    # Database migrations (Alembic runs sync via psycopg2)
    "alembic>=1.13.0",
    "sqlalchemy>=2.0.0",
    "psycopg2-binary>=2.9.0",

    # LLM Client (OpenAI-kompatibel für LM Studio)
    "openai>=2.21.0",
    "tiktoken>=0.8.0",  # approximate token counting for the context budget

    # MCP SDK
    "mcp>=2.3.0,<3",

    # Config
    "pydantic-settings>=2.13.0",
    "pyyaml>=6.0.3",

    # Scheduling
    "apscheduler>=3.11.2",

    # Web UI (templates + static files)
    "jinja2>=3.1.0",
    "aiofiles>=24.0.0",

    # Signed session cookies (Google OAuth)
    "itsdangerous>=2.0",

    # Password hashing (Argon2id)
    "argon2-cffi>=25.1.0",

    # RRULE expansion for recurring calendar events
    "python-dateutil>=2.8.0",

    # Structured JSON logging (12-factor XI)
    "structlog>=24.1.0",

    # Prometheus metrics
    "prometheus-client>=0.21.0",

    # WebSocket client (Signal integration)
    "websockets>=14.0",

    # MCP Web Search is built-in (src/niles/mcp/search)

    # HTML text extraction for web fetch MCP server
    "trafilatura>=2.0.0",
    # Pin transitive lxml[html-clean] to patched release (GHSA-4jhm-jv67-739f)
    "lxml-html-clean>=0.4.5",

    # Robust JSON repair for malformed LLM tool-call output
    "json-repair>=0.58.0",

    # Notion workspace integration (RAG pipeline)
    "notion-client>=2.0.0",

    # Column-level credential encryption (Fernet AES-128-CBC + HMAC)
    "cryptography>=44.0",

    # Error tracking (opt-in via SENTRY_DSN)
    "sentry-sdk[fastapi]>=2.0.0",

    # Safe XML parsing (XXE protection for CalDAV responses)
    "defusedxml>=0.7.0",
]

[project.optional-dependencies]
tracing = [
    "langfuse>=5.0.4,<6",
]
dev = [
    "pytest>=9.0.0",
    "pytest-asyncio>=1.3.0",
    "pytest-cov>=6.0.0",
    "pytest-json-report>=1.5.0",  # machine-readable eval pass counts for the LLM-eval gate
    "httpx>=0.28.1",  # For TestClient
    "mypy>=1.14.0",
    "pip-audit>=2.7.0",
    "ruff>=0.9.0",
    "anthropic>=0.40",  # Claude-as-Judge E2E tests
    "types-python-dateutil>=2.9.0.20260518",
    "types-pyyaml>=6.0.12.20260518",
]

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.hatch.build.targets.wheel]
packages = ["src/niles"]

[tool.pytest.ini_options]
testpaths = ["tests"]
asyncio_mode = "auto"
markers = [
    "integration: requires Docker Compose infrastructure (deselect with -m 'not integration')",
    "e2e: end-to-end agent pipeline tests (deselect with -m 'not e2e')",
    "llm_judge: requires Ollama + Claude API key, slow (deselect with -m 'not llm_judge')",
    "llm_eval: behavioral quality evals against live Ollama (deselect with -m 'not llm_eval')",
]

[tool.ruff]
target-version = "py314"
line-length = 120

[tool.ruff.lint]
select = ["E", "F", "W", "S"]
ignore = ["E501"]  # Line length handled by ruff format

[tool.ruff.lint.per-file-ignores]
# Tests legitimately use assert, hardcoded credentials, verify=False, and try-except-pass
"tests/**/*.py" = ["S101", "S105", "S106", "S110", "S501"]
# Web route handlers use assert for type narrowing after auth checks
"src/niles/sources/web/_admin.py" = ["S101"]
"src/niles/sources/web/_chat.py" = ["S101"]
"src/niles/sources/web/_contacts.py" = ["S101"]
"src/niles/sources/web/_core.py" = ["S101"]
"src/niles/sources/web/_settings.py" = ["S101"]
"src/niles/sources/web/_vikunja.py" = ["S101"]
"src/niles/sources/web/_whatsapp.py" = ["S101"]
# CalDAV: uses defusedxml (S314 no longer needed)
# Dynamic SQL uses parameterized queries (where_clause built from internal logic, not user input)
"src/niles/contact_store.py" = ["S608"]

[tool.mypy]
python_version = "3.14"
warn_return_any = false
warn_unused_configs = true
ignore_missing_imports = true
check_untyped_defs = true
disallow_untyped_defs = true
disallow_incomplete_defs = true

# All per-module error-code suppressions removed in W18 — fixed at the source.
# Type stubs (types-python-dateutil, types-pyyaml) resolve the import-untyped cases.

[tool.coverage.run]
source = ["src/niles"]
omit = ["tests/*", "alembic/*"]
branch = true

[tool.coverage.report]
show_missing = true
fail_under = 77  # branch-inclusive; raised from 70 after the route/agent-loop test additions (W16/W17)
exclude_lines = [
    "pragma: no cover",
    "if __name__",
    "if TYPE_CHECKING",
]