[build-system] requires = ["hatchling"] build-backend = "hatchling.build" [project] name = "auralynq" version = "0.2.0" description = "Auralynq — Talk to Your Data: a local-first, agentic, voice-enabled RAG platform with PathRAG graph retrieval." readme = "README.md" requires-python = ">=3.11" license = { text = "Apache-2.0" } authors = [{ name = "Auralynq" }] keywords = ["rag", "pathrag", "voice", "agent", "langgraph", "qdrant", "retrieval"] classifiers = [ "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "License :: OSI Approved :: Apache Software License", "Operating System :: OS Independent", ] # Core dependencies are intentionally lightweight and pure-Python where possible # so the platform installs fast and the full test-suite runs offline at $0. # Heavy / GPU / paid integrations live in optional extras and are imported lazily. dependencies = [ "pydantic>=2.7,<3", "pydantic-settings>=2.3,<3", "typer>=0.12,<1", "rich>=13.7", "httpx>=0.27", "numpy>=1.26", "networkx>=3.2", "structlog>=24.1", "tenacity>=8.2", "orjson>=3.10", "pyyaml>=6.0", "fastapi>=0.111", "uvicorn[standard]>=0.30", "sse-starlette>=2.1", "python-multipart>=0.0.9", "websockets>=12.0", ] [project.optional-dependencies] embeddings = ["sentence-transformers>=3.0", "FlagEmbedding>=1.2", "torch>=2.2"] vector = ["qdrant-client>=1.9", "chromadb>=0.5"] ingest = ["pypdf>=4.2", "python-docx>=1.1", "beautifulsoup4>=4.12", "markdown-it-py>=3.0", "pdfplumber>=0.11", "pymupdf>=1.24", "pdf2image>=1.17", "lxml>=5.0", "trafilatura>=1.8"] # Cloud connectors. Notion + Slack use raw REST (httpx, already a core dep); # only Google Drive's service-account auth needs the google SDK. connectors = ["google-api-python-client>=2.0", "google-auth>=2.0"] voice = [ "faster-whisper>=1.0", "soundfile>=0.12", "librosa>=0.10", "silero-vad>=5.1", ] agent = ["langgraph>=0.2", "langchain-core>=0.2"] # Commercial LLM provider SDKs (optional; auto-detected, with offline fallback). llm = ["openai>=1.30", "anthropic>=0.30", "cohere>=5.5"] eval = ["ragas>=0.1.9", "jiwer>=3.0", "datasets>=2.19", "scikit-learn>=1.4"] telemetry = [ "opentelemetry-api>=1.25", "opentelemetry-sdk>=1.25", "opentelemetry-exporter-otlp>=1.25", "arize-phoenix>=4.0", "openinference-instrumentation>=0.1", "langfuse>=2.0", ] # CPU/GPU local GGUF inference — fallback when Ollama is not running. # Install the CUDA build for GPU: pip install llama-cpp-python --extra-index-url https://abetlen.github.io/llama-cpp-python/whl/cu121 slm = ["llama-cpp-python>=0.3", "huggingface_hub>=0.23"] mcp = ["mcp>=1.0"] # ColPali late-interaction visual retrieval (GPU-favored). torch comes from the # `embeddings` extra; a deterministic offline hash fallback runs without this. colpali = ["colpali-engine>=0.3", "pillow>=10.0"] dev = [ "ruff>=0.15.18,<0.16", "mypy>=1.10,<2.2", # stability cap; type-check targets py3.12 (see [tool.mypy]) "pytest>=8.2", "pytest-cov>=5.0", "pytest-asyncio>=0.23", "types-requests", "pre-commit>=3.7", ] all = [ "auralynq[embeddings,vector,ingest,voice,agent,llm,eval,telemetry,mcp]", ] [project.scripts] auralynq = "auralynq.cli:app" auralynq-mcp = "auralynq.mcp_server.server:main" auralynq-modelfit = "auralynq.modelfit.cli:main" [project.urls] Homepage = "https://github.com/MHHamdan/Auralynq" Documentation = "https://github.com/MHHamdan/Auralynq#readme" [tool.hatch.build.targets.wheel] packages = ["auralynq"] [tool.ruff] line-length = 100 target-version = "py311" src = ["auralynq", "tests", "scripts"] [tool.ruff.lint] select = ["E", "F", "I", "UP", "B", "C4", "SIM", "RUF", "TID"] # UP042: str+Enum is an intentional, widely-used pattern (pydantic-friendly). # RUF001: ambiguous unicode (curly quotes / en-dash) is intentional in entity # regexes and human-facing locators. ignore = ["B008", "C901", "RUF012", "UP042", "RUF001"] [tool.ruff.lint.per-file-ignores] "tests/*" = ["B011", "SIM117"] # planned.py embeds multi-line LLM prompt templates whose prose lines exceed # the 100-col limit; reflowing them would alter the prompt text, so E501 is # waived for this one file only. "auralynq/rag/strategies/planned.py" = ["E501"] [tool.mypy] # Target 3.12: numpy>=2.4 ships PEP 695 `type` statements in its stubs, which # mypy only accepts when both the target version and the interpreter running # mypy are 3.12+. CI runs the type-check step on the 3.12 matrix job only. python_version = "3.12" warn_unused_ignores = false warn_redundant_casts = true disallow_untyped_defs = false ignore_missing_imports = true no_implicit_optional = true check_untyped_defs = true plugins = ["pydantic.mypy"] exclude = ["web/", "build/", "tests/"] [tool.pytest.ini_options] asyncio_mode = "auto" testpaths = ["tests"] addopts = "-q --strict-markers" markers = [ "integration: requires optional heavy dependencies or network", "slow: long-running tests", ] filterwarnings = ["ignore::DeprecationWarning"] [tool.coverage.run] source = ["auralynq"] # Omit integration-only paths that require a live server / network / optional # heavy dependency and therefore cannot run in the offline $0 unit suite. Their # logic is covered by integration tests behind the `integration` marker. omit = [ "*/mcp_server/*", "*/__main__.py", "*/vectorstore/qdrant_store.py", "*/vectorstore/chroma_store.py", "*/retrieval/visual/colpali_embedder.py", "*/llm/providers.py", "*/llm/slm.py", "*/serving/worker.py", "*/embeddings/bge.py", "*/embeddings/ollama_embed.py", "*/modelfit/catalog_fetcher.py", ] [tool.coverage.report] show_missing = true skip_covered = false