[build-system]
build-backend = "poetry.core.masonry.api"
requires = [
  "poetry-core",
]

[tool.poetry]
name = "openhands-ai"
version = "1.1.0"
description = "OpenHands: Code Less, Make More"
authors = [ "OpenHands" ]
license = "MIT"
readme = "README.md"
repository = "https://github.com/OpenHands/OpenHands"
packages = [
  { include = "openhands/**/*" },
  { include = "third_party/**/*" },
  { include = "pyproject.toml", to = "openhands" },
  { include = "poetry.lock", to = "openhands" },
]
include = [
  "skills/**/*",
]

[tool.poetry.dependencies]
python = "^3.12,<3.14"
litellm = ">=1.74.3, !=1.64.4, !=1.67.*"           # avoid 1.64.4 (known bug) & 1.67.* (known bug #10272)
openai = "2.8.0"                                   # Pin due to litellm incompatibility with >=1.100.0 (BerriAI/litellm#13711)
aiohttp = ">=3.9.0,!=3.11.13"                      # Pin to avoid yanked version 3.11.13
google-genai = "*"                                 # To use litellm with Gemini Pro API
google-api-python-client = "^2.164.0"              # For Google Sheets API
google-auth-httplib2 = "*"                         # For Google Sheets authentication
google-auth-oauthlib = "*"                         # For Google Sheets OAuth
termcolor = "*"
docker = "*"
fastapi = "*"
toml = "*"
types-toml = "*"
uvicorn = "*"
numpy = "*"
json-repair = "*"
browsergym-core = "0.13.3"                         # integrate browsergym-core as the browsing interface
playwright = "^1.55.0"
html2text = "*"
deprecated = "*"
pexpect = "*"
jinja2 = "^3.1.3"
python-multipart = "*"
tenacity = ">=8.5,<10.0"
zope-interface = "7.2"
pathspec = "^0.12.1"
pyjwt = "^2.9.0"
dirhash = "*"
tornado = "*"
python-dotenv = "*"
rapidfuzz = "^3.9.0"
whatthepatch = "^1.0.6"
protobuf = "^5.0.0,<6.0.0"                         # Updated to support newer opentelemetry
opentelemetry-api = "^1.33.1"
opentelemetry-exporter-otlp-proto-grpc = "^1.33.1"

libtmux = ">=0.46.2"
pygithub = "^2.5.0"
joblib = "*"
openhands-aci = "0.3.2"
python-socketio = "^5.11.4"
sse-starlette = "^3.0.2"
psutil = "*"
python-json-logger = "^3.2.1"
prompt-toolkit = "^3.0.50"
poetry = "^2.1.2"
anyio = "4.9.0"
pythonnet = "*"
fastmcp = "^2.12.4"           # Note: 2.12.0+ has breaking auth API changes
python-frontmatter = "^1.1.0"
shellingham = "^1.5.4"
# TODO: Should these go into the runtime group?
ipywidgets = "^8.1.5"
qtconsole = "^5.6.1"
python-pptx = "*"
pylatexenc = "*"
python-docx = "*"
bashlex = "^0.18"

# Explicitly pinned packages for latest versions
pypdf = "^6.0.0"
pillow = "^11.3.0"
starlette = "^0.48.0"
urllib3 = "^2.5.0"
requests = "^2.32.5"
setuptools = ">=78.1.1"

# TODO: These are integrations that should probably be optional
redis = ">=5.2,<7.0"

google-cloud-aiplatform = "*"
anthropic = { extras = [ "vertex" ], version = "*" }
boto3 = "*"
kubernetes = "^33.1.0"
pyyaml = "^6.0.2"
memory-profiler = "^0.61.0"
jupyter_kernel_gateway = "*"

# Third-party runtime dependencies (optional)
modal = { version = ">=0.66.26,<1.2.0", optional = true }
runloop-api-client = { version = "0.50.0", optional = true }
daytona = { version = "0.24.2", optional = true }
httpx-aiohttp = "^0.1.8"
e2b-code-interpreter = { version = "^2.0.0", optional = true }
pybase62 = "^1.0.0"

# V1 dependencies
#openhands-agent-server = { git = "https://github.com/OpenHands/agent-sdk.git", subdirectory = "openhands-agent-server", rev = "15f565b8ac38876e40dc05c08e2b04ccaae4a66d" }
#openhands-sdk = { git = "https://github.com/OpenHands/agent-sdk.git", subdirectory = "openhands-sdk", rev = "15f565b8ac38876e40dc05c08e2b04ccaae4a66d" }
#openhands-tools = { git = "https://github.com/OpenHands/agent-sdk.git", subdirectory = "openhands-tools", rev = "15f565b8ac38876e40dc05c08e2b04ccaae4a66d" }
openhands-sdk = "1.7.3"
openhands-agent-server = "1.7.3"
openhands-tools = "1.7.3"
python-jose = { version = ">=3.3", extras = [ "cryptography" ] }
sqlalchemy = { extras = [ "asyncio" ], version = "^2.0.40" }
pg8000 = "^1.31.5"
asyncpg = "^0.30.0"
deprecation = "^2.1.0"
lmnr = "^0.7.20"

[tool.poetry.extras]
third_party_runtimes = [ "e2b-code-interpreter", "modal", "runloop-api-client", "daytona" ]

[tool.poetry.group.dev]
optional = true

[tool.poetry.group.dev.dependencies]
ruff = "0.12.5"
mypy = "1.17.0"
pre-commit = "4.2.0"
build = "*"
types-setuptools = "*"
pytest = "^8.4.0"
pytest-asyncio = "^1.3.0"

[tool.poetry.group.test]
optional = true

[tool.poetry.group.test.dependencies]
pytest = "*"
pytest-cov = "*"
pytest-asyncio = "*"
pytest-forked = "*"
pytest-xdist = "*"
pytest-playwright = "^0.7.0"
pytest-timeout = "^2.4.0"
pandas = "*"
reportlab = "*"
gevent = ">=24.2.1,<26.0.0"

[tool.poetry.group.runtime]
optional = true

[tool.poetry.group.runtime.dependencies]
jupyterlab = "*"
notebook = "*"
flake8 = "*"

[tool.poetry.group.evaluation]
optional = true

[tool.poetry.group.evaluation.dependencies]
streamlit = "*"
whatthepatch = "*"
retry = "*"
evaluate = "*"
visualswebench = { git = "https://github.com/luolin101/Visual-SWE-bench.git" }
swegym = { git = "https://github.com/SWE-Gym/SWE-Bench-Package.git" }
commit0 = "*"
func_timeout = "*"
sympy = "*"
gdown = "*"
matplotlib = "*"
seaborn = "*"
tabulate = "*"
browsergym = "0.13.3"
browsergym-webarena = "0.13.3"
browsergym-miniwob = "0.13.3"
browsergym-visualwebarena = "0.13.3"
boto3-stubs = { extras = [ "s3" ], version = "^1.37.19" }
# transitive dependency, pinned here to avoid conflicts
pyarrow = "21.0.0"
datasets = "*"
joblib = "*"
swebench = { git = "https://github.com/ryanhoangt/SWE-bench.git", rev = "fix-modal-patch-eval" }
multi-swe-bench = "0.1.2"
pandas = "*"
# tau-bench = { git = "https://github.com/sierra-research/tau-bench.git" }
# bfcl-eval = "*" # TODO: Verify exact package name/source

[tool.poetry.group.testgeneval.dependencies]
fuzzywuzzy = "^0.18.0"
rouge = "^1.0.1"
python-levenshtein = ">=0.26.1,<0.28.0"
tree-sitter-python = "^0.23.6"

[tool.poetry-dynamic-versioning]
enable = true
style = "semver"

[tool.autopep8]
# autopep8 fights with mypy on line length issue
ignore = [ "E501" ]

[tool.black]
# prevent black (if installed) from changing single quotes to double quotes
skip-string-normalization = true

[tool.ruff]
lint.select = [ "D" ]
# ignore warnings for missing docstrings
lint.ignore = [ "D1" ]
lint.pydocstyle.convention = "google"

[tool.coverage.run]
concurrency = [ "gevent" ]
relative_files = true
omit = [ "enterprise/tests/*", "**/test_*" ]
