[build-system]
requires = [
    "setuptools>=61.0",
    "setuptools-scm>=8.0",
    "cmake>=3.15",
    "wheel",
]
build-backend = "setuptools.build_meta"

[project]
name = "openviking"
dynamic = ["version"]
description = "An Agent-native context database"
readme = "README.md"
requires-python = ">=3.10"
authors = [
    {name = "ByteDance", email = "noreply@bytedance.com"}
]
license = { text = "Apache-2.0" }
classifiers = [
    "Development Status :: 3 - Alpha",
    "Intended Audience :: Developers",
    "Topic :: Scientific/Engineering :: Artificial Intelligence",
    "Programming Language :: Python :: 3",
    "Programming Language :: Python :: 3.10",
    "Programming Language :: Python :: 3.11",
    "Programming Language :: Python :: 3.12",
    "Programming Language :: Python :: 3.13",
    "Programming Language :: Python :: 3.14",
]
dependencies = [
    "pydantic>=2.0.0",
    "typing-extensions>=4.5.0",
    "pyyaml>=6.0",
    "httpx>=0.25.0",
    "pdfplumber>=0.10.0",
    "readabilipy>=0.2.0",
    "markdownify>=0.11.0",
    "openai>=1.0.0",
    "requests>=2.31.0",
    "python-docx>=1.0.0",
    "olefile>=0.47",
    "xlrd>=2.0.1",
    "python-pptx>=1.0.0",
    "openpyxl>=3.0.0",
    "ebooklib>=0.18.0",
    "json-repair>=0.25.0",
    "apscheduler>=3.11.0",
    "volcengine>=1.0.216",
    "volcengine-python-sdk[ark]>=5.0.3",
    "fastapi>=0.128.0",
    "uvicorn>=0.39.0",
    "xxhash>=3.0.0",
    "jinja2>=3.1.6",
    "tabulate>=0.9.0",
    "urllib3>=2.6.3",
    "protobuf>=6.33.5",
    "pdfminer-six>=20251230",
    "typer>=0.12.0",
    "litellm>=1.0.0,<1.82.6",
    "python-multipart>=0.0.22",
    "tree-sitter>=0.23.0",
    "tree-sitter-python>=0.23.0",
    "tree-sitter-javascript>=0.23.0",
    "tree-sitter-typescript>=0.23.0",
    "tree-sitter-java>=0.23.0",
    "tree-sitter-cpp>=0.23.0",
    "tree-sitter-rust>=0.23.0",
    "tree-sitter-go>=0.23.0",
    "tree-sitter-c-sharp>=0.23.0",
    "loguru>=0.7.3",
    "cryptography>=42.0.0",
    "argon2-cffi>=23.0.0",
]

[tool.uv.sources]
pyagfs = { path = "third_party/agfs/agfs-sdk/python" }

[project.optional-dependencies]
test = [
    "pytest>=7.0.0",
    "pytest-asyncio>=0.21.0",
    "boto3>=1.42.44",
    "pytest-cov>=4.0.0",
    "ragas>=0.1.0",
    "datasets>=2.0.0",
    "pandas>=2.0.0",
    "diff-match-patch>=20200713",
    "hvac>=2.0.0",
]
dev = [
    "mypy>=1.0.0",
    "ruff>=0.1.0",
]
doc = [
    "sphinx>=7.0.0",
    "sphinx-rtd-theme>=1.3.0",
    "myst-parser>=2.0.0",
]
eval = [
    "ragas>=0.1.0",
    "datasets>=2.0.0",
    "pandas>=2.0.0",
]
gemini = [
    "google-genai>=1.0.0",
]
gemini-async = [
    "google-genai>=1.0.0",
    "anyio>=4.0.0",
]
build = [
    "setuptools>=61.0",
    "setuptools-scm>=8.0",
    "cmake>=3.15",
    "wheel",
    "build",
]
# vikingbot core dependencies
bot = [
    "pydantic-settings>=2.0.0",
    "websockets>=12.0",
    "websocket-client>=1.6.0",
    "httpx[socks]>=0.25.0",
    "readability-lxml>=0.8.0",
    "rich>=13.0.0",
    "croniter>=2.0.0",
    "socksio>=1.0.0",
    "python-socketio>=5.11.0",
    "msgpack>=1.0.8",
    "python-socks[asyncio]>=2.4.0",
    "prompt-toolkit>=3.0.0",
    "pygments>=2.16.0",
    "html2text>=2020.1.16",
    "beautifulsoup4>=4.12.0",
    "ddgs>=9.0.0",
    "tavily-python>=0.5.0",
    "gradio>=6.6.0",
    "py-machineid>=1.0.0",
]
# vikingbot optional features
bot-langfuse = ["langfuse>=3.0.0"]
bot-telegram = ["python-telegram-bot[socks]>=21.0"]
bot-feishu = ["lark-oapi>=1.0.0"]
bot-dingtalk = ["dingtalk-stream>=0.4.0"]
bot-slack = ["slack-sdk>=3.26.0"]
bot-qq = ["qq-botpy>=1.0.0"]
bot-sandbox = [
    "opensandbox>=0.1.0",
    "opensandbox-server>=0.1.0",
    "agent-sandbox>=0.0.23",
]
bot-fuse = ["fusepy>=3.0.1"]
bot-opencode = ["opencode-ai>=0.1.0a0"]
bot-full = [
    "openviking[bot,bot-langfuse,bot-telegram,bot-feishu,bot-dingtalk,bot-slack,bot-qq,bot-sandbox,bot-fuse,bot-opencode]",
]

