Files
Octop/pyproject.toml
2026-09-26 16:36:31 +00:00

218 lines
5.6 KiB
TOML

[build-system]
requires = ["hatchling>=1.18"]
build-backend = "hatchling.build"
[project]
name = "octop"
version = "1.0.2b3"
description = "Smarter self-hosted AI assistant for multiple users and agents, built on octop-harness"
readme = "README.md"
license = { text = "MIT" }
requires-python = ">=3.12"
authors = [{name = "octop contributors"}]
dependencies = [
"fastapi>=0.110",
"uvicorn[standard]>=0.27",
"pydantic>=2.6,<2.14",
"langchain-core>=1.4.8",
"click>=8.1",
"rich>=13.7",
"questionary>=2.0",
"apscheduler>=3.10,<4",
"argon2-cffi>=23.1",
"pyjwt>=2.8",
"octop-harness[all]>=1.0.0",
"octop-memory>=1.0.0",
"lark-oapi>=1.7.3",
"octop-gateway>=1.0.0",
"cryptography>=41",
"scalar-fastapi>=1.0",
"edge-tts>=6.1",
"segno>=1.6",
"websockets>=13.0",
"acme>=5.6.0",
"josepy>=2.2.0",
"boto3>=1.40.61",
"octop-browser>=1.0.0",
"playwright>=1.40",
"psycopg[binary]>=3.2",
"langgraph-checkpoint-postgres>=2.0",
"mcp>=1.9,<2",
"pillow>=10.0",
"pypdf>=5.0",
"python-docx>=1.2.0",
"python-pptx>=1.0",
"pypinyin>=0.53",
"openpyxl>=3.1",
"xlrd>=2.0.1",
]
[project.optional-dependencies]
# PEP 621 extras — kept so `pip install -e ".[dev]"` keeps working for
# legacy / CI flows. `uv sync` reads `[dependency-groups].dev` below.
dev = [
"pytest>=8.0",
"pytest-asyncio>=0.23",
"pytest-cov>=4.1",
"pytest-testmon>=2.0",
"pytest-xdist>=3.6",
"httpx>=0.27",
"ruff>=0.4",
"mypy>=1.10",
"build>=1.0",
"xlwt>=1.3",
]
# Kept for backward compatibility; playwright is now a core dependency.
browser = [
"playwright>=1.40",
]
# Kept for backward compatibility; pillow is now a core dependency.
desktop = ["mss>=9.0", "pynput>=1.7"]
# Local ONNX / fastembed embedding models (Models admin local tab).
local-embedding = ["fastembed>=0.4", "huggingface_hub>=0.20"]
knowledge-ocr = [
"rapidocr>=3.4,<4",
"onnxruntime>=1.17",
"pymupdf>=1.24",
]
[dependency-groups]
# PEP 735 dev group — installed by default on `uv sync`. Mirrors the
# `[project.optional-dependencies].dev` list above.
dev = [
"pytest>=8.0",
"pytest-asyncio>=0.23",
"pytest-cov>=4.1",
"pytest-testmon>=2.0",
"pytest-xdist>=3.6",
"httpx>=0.27",
"ruff>=0.4",
"mypy>=1.10",
"build>=1.0",
"xlwt>=1.3",
]
[project.scripts]
octop = "octop.cli.main:cli"
[tool.hatch.build.targets.wheel]
packages = ["src/octop"]
[tool.hatch.build]
include = [
"src/octop/**/*.py",
"src/octop/**/*.json",
"src/octop/**/*.md",
"src/octop/**/*.sql",
"src/octop/**/*.sh",
"src/octop/**/*.png",
"src/octop/dashboard/**/*",
"src/octop/infra/agents/experts/library/**/*",
"src/octop/infra/agents/plugins/bundled/**/*",
"src/octop/infra/agents/subagents/library/**/*",
"src/octop/infra/agents/subagents/divisions.json",
"src/octop/infra/desktop/scripts/**/*",
]
artifacts = [
"src/octop/dashboard/**/*",
]
[tool.ruff]
line-length = 100
target-version = "py312"
src = ["src", "tests"]
include = ["*.py", "*.pyi", "*.pyw", "*.ipynb", "**/pyproject.toml", "**/ruff.toml", "**/.ruff.toml"]
[tool.ruff.lint]
select = ["E", "F", "W", "I", "B", "UP", "SIM", "C4"]
ignore = ["E501"]
[tool.ruff.lint.per-file-ignores]
"tests/**" = ["B011"]
"src/octop/api/**" = ["B008"]
[tool.mypy]
python_version = "3.12"
strict = true
ignore_missing_imports = true
files = ["src/octop"]
exclude = [
"src/octop/dashboard/",
"src/octop/infra/agents/experts/library/",
"src/octop/infra/agents/plugins/bundled/",
"src/octop/infra/agents/subagents/library/",
]
[[tool.mypy.overrides]]
module = "tests.*"
disallow_untyped_defs = false
[[tool.mypy.overrides]]
module = "octop.api.routers.auth"
disallow_untyped_defs = false
[[tool.mypy.overrides]]
module = "octop.api.routers.health"
disallow_untyped_defs = false
[[tool.mypy.overrides]]
module = "octop.api.routers.setup"
disallow_untyped_defs = false
[[tool.mypy.overrides]]
module = "octop.api.routers.users"
disallow_untyped_defs = false
[[tool.mypy.overrides]]
module = "octop.api.routers.agents"
disallow_untyped_defs = false
[[tool.mypy.overrides]]
module = "octop.api.routers.providers"
disallow_untyped_defs = false
[[tool.mypy.overrides]]
module = "octop.api.routers.chat"
disallow_untyped_defs = false
[[tool.mypy.overrides]]
module = "octop.api.routers.channels"
disallow_untyped_defs = false
[[tool.mypy.overrides]]
module = "octop.api.routers.cron"
disallow_untyped_defs = false
[[tool.mypy.overrides]]
module = "octop.api.routers.admin"
disallow_untyped_defs = false
[[tool.mypy.overrides]]
module = "octop.api.app"
disallow_untyped_defs = false
[[tool.mypy.overrides]]
module = "octop.infra.utils.posix_compat"
disable_error_code = ["attr-defined"]
[[tool.mypy.overrides]]
module = "octop.infra.utils.subprocess_io_win"
disable_error_code = ["attr-defined"]
[tool.pytest.ini_options]
testpaths = ["tests"]
asyncio_mode = "auto"
markers = [
"live: tests that hit real LLM / external services (skipped by default)",
"slow: expensive tests (integration boot, real harness, browser); skipped by make test-fast",
"postgresql: tests that need a live PostgreSQL (set OCTOP_TEST_DATABASE_URL)",
]
# The project pins a starlette fork (1.3.1) whose TestClient prefers a
# private ``httpx2`` build that is not installable from PyPI. When ``httpx2``
# is absent it falls back to ``httpx`` and emits a non-actionable
# StarletteDeprecationWarning on every ``starlette.testclient`` import. The
# fallback is intentional for this environment, so silence the noise.
filterwarnings = [
"ignore::starlette.exceptions.StarletteDeprecationWarning",
]