[project] name = "lightspeed-stack" dynamic = ["version"] description = "LLM tooling stack" authors = [] maintainers = [ {email = "tisnik@centrum.cz", name = "Pavel Tišnovský"}, ] classifiers = [ "Development Status :: 4 - Beta", "Topic :: Scientific/Engineering :: Artificial Intelligence", "Topic :: Software Development", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", "License :: OSI Approved :: Apache Software License", ] keywords = [ "LLM", "RAG" ] requires-python = ">=3.12,<3.15" readme = "README.md" license = {file = "LICENSE"} dependencies = [ # Used for HTTP service base "fastapi>=0.115.12", "uvicorn>=0.34.3", # Used by authentication/k8s integration "kubernetes>=30.1.0,<37.0.0", # Used to call Llama Stack APIs "ogx==1.2.5", "ogx-client==1.2.5", "ogx-api==1.2.5", # Used by Logger "rich>=14.0.0", # Used by JWK token auth handler "cachetools>=6.1.0", # Used for metric exporter "prometheus-client>=0.22.1", # Used for Bearer token extraction "starlette>=0.47.1", # Used by JWK token auth handler "aiohttp>=3.13.3", "authlib>=1.6.0", # Used for A2A protocol support "a2a-sdk>=0.3.4,<0.4.0", # OpenAPI exporter "email-validator>=2.2.0", "openai>=1.99.9", # Used by database interface "sqlalchemy[asyncio]>=2.0.42", # Async database drivers for A2A persistent storage "aiosqlite>=0.21.0", "asyncpg>=0.31.0", # Used by OGX version checker "semver<4.0.0", # Used by authorization resolvers "jsonpath-ng>=1.6.1,<1.9.0", "psycopg2-binary>=2.9.10", "urllib3>=2.6.3", # Used for agent card configuration "PyYAML>=6.0.0", # Used for rag faiss support "einops>=0.8.1", # Used for Azure Entra ID token management "azure-core>=1.38.0", "azure-identity>=1.21.0", "pyasn1>=0.6.3", # LCORE-1490 # Used for system prompt template variable rendering "jinja2>=3.1.0", # To be able to fix multiple CVEs, also LCORE-1117 "requests>=2.33.0", # Transitive via kubernetes/requests-oauthlib (CVE-2026-49264, CVE-2026-49265) "oauthlib>=4.0.0", # Transitive via mcp, msal, ogx (CVE-2026-48522, CVE-2026-102265, GHSA 2.14+) "PyJWT>=2.15.1", # Used for RAG chunk reranking (cross-encoder) "datasets>=4.7.0", # Used for error tracking and monitoring "sentry-sdk[fastapi]>=2.58.0", "python-dotenv>=1.2.2", # Used for token estimation before LLM calls (LCORE-1569 / conversation compaction) "tiktoken>=0.8.0", # Used for model context windows in conversation compaction (LCORE-4765) "genai-prices>=0.1.12", # Used for Pydantic AI "pydantic-ai==2.38.0", "pydantic-ai-skills>=0.11.0,<2.0.0", # Used for OpenTelemetry instrumentation "opentelemetry-distro>=0.49b0", "opentelemetry-exporter-otlp>=1.34.1", "opentelemetry-instrumentation-fastapi>=0.49b0", ] [tool.pyright] exclude = [ ] extraPaths = ["./src"] [tool.pdm] distribution = true [tool.pdm.version] source = "file" path = "src/version.py" [tool.behave] paths = ["tests/e2e/features"] [project.scripts] lightspeed-stack = "lightspeed_stack:main" [project.urls] Homepage = "https://github.com/lightspeed-core/lightspeed-stack" Issues = "https://github.com/lightspeed-core/lightspeed-stack/issues" # PyTorch has multiple wheel variants for different backends - cpu, gpu, etc. # By default on pypi.org is the gpu variant. Forces uv to use the cpu variant. [[tool.uv.index]] name = "pytorch-cpu" url = "https://download.pytorch.org/whl/cpu" explicit = true [tool.uv.sources] torch = [ { index = "pytorch-cpu", group = "ogxlibdev" }, ] [dependency-groups] dev = [ "black>=26.1.0", "pytest>=8.3.2", "pytest-cov>=5.0.0", "pytest-mock>=3.14.0", "pytest-asyncio>=1.0.0", "pytest-order>=1.2.0", "pyright>=1.1.401", "pylint>=3.3.7", "pydocstyle>=6.3.0", "mypy>=2.0.0", "types-PyYAML>=6.0.2", "types-requests>=2.28.0", "ruff>=0.11.13", "aiosqlite", "behave>=1.3.0", "trustme>=1.2.1", "types-cachetools>=6.1.0.20250717", "build>=1.2.2.post1", "twine>=6.1.0", "openapi-to-md>=0.1.0b2", "pytest-subtests>=0.14.2", "bandit>=1.8.6", "pybuild-deps>=0.5.0", "pip==26.1", "pytest-benchmark>=5.2.3", "pyroscope-io>=0.8.7", "memray>=1.13.0", "pygal>=3.1.3", "pygaljs>=1.0.2", "pdm>=2.29.2", ] ogxlibdev = [ # To check OGX API provider dependecies: # # $ uv run ogx stack list-providers # # API agents: inline::meta-reference # commented out because they are not used in the project # "matplotlib>=3.10.0", # "pillow>=11.1.0", # "pandas>=2.2.3", # "scikit-learn>=1.5.2", # API eval: inline::meta-reference "tree_sitter>=0.24.0", "pythainlp>=3.0.10", "langdetect>=1.0.9", "emoji>=2.1.0", "nltk>=3.8.1", # API inference: inline::sentence-transformers "sentence-transformers>=5.6.0", # API vector_io: inline::faiss, inline::sqlite-vec, remote::pgvector "faiss-cpu>=1.11.0", "chardet>=5.2.0", "psycopg2-binary>=2.9.10", "pgvector>=0.3.6", "pypdf>=6.19.0", # API scoring: inline::basic "requests>=2.33.0", # API datasetio: inline::localfs "aiosqlite>=0.21.0", # API datasetio: remote::huggingface "datasets>=3.6.0", # API telemetry: inline::meta-reference "opentelemetry-sdk>=1.34.1", "opentelemetry-exporter-otlp>=1.34.1", # API tool_runtime: inline::rag-runtime "transformers>=4.34.0", "numpy==2.3.5", # API tool_runtime: remote::model-context-protocol "mcp>=1.23.0", # API post_training: inline::huggingface "torch==2.11.0", "trl>=0.18.2", "peft>=0.15.2", # API inference: remote::vertexai "google-cloud-aiplatform>=1.130.0", # Other "autoevals>=0.0.129", "fire>=0.7.0", "opentelemetry-instrumentation>=0.55b0", "psutil>=7.0.0", # Azure "azure-identity>=1.21.0", # Lightspeed providers "httpx>=0.27.0", "pydantic>=2.10.6", "protobuf>=6.33.5", "filelock>=3.20.3", "uv-build==0.11.8", ] build = [ "build>=1.2.2.post1", "twine>=6.1.0", ] [tool.pytest.ini_options] asyncio_mode = "auto" pythonpath = [ "src" ] addopts = [ "--import-mode=importlib", ] markers = [ "destructive: marks tests as destructive (deselect with '-m \"not destructive\"')", "order: controls test execution order (requires pytest-order plugin)", ] [tool.pylint.main] source-roots = "src" ignore = ["query.py"] [build-system] requires = ["pdm-backend"] build-backend = "pdm.backend" [tool.pylint."MESSAGES CONTROL"] disable = ["R0801"] [tool.ruff] line-length = 88 extend-exclude = ["tests/profiles/syntax_error.py"] [tool.ruff.lint] extend-select = ["C", "FA", "FLY", "I", "ISC", "TID251", "UP", "RUF100", "B009", "B010", "B011", "BLE", "DTZ005", "D202", "PLR1733", "RUF022", "PLW1510", "TC004", "PIE790", "PERF402", "FURB129", "RET501", "LOG", "D413", "PT006"] ignore = ["UP047", "UP045", "S", "C901", "RUF", "SIM", "B017", "TRY004", "TRY201", "TRY203", "TRY401", "B008", "EXE001", "G201", "PYI034", "PYI064"] [tool.ruff.lint.flake8-tidy-imports.banned-api] unittest = { msg = "use pytest instead of unittest" } # commented temporarily - Dependabot has problems with this line for some reason #"unittest.mock" = { msg = "use pytest-mock instead of unittest.mock" } [tool.mypy] explicit_package_bases = true disallow_untyped_calls = true disallow_untyped_defs = true disallow_incomplete_defs = true ignore_missing_imports = true disable_error_code = "attr-defined"