[project.urls]
Homepage = "https://github.com/volcengine/openviking"
Documentation = "https://openviking.ai"
Repository = "https://github.com/volcengine/openviking"
Issues = "https://github.com/volcengine/openviking/issues"

[project.scripts]
ov = "openviking_cli.rust_cli:main"  # Rust CLI 入口（极简包装器）
openviking = "openviking_cli.rust_cli:main"  # Rust CLI 入口（放弃 python CLI）
openviking-server = "openviking_cli.server_bootstrap:main"
vikingbot = "vikingbot.cli.commands:app"

[tool.setuptools_scm]
write_to = "openviking/_version.py"
local_scheme = "no-local-version"
tag_regex = "^(?:v)?(?:[a-zA-Z0-9_]+@)?(?P<version>[0-9]+(?:\\.[0-9]+)*)$"

[tool.setuptools.packages.find]
where = [".", "bot"]
include = ["openviking*", "vikingbot*"]
exclude = ["tests*", "docs*", "examples*"]

[tool.setuptools.package-data]
openviking = [
    "prompts/templates/**/*.yaml",
    "bin/agfs-server",
    "bin/agfs-server.exe",
    "lib/libagfsbinding.so",
    "lib/libagfsbinding.dylib",
    "lib/libagfsbinding.dll",
    "bin/ov",
    "bin/ov.exe",
    "storage/vectordb/engine/*.abi3.so",
    "storage/vectordb/engine/*.pyd",
]
vikingbot = [
    "**/*.mjs",
    "skills/**/*.md",
    "skills/**/*.sh",
    "console/static/**/*",
    "bridge/**/*",
]

[tool.mypy]
python_version = "3.10"
warn_return_any = false
warn_unused_configs = true
disallow_untyped_defs = false
disallow_incomplete_defs = false
check_untyped_defs = true
no_implicit_optional = false
warn_redundant_casts = true
warn_unused_ignores = true
ignore_missing_imports = true

[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py"]
python_classes = ["Test*"]
python_functions = ["test_*"]
asyncio_mode = "auto"
addopts = "-v --cov=openviking --cov-report=term-missing"

[tool.ruff]
line-length = 100
exclude = ["third_party"]
target-version = "py310"

[tool.ruff.lint]
select = [
    "E",  # pycodestyle errors
    "W",  # pycodestyle warnings
    "F",  # pyflakes
    "I",  # isort
    "C",  # flake8-comprehensions
    "B",  # flake8-bugbear
]
ignore = [
    "E501",  # line too long (handled by black)
    "B008",  # do not perform function calls in argument defaults
    "C901",  # too complex
    "B006",  # Do not use mutable data structures for argument defaults
    "B904",  # Within an `except` clause, raise exceptions with `raise ... from err`
    "E741",  # Ambiguous variable name
    "E722",  # Do not use bare `except`
    "B027",  # empty method in an abstract base class
]

[tool.ruff.lint.per-file-ignores]
"__init__.py" = ["F401"]  # Allow unused imports in __init__.py

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

[dependency-groups]
dev = [
    "pytest>=9.0.2",
]
