[build-system] build-backend = "setuptools.build_meta" requires = ["setuptools>=64", "setuptools_scm>=8"] [project] authors = [ {email = "hello@futurehouse.org", name = "FutureHouse technical staff"}, ] # Full list: https://pypi.python.org/pypi?%3Aaction=list_classifiers classifiers = [ "Operating System :: OS Independent", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python", ] dependencies = [ "aiofiles", "dm-tree", "fhaviary>=0.8", # For from_task "httpx", "litellm>=1.40.15", # For LITELLM_LOG addition "networkx[default]~=3.4", # Pin for pydot fix "numpy>=1.20", # For numpy.typing "openai>=1", "pydantic~=2.0", "tenacity", "tiktoken", "tqdm", "typing-extensions; python_version <= '3.11'", # for typing.override "usearch>=2.13", # For py.typed ] description = "Agent framework for constructing language model agents and training on constructive tasks." dynamic = ["version"] license = {file = "LICENSE"} name = "ldp" readme = "README.md" requires-python = ">=3.11" [project.optional-dependencies] monitor = [ "wandb", ] nn = [ "torch>=2.2", ] rich = [ "rich", "tqdm>=4.56", # When tqdm.rich was created ] server = [ "fastapi>=0.109", # For Python 3.12 support ] typing = [ "types-aiofiles", "types-tqdm", ] visualization = [ "pydot>=3.0.1", # Matching networkx[extra]==3.4 version, SEE: https://github.com/networkx/networkx/blob/networkx-3.4/pyproject.toml#L92C6-L92C18 ] [project.urls] issues = "https://github.com/Future-House/ldp/issues" repository = "https://github.com/Future-House/ldp" [tool.black] preview = true [tool.codeflash] disable-imports-sorting = true disable-telemetry = true formatter-cmds = ["ruff check --exit-zero --fix $file", "ruff format $file"] module-root = "ldp" test-framework = "pytest" tests-root = "tests" [tool.codespell] check-filenames = true check-hidden = true ignore-words-list = "astroid,ser" skip = "tests/cassettes/*" [tool.mypy] # Type-checks the interior of functions without type annotations. check_untyped_defs = true # Allows enabling one or multiple error codes globally. Note: This option will # override disabled error codes from the disable_error_code option. enable_error_code = [ "ignore-without-code", "redundant-cast", "redundant-expr", "redundant-self", "truthy-bool", "truthy-iterable", "unimported-reveal", "unreachable", "unused-ignore", ] # Shows a short summary line after error messages. error_summary = false # A regular expression that matches file names, directory names and paths which mypy # should ignore while recursively discovering files to check. Use forward slashes (/) as # directory separators on all platforms. exclude = [ "^\\.?venv", # SEE: https://regex101.com/r/0rp5Br/1 ] # This flag tells mypy that top-level packages will be based in either the current # directory, or a member of the MYPYPATH environment variable or mypy_path config # option. This option is only useful in the absence of __init__.py. See Mapping file # paths to modules for details. explicit_package_bases = true # Specifies the OS platform for the target program, for example darwin or win32 # (meaning OS X or Windows, respectively). The default is the current platform # as revealed by Python’s sys.platform variable. platform = "linux" # Comma-separated list of mypy plugins. plugins = ["pydantic.mypy"] # Use visually nicer output in error messages: use soft word wrap, show source # code snippets, and show error location markers. pretty = true # Shows column numbers in error messages. show_column_numbers = true # Shows error codes in error messages. # SEE: https://mypy.readthedocs.io/en/stable/error_codes.html#error-codes show_error_codes = true # Prefixes each error with the relevant context. show_error_context = true # Warns about casting an expression to its inferred type. warn_redundant_casts = true # Shows a warning when encountering any code inferred to be unreachable or # redundant after performing type analysis. warn_unreachable = true # Warns about per-module sections in the config file that do not match any # files processed when invoking mypy. warn_unused_configs = true # Warns about unneeded `# type: ignore` comments. warn_unused_ignores = true [[tool.mypy.overrides]] # Suppresses error messages about imports that cannot be resolved. ignore_missing_imports = true # Per-module configuration options module = [ "networkx", # SEE: https://github.com/networkx/networkx/issues/3988 "pydot", "tree", # SEE: https://github.com/google-deepmind/tree/issues/84 ] [tool.pylint] [tool.pylint.design] # Maximum number of attributes for a class (see R0902). max-attributes = 12 [tool.pylint.format] # Maximum number of characters on a single line. max-line-length = 88 # Match ruff line-length [tool.pylint.main] # Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the # number of processors available to use, and will cap the count on Windows to # avoid hangs. jobs = 0 # List of plugins (as comma separated values of python module names) to load, # usually to register additional checkers. load-plugins = [ "pylint_pydantic", ] [tool.pylint.messages_control] # Disable the message, report, category or checker with the given id(s). disable = [ "arguments-differ", # Ops intentionally differ arguments "attribute-defined-outside-init", # Disagrees with reset pattern "bare-except", # Rely on ruff E722 for this "broad-exception-caught", # Don't care to enforce this "broad-exception-raised", # Rely on ruff TRY002 for this "cyclic-import", # Let Python blow up "expression-not-assigned", # Rely on mypy func-returns-value for this "fixme", # codetags are useful "function-redefined", # Rely on mypy no-redef for this "import-outside-toplevel", # Rely on ruff PLC0415 for this "invalid-name", # Don't care to enforce this "line-too-long", # Rely on ruff E501 for this "logging-fstring-interpolation", # f-strings are convenient "logging-too-many-args", # Rely on ruff PLE1205 for this "missing-docstring", # Let docformatter and ruff take care of docstrings "missing-final-newline", # Rely on ruff W292 for this "no-else-return", # Rely on ruff RET506 for this "no-member", # Buggy, SEE: https://github.com/pylint-dev/pylint/issues/8138 "not-callable", # Don't care to enforce this "protected-access", # Don't care to enforce this "raise-missing-from", # Rely on ruff B904 for this "redefined-builtin", # Rely on ruff A002 for this "super-init-not-called", # Don't care to enforce this "too-few-public-methods", # Don't care to enforce this "too-many-ancestors", # Don't care to enforce this "too-many-arguments", # Don't care to enforce this "too-many-branches", # Rely on ruff PLR0912 for this "too-many-instance-attributes", # Don't care to enforce this "too-many-lines", # Don't care to enforce this "too-many-locals", # Rely on ruff PLR0914 for this "too-many-positional-arguments", # Don't care to enforce this "too-many-return-statements", # Rely on ruff PLR0911 for this "too-many-statements", # Rely on ruff PLR0915 for this "ungrouped-imports", # Rely on ruff I001 for this "unidiomatic-typecheck", # Rely on ruff E721 for this "unreachable", # Rely on mypy unreachable for this "unspecified-encoding", # Don't care to enforce this "unsubscriptable-object", # Buggy, SEE: https://github.com/PyCQA/pylint/issues/3637 "unsupported-membership-test", # Buggy, SEE: https://github.com/pylint-dev/pylint/issues/3045 "unused-argument", # Rely on ruff ARG002 for this "unused-import", # Rely on ruff F401 for this "unused-variable", # Rely on ruff F841 for this "wrong-import-order", # Rely on ruff I001 for this "wrong-import-position", # Rely on ruff E402 for this ] # Enable the message, report, category or checker with the given id(s). enable = [ "useless-suppression", # Print unused `pylint: disable` comments ] [tool.pylint.reports] # Set true to activate the evaluation score. score = false [tool.pylint.similarities] # Minimum lines number of a similarity. min-similarity-lines = 12 [tool.pytest.ini_options] # Add the specified OPTS to the set of command line arguments as if they had been # specified by the user. addopts = "--doctest-modules" # Sets a list of filters and actions that should be taken for matched warnings. # By default all warnings emitted during the test session will be displayed in # a summary at the end of the test session. filterwarnings = [ "ignore:Support for class-based `config` is deprecated, use ConfigDict instead", # SEE: https://github.com/BerriAI/litellm/issues/5648 "ignore:The `dict` method is deprecated; use `model_dump` instead", # SEE: https://github.com/BerriAI/litellm/issues/5987 "ignore:Use 'content=<...>' to upload raw bytes/text content:DeprecationWarning", # SEE: https://github.com/BerriAI/litellm/issues/5986 'ignore:open_text is deprecated. Use files\(\) instead:DeprecationWarning', # SEE: https://github.com/BerriAI/litellm/issues/5647 ] # List of directories that should be searched for tests when no specific directories, # files or test ids are given in the command line when executing pytest from the rootdir # directory. File system paths may use shell-style wildcards, including the recursive ** # pattern. testpaths = ["src", "tests"] [tool.refurb] enable_all = true ignore = [ "FURB101", # FURB101, FURB103, FURB141, FURB144, FURB146, FURB147, FURB150, FURB155: no need for pathlib "FURB103", "FURB118", # We often use inspect.signature in FxnOp. In 3.11, this doesn't work on operator.itemgetter. "FURB141", "FURB144", "FURB146", "FURB147", "FURB150", "FURB155", ] [tool.ruff] # Line length to use when enforcing long-lines violations (like `E501`). line-length = 88 # The minimum Python version to target, e.g., when considering automatic code # upgrades, like rewriting type annotations. Ruff will not propose changes # using features that are not available in the given version. target-version = "py311" # Enable application of unsafe fixes. unsafe-fixes = true [tool.ruff.format] # Enable reformatting of code snippets in docstrings. docstring-code-format = true # Enable preview style formatting. preview = true [tool.ruff.lint] explicit-preview-rules = true extend-select = [ "C420", "DOC202", "DOC403", "FURB110", "FURB113", "FURB116", "FURB131", "FURB132", "FURB140", "FURB142", "FURB145", "FURB148", "FURB152", "FURB154", "FURB157", "FURB164", "FURB166", "FURB171", "FURB180", "FURB192", "PLR6104", "PLR6201", "PLW0108", "RUF022", ] external = [ "FURB", # refurb ] # List of rule codes that are unsupported by Ruff, but should be preserved when # (e.g.) validating # noqa directives. Useful for retaining # noqa directives # that cover plugins not yet implemented by Ruff. ignore = [ "ANN", # Don't care to enforce typing "ARG002", # Thrown all the time when we are subclassing "ARG003", # Thrown all the time when we are subclassing "ASYNC109", # Buggy, SEE: https://github.com/astral-sh/ruff/issues/12353 "ASYNC2", # It's ok to mix async and sync ops (like opening a file) "BLE001", # Don't care to enforce blind exception catching "COM812", # Trailing comma with black leads to wasting lines "D100", # D100, D101, D102, D103, D104, D105, D106, D107: don't always need docstrings "D101", "D102", "D103", "D104", "D105", "D106", "D107", "D203", # Keep docstring next to the class definition (covered by D211) "D212", # Summary should be on second line (opposite of D213) "D402", # It's nice to reuse the method name "D406", # Google style requires ":" at end "D407", # We aren't using numpy style "D413", # Blank line after last section. -> No blank line "DTZ", # Don't care to have timezone safety "EM", # Overly pedantic "ERA001", # Don't care to prevent commented code "FBT001", # FBT001, FBT002: overly pedantic "FBT002", "FIX", # Don't care to prevent TODO, FIXME, etc. "FLY002", # Can be less readable "G004", # f-strings are convenient "INP001", # Can use namespace packages "ISC001", # For ruff format compatibility "N803", # Allow matching math formula names/conventions "N806", # Allow matching math formula names/conventions "PLC0415", # Don't care to prevent imports outside of top-level "PLR0912", # Allow us to have lots of branches "PLR0913", "PLW2901", # Allow modifying loop variables "PTH", # Overly pedantic "S101", # Don't care to prevent asserts "S105", # Duplicates Yelp/detect-secrets in pre-commit "S311", # Ok to use python random "SLF001", # Overly pedantic "T201", # Overly pedantic "TCH001", # TCH001, TCH002, TCH003: don't care to enforce type checking blocks "TCH002", "TCH003", "TD002", # Don't care for TODO author "TD003", # Don't care for TODO links "TRY003", # Overly pedantic ] preview = true select = ["ALL"] unfixable = [ "B007", # While debugging, unused loop variables can be useful "B905", # Default fix is zip(strict=False), but that can hide bugs "ERA001", # While debugging, temporarily commenting code can be useful "F401", # While debugging, unused imports can be useful "F841", # While debugging, unused locals can be useful ] [tool.ruff.lint.flake8-annotations] mypy-init-return = true [tool.ruff.lint.per-file-ignores] "**/tests/*.py" = [ "E501", # Tests can have long strings "F841", # Tests can have unused locals "N802", # Tests function names can match class names "PLR2004", # Tests can have magic values ] [tool.ruff.lint.pycodestyle] # The maximum line length to allow for line-length violations within # documentation (W505), including standalone comments. max-doc-length = 120 # Match line-length # The maximum line length to allow for line-too-long violations. By default, # this is set to the value of the line-length option. max-line-length = 120 [tool.ruff.lint.pydocstyle] # Whether to use Google-style or NumPy-style conventions or the PEP257 # defaults when analyzing docstring sections. convention = "google" [tool.setuptools.packages.find] include = ["ldp*"] [tool.setuptools_scm] version_file = "ldp/version.py" [tool.tomlsort] all = true in_place = true spaces_before_inline_comment = 2 # Match Python PEP 8 spaces_indent_inline_array = 4 # Match Python PEP 8 trailing_comma_inline_array = true [tool.uv] dev-dependencies = [ "codeflash", "fhaviary[xml]", "ipython>=8", # Pin to keep recent "ldp[monitor,nn,rich,server,typing,visualization]", "litellm!=1.49.4,!=1.49.5,!=1.49.6", # For https://github.com/BerriAI/litellm/issues/6216 "mypy>=1.8", # Pin for mutable-override "openai<1.47", # Pin for https://github.com/BerriAI/litellm/issues/5854 "pre-commit>=3.4", # Pin to keep recent "pydantic~=2.9", # Pydantic 2.9 changed JSON schema exports 'allOf', so ensure tests match "pylint-pydantic", "pylint>=3.2", # Pin to keep recent "pytest-asyncio", "pytest-mock", "pytest-recording", "pytest-rerunfailures", "pytest-subtests", "pytest-sugar", "pytest-timer[colorama]", "pytest-xdist", "pytest>=8", # Pin to keep recent "refurb>=2", # Pin to keep recent, "sphinx" ]