8dde6c81ef
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
246 lines
6.9 KiB
TOML
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
|