[project]
name = "openjiuwen"
version = "0.1.5"
description = "openJiuwen agent-core is a feature-rich AI agent SDK for developing, running, tuning, and improving your AI agents."
readme = "README.md"
requires-python = ">=3.11,<3.14"
classifiers = [
    'Development Status :: 4 - Beta',
    'Programming Language :: Python',
    'Programming Language :: Python :: Implementation :: CPython',
    'Programming Language :: Python :: 3',
    'Programming Language :: Python :: 3 :: Only',
    'Programming Language :: Python :: 3.11',
    'Programming Language :: Python :: 3.12',
    'Programming Language :: Python :: 3.13',
]
dependencies = [
    # HTTP clients
    "aiohttp>=3.11.12",
    "requests>=2.32.3",
    # Date & time
    "python-dateutil>=2.9.0.post0",
    # File & locking
    "filelock>=3.20.1",
    "portalocker>=3.2.0",
    "aiofiles>=25.1.0",
    # Database ORM
    "sqlalchemy>=2.0.41",
    # AI/LLM
    "openai>=1.108.0",
    "transformers>=4.52.4",
    "tiktoken>=0.12.0",
    "dashscope>=1.25.6",
    # Vector database
    "pymilvus>=2.6.2",
    # MCP server
    "fastmcp>=2.14.2,<3.0",
    # Document processing
    "docx2txt>=0.8",
    "python-docx>=1.2.0",
    "pdfplumber>=0.11.8",
    # Utilities
    "numpy!=2.4.0",
    "cacheout>=0.16.0",
    "mermaid-py>=0.8.0",
    "pycryptodome>=3.23.0",
    "charset-normalizer>=3.4.4",
    "pysbd>=0.3.4",
    "oauthlib>=3.3.1",
    "json-repair>=0.55.0",
    "agent-sandbox>=0.0.21",
]

[project.optional-dependencies]
pulsar = ["pulsar-client>=3.5.0"]
redis = ["redis>=7.1.0"]
sqlite = ["aiosqlite>=0.22.1", "greenlet>=3.1.1"]
mysql = ["aiomysql>=0.3.2"]
pgvector = ["pgvector>=0.2.0"]
chromadb = ["chromadb>=1.3.7"]
obs = ["aioboto3>=11.0.0"]
sandbox-docker = ["docker>=7.0.0"]

all-mq = ["openjiuwen[pulsar]"]
all-storage = ["openjiuwen[sqlite,mysql,redis,obs]"]
all-vector = ["openjiuwen[pgvector,chromadb]"]

default = []
all = ["openjiuwen[all-mq,all-storage-sql,all-storage-vector]"]

[dependency-groups]
# Testing
test = [
    "pytest>=8.3.5",
    "pytest-asyncio>=1.0.0",
    "pytest-html>=4.1.1",
    "pytest-mock>=3.14.0",
    "pytest-cov>=7.0.0",
    "coverage>=7.7.1",
]
# Linting & formatting
lint = [
    "ruff>=0.11.2",
    "pylint>=3.0.0",
    "mypy>=1.12.0",
    "codespell>=2.2.4",
]
# Documentation
docs = [
    "autodoc-pydantic>=2.2.0",
]

dev = [{ include-group = "test" }, { include-group = "lint" }, { include-group = "docs" }]

[project.urls]
Homepage = "https://openjiuwen.com"
Documentation = "https://openjiuwen.com/docs-page"
Repository = "https://gitcode.com/openJiuwen/agent-core.git"
Changelog = "https://gitcode.com/openJiuwen/agent-core/releases"

[tool.uv]
default-groups = ['dev']

[[tool.uv.index]]
name = "aliyun"
url = "https://mirrors.aliyun.com/pypi/simple"
default = true

[tool.coverage.run]
omit = ["tests/*"]

[tool.pytest.ini_options]
asyncio_default_fixture_loop_scope = "function"
testpaths = ["tests"]
pythonpath = ["jiuwen"]
addopts = ["-v", "--html=report/index.html", "--self-contained-html"]

# Formatting & Linting
[tool.ruff]
line-length = 120
target-version = "py311"

[tool.pylint.MAIN]
ignore-paths = ["^(examples|tests)/.*"]
load-plugins = ["pylint.extensions.bad_builtin"]
py-version = "3.11"

[tool.pylint."DEPRECATED BUILTINS"]
bad-functions = ["print"]

[tool.pylint.FORMAT]
max-line-length = 120

[tool.pylint.DESIGN]
max-return = 5
max-args = 10
max-locals = 15
max-branches = 25

[tool.pylint."MESSAGES CONTROL"]
disable = [
    "import-outside-toplevel",
    "missing-module-docstring",
    "too-few-public-methods",
    "use-dict-literal",
    "use-list-literal",
    "unused-argument",
    "too-many-nested-blocks",
    "too-many-positional-arguments",
    "too-many-instance-attributes",
    "too-many-ancestors",
    "broad-exception-caught",
    "broad-exception-raised",
    "missing-timeout",
]

# Type Checking
[tool.mypy]
python_version = "3.11"

# Required to catch inconsistent return types
check_untyped_defs = true

# Ignore certain issues to stay minimal
disable_error_code = ["index"]
disallow_untyped_defs = false
disallow_any_unimported = false
disallow_any_expr = false
disallow_any_decorated = false
warn_unused_ignores = false
warn_return_any = false
ignore_missing_imports = true

# No constraints on optional
no_implicit_optional = false
strict_optional = false

# Show errors
show_error_codes = true