Files
cleveragents-core/pyproject.toml
T
HAL9000 8dde6c81ef feat(server): implement PostgreSQL storage backend for server mode
Add PostgreSQL support as the server-mode storage backend alongside
existing SQLite for local mode. Verify all ORM models are dialect-
agnostic, configure connection pooling for multi-user access, add
Docker Compose for local PG development, and wire database URL
selection based on deployment mode.

Changes:
- Add psycopg2-binary dependency to pyproject.toml
- Add server_mode, db_pool_size, db_max_overflow, db_pool_recycle
  settings to Settings with environment variable support
- Add resolve_database_url() and is_postgresql() to Settings for
  mode-aware database URL resolution
- Configure UnitOfWork engine creation with pool_size, max_overflow,
  pool_recycle, and pool_pre_ping for PostgreSQL connections
- Update MigrationRunner to handle both SQLite and PostgreSQL backends
- Add compare_type=True to Alembic env.py for dialect-aware migrations
- Add docker-compose.yml with PostgreSQL 16-alpine for local development
- Add Behave BDD feature (14 scenarios) covering settings, pool config,
  engine creation, ORM dialect compatibility, and migration runner
- Add Robot Framework integration tests (12 test cases) for the
  abstraction layer with requires_postgresql tag for live PG tests

Fixes:
- Restore require_confirmation parameter to UnitOfWork.__init__
- Add argument validation to UnitOfWork.__init__ (fail-fast)
- Add explicit PostgreSQL isolation_level (READ COMMITTED)
- Add dispose() method and context manager support to UnitOfWork
- Fix MigrationRunner.get_current_revision() to dispose engine
- Fix Settings.is_postgresql() to handle ValueError gracefully

ISSUES CLOSED: #878
2026-05-29 01:04:59 -04:00

246 lines
6.9 KiB
TOML

[build-system]
requires = ["hatchling>=1.21.0"]
build-backend = "hatchling.build"
[project]
name = "cleveragents"
version = "1.0.0"
description = "CleverAgents CLI and runtime toolkit"
readme = "README.md"
requires-python = ">=3.13"
license = {text = "MIT"}
authors = [
{name = "CleverThis Engineering", email = "engineering@cleverthis.com"},
]
keywords = ["cleveragents", "ai", "cli", "automation"]
classifiers = [
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.13",
]
dependencies = [
# CLI Framework (ADR-009)
"typer>=0.9.0",
"uvicorn>=0.30.1",
"watchdog>=4.0.0",
"faiss-cpu>=1.7.4", # Vector store backend
"rx>=3.2.0", # Reactive streams for routing
"dependency-injector>=4.41.0", # DI container
"pydantic>=2.7.0",
"pydantic-settings>=2.11.0",
"structlog>=24.4.0",
"langchain>=0.2.14",
"langchain-anthropic>=0.2.0",
"langchain-community>=0.2.14",
"langchain-openai>=0.2.0",
"langchain-google-genai>=0.2.0",
"jinja2>=3.1.0",
"alembic>=1.13.1",
"numpy>=2.1.0",
"python-ulid>=2.7.0", # ULID generation for plan/action IDs
"RestrictedPython>=7.0", # Secure sandbox for user-supplied code
"jsonschema>=4.20.0", # JSON Schema validation for tool inputs/outputs
"tomlkit>=0.13.0", # TOML writing with comment preservation for config CLI
"tenacity>=8.2.0", # Retry framework for service layer resilience
"aiohttp>=3.13.4", # CVE-2026-34515 mitigation: open redirect vulnerability
"pyyaml>=6.0.3", # Security: address known YAML parsing vulnerabilities
"a2a-sdk>=0.3.0,<1.0.0", # A2A Python SDK — required transport for local (stdio) and server (HTTP) modes (ADR-047); pinned <1.0.0 (removed legacy A2AClient)
]
[project.optional-dependencies]
server = [
"psycopg2-binary>=2.9.9", # PostgreSQL adapter for server-mode storage
]
tui = [
"textual>=1.0.0,<2.0.0",
]
dev = [
# Code formatting and linting
"ruff>=0.15.0,<0.16.0",
# Type checking
"pyright>=1.1.350",
"types-pyyaml>=6.0.0",
"types-aiofiles>=23.0.0",
# Testing
"behave==1.3.3",
"pytest>=8.0.0",
"pytest-asyncio>=0.23.0",
"pytest-cov>=4.1.0",
# Pre-commit hooks
"pre-commit>=3.6.0",
# Security scanning
"bandit[toml]>=1.7.5",
"semgrep>=1.60.0",
# Dead code detection
"vulture>=2.10",
# Complexity metrics
"radon>=6.0.1",
]
tests = [
"behave==1.3.3",
"slipcover>=1.0.17",
"asv>=0.6.5",
"robotframework>=7.3.2",
"robotframework-pabot>=4.0.0",
"faker>=20.0.0", # Dynamic test data generation
]
docs = [
"mkdocs>=1.6.1",
"mkdocs-material>=9.6.0",
"mkdocstrings[python]>=0.24.0",
"mkdocs-kroki-plugin>=1.2.0",
"mkdocs-gen-files>=0.5.0",
"mkdocs-literate-nav>=0.6.0",
"griffe-pydantic>=1.0.0",
"mkdocs-click>=0.8.0",
"ruff>=0.4.0",
]
[project.urls]
Homepage = "https://cleverthis.com/cleveragents"
Documentation = "https://docs.cleverthis.com/cleveragents"
Repository = "https://git.cleverthis.com/cleveragents/core"
Issues = "https://git.cleverthis.com/cleveragents/core/issues"
[project.scripts]
cleveragents = "cleveragents.cli:main"
agents = "cleveragents.cli:main"
[tool.hatch.build.targets.wheel]
packages = ["src/cleveragents"]
include = [
"src/cleveragents/py.typed",
"src/cleveragents/infrastructure/database/migrations/alembic.ini",
"src/cleveragents/infrastructure/database/migrations/script.py.mako",
"src/cleveragents/infrastructure/database/migrations/README",
]
[tool.ruff]
line-length = 88
target-version = "py313" # Target Python 3.13
src = ["src", "tests", "benchmarks"]
extend-exclude = ["docs/reference/contracts/stubs/*.py", "scripts/*.sh", "**/*.feature"]
[tool.ruff.lint]
select = ["E", "F", "W", "B", "UP", "I", "SIM", "RUF"]
ignore = []
[tool.ruff.lint.per-file-ignores]
"__init__.py" = ["F401"]
# Behave step files: F811 = redefined step_impl (Behave pattern), E501 = long step decorator strings
# B010 = setattr with constant attribute name is intentional in immutability tests (exercises frozen model enforcement)
# I001 = import sorting (Behave step files have specific import patterns)
"features/steps/*.py" = ["F811", "E501", "B010", "I001"]
"features/mocks/*.py" = ["E501"]
"features/environment.py" = ["E501"]
# retry_patterns.py re-exports symbols from retry_service_patterns at module bottom
"src/cleveragents/core/retry_patterns.py" = ["E402"]
[tool.ruff.format]
# Use double quotes for strings
quote-style = "double"
# Indent with 4 spaces
indent-style = "space"
# Unix line endings
line-ending = "auto"
[tool.pyright]
include = ["src"]
exclude = ["**/.nox", "**/__pycache__", "**/site-packages", "src/cleveragents/discovery"]
pythonVersion = "3.13" # Target Python 3.13
typeCheckingMode = "strict"
strictListInference = true
strictDictionaryInference = true
strictSetInference = true
reportMissingImports = true
reportMissingTypeStubs = false
reportMissingTypeArgument = true
reportIncompatibleMethodOverride = true
reportIncompatibleVariableOverride = true
reportUnusedImport = true
reportUnusedClass = true
reportUnusedFunction = true
reportUnusedVariable = true
reportDuplicateImport = true
reportOptionalMemberAccess = true
reportOptionalCall = true
reportOptionalIterable = true
reportOptionalContextManager = true
reportOptionalOperand = true
reportTypedDictNotRequiredAccess = true
reportUnnecessaryIsInstance = true
reportUnnecessaryCast = true
reportUnnecessaryComparison = true
reportImplicitStringConcatenation = false
reportUnusedCallResult = false
reportUnknownMemberType = false
reportUnknownVariableType = false
reportUnknownParameterType = false
[tool.coverage]
# Coverage configuration
[tool.coverage.run]
source = ["src", "scripts"]
branch = true
parallel = false
omit = [
"*/tests/*",
"*/test_*",
"features/*",
"*/features/*",
"*/__pycache__/*",
"*/site-packages/*",
"*/dependency_injector/*",
"*/venv/*",
"*/.venv/*",
"*/.nox/*",
"src/cleveragents/discovery/*",
"src/cleveragents/tui/materializer.py",
]
data_file = "build/.coverage"
[tool.coverage.html]
directory = "build/htmlcov"
[tool.coverage.xml]
output = "build/coverage.xml"
[tool.bandit]
targets = ["src/cleveragents"]
exclude_dirs = [
"tests",
"features",
".nox",
"build",
"dist",
"docs",
"src/cleveragents/discovery",
]
# Severity level: LOW, MEDIUM, HIGH
severity = "MEDIUM"
# Confidence level: LOW, MEDIUM, HIGH
confidence = "MEDIUM"
# Skip specific tests if needed
skips = []
[tool.vulture]
min_confidence = 80
paths = ["src/cleveragents"]
exclude = ["src/cleveragents/discovery"]
[tool.hatch]
# Hatch build configuration
[tool.commitizen]
name = "cz_conventional_commits"
tag_format = "$version"
version_scheme = "pep440"
version_provider = "pep621"
update_changelog_on_bump = true
major_version_zero = true