[build-system]
requires = [
    "pdm-backend>=2.4.3",
]
build-backend = "pdm.backend"

[project]
name = "local-deep-research"
dynamic = []
description = "AI-powered research assistant with deep, iterative analysis using LLMs and web searches"
readme = "README.md"
requires-python = ">=3.11,<3.15"
authors = [
    { name = "LearningCircuit", email = "185559241+LearningCircuit@users.noreply.github.com" },
    { name = "HashedViking", email = "6432677+HashedViking@users.noreply.github.com" },
    { name = "djpetti", email = "djpetti@gmail.com" },
]
classifiers = [
    "Programming Language :: Python :: 3",
    "License :: OSI Approved :: MIT License",
    "Operating System :: OS Independent",
]
dependencies = [
    "langchain~=1.1",
    "langchain-community~=0.4",
    "langchain-core~=1.1",
    "langchain-ollama~=1.0",
    "langchain-openai~=1.1",
    "langchain-anthropic~=1.2",
    "duckduckgo-search~=8.1",
    "python-dateutil~=2.9",
    "typing-extensions~=4.15",
    "justext~=3.0",
    "playwright~=1.56",
    "beautifulsoup4~=4.14",
    "flask~=3.1",
    "flask-cors~=6.0",
    "flask-socketio~=5.5",
    "sqlalchemy~=2.0",
    "sqlalchemy-utc~=0.14",
    "wikipedia~=1.4",
    "arxiv~=2.3",
    "pypdf~=6.4",
    "sentence-transformers~=5.1",
    "faiss-cpu~=1.13",
    "pydantic~=2.12",
    "pydantic-settings~=2.12",
    "toml~=0.10",
    "platformdirs~=4.5",
    "dynaconf~=3.2",
    "requests~=2.32",
    "tiktoken~=0.12",
    "xmltodict~=1.0",
    "lxml~=6.0",
    "pdfplumber~=0.11",
    "unstructured~=0.18",
    "google-search-results~=2.4",
    "importlib-resources~=6.5",
    "setuptools~=80.9",
    "flask-wtf~=1.2",
    "optuna~=4.6",
    "elasticsearch~=9.2",
    "methodtools~=0.4",
    "loguru~=0.7",
    "cachetools~=6.2",
    "matplotlib~=3.10",
    "pandas~=2.3",
    "plotly~=6.5",
    "kaleido~=1.2",
    "aiohttp~=3.13",
    "tenacity~=9.1",
    "apscheduler~=3.11",
    "rich~=14.2",
    "click~=8.3",
    "flask-login~=0.6",
    "flask-limiter~=4.1",
    "sqlcipher3-binary~=0.5; sys_platform == \"linux\" and platform_machine == \"x86_64\"",
    "sqlcipher3~=0.5; (platform_machine == \"aarch64\" or platform_machine == \"arm64\") and sys_platform == \"linux\"",
    "sqlcipher3~=0.5; sys_platform != \"linux\"",
    "lxml-html-clean~=0.4",
    "weasyprint~=67.0",
    "apprise~=1.9",
    "markdown~=3.10",
    "datasets~=4.4",
    "pyarrow~=22.0",
    "langchain-experimental~=0.4",
]
version = "1.3.13"

[project.license]
file = "LICENSE"

[project.optional-dependencies]
vllm = [
    "torch>=2.0.0",
    "transformers>=4.30.0",
    "vllm>=0.4.0",
]

[project.urls]
Homepage = "https://github.com/LearningCircuit/local-deep-research"
"Bug Tracker" = "https://github.com/LearningCircuit/local-deep-research/issues"

[project.scripts]
ldr = "local_deep_research.main:main"
ldr-web = "local_deep_research.web.app:main"

[tool.setuptools]
include-package-data = true

[tool.setuptools.package-data]
"local_deep_research.web" = [
    "templates/*",
    "static/*",
    "static/**/*",
]
"local_deep_research.defaults" = [
    "*.toml",
    "*.py",
    "*.template",
    ".env.template",
]
"local_deep_research.notifications" = [
    "templates/*.jinja2",
]

[tool.pdm]
distribution = true

[tool.pdm.version]
source = "file"
path = "src/local_deep_research/__version__.py"

[[tool.pdm.source]]
url = "https://download.pytorch.org/whl/cpu"
name = "torch"
include_packages = [
    "torch",
    "torch*",
]

[tool.pytest.ini_options]
markers = [
    "requires_llm: marks tests that require a real LLM (not fallback)",
    "integration: marks integration tests",
    "slow: marks slow tests",
    "asyncio: marks async tests that use asyncio",
]

[tool.ruff]
exclude = [
    ".bzr",
    ".direnv",
    ".eggs",
    ".git",
    ".git-rewrite",
    ".hg",
    ".ipynb_checkpoints",
    ".mypy_cache",
    ".nox",
    ".pants.d",
    ".pyenv",
    ".pytest_cache",
    ".pytype",
    ".ruff_cache",
    ".svn",
    ".tox",
    ".venv",
    ".vscode",
    "__pypackages__",
    "_build",
    "buck-out",
    "build",
    "dist",
    "node_modules",
    "site-packages",
    "venv",
]
line-length = 80
indent-width = 4

[tool.ruff.lint]
select = [
    "E4",
    "E7",
    "E9",
    "F",
]
ignore = [
    "E722",
]
fixable = [
    "ALL",
]
unfixable = []
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"

[tool.ruff.format]
quote-style = "double"
indent-style = "space"
skip-magic-trailing-comma = false
line-ending = "auto"

[tool.mypy]
python_version = "3.11"
warn_return_any = true
warn_unused_configs = true
disallow_untyped_defs = false
check_untyped_defs = true
warn_redundant_casts = true
warn_unused_ignores = true
no_implicit_optional = true
strict_equality = true
show_error_codes = true
ignore_missing_imports = true
overrides = [
    { module = "tests.*", ignore_errors = true },
]

[dependency-groups]
dev = [
    "pre-commit~=4.5",
    "jupyter~=1.1",
    "cookiecutter~=2.6",
    "pandas~=2.3",
    "optuna~=4.6",
    "pytest-mock~=3.15",
    "pytest~=9.0",
    "pytest-cov~=7.0",
    "pytest-timeout~=2.4",
    "pytest-asyncio~=1.3",
    "pytest-xdist~=3.5",
    "ruff~=0.14",
    "freezegun~=1.5",
    "mypy~=1.19",
    "types-requests~=2.32",
    "types-setuptools~=80.9",
    "types-toml~=0.10",
    "hypothesis~=6.148",
]
