[project] name = "cai-framework" version = "0.4.0" description = "Cybersecurity AI Framework" readme = "README.md" requires-python = ">=3.9" license = {text = "Dual-licensed MIT and Proprietary"} authors = [{ name = "Alias Robotics", email = "research@aliasrobotics.com" }] dependencies = [ # logging and visualization "folium>=0.15.0, <1", "matplotlib>=3.0, <4", "numpy>=1.21, <3", "pandas>=1.3, <3", # core cai "openai==1.75.0", "pydantic>=2.10, <3", "griffe>=1.5.6, <2", "typing-extensions>=4.12.2, <5", "requests>=2.0, <3", "types-requests>=2.0, <3", "openinference-instrumentation-openai>=0.1.22", "wasabi>=1.1.3", "rich>=13.9.4", "prompt_toolkit>=3.0.39", "dotenv>=0.9.9", "litellm>=1.63.7", "mako>=1.3.8", "mcp; python_version >= '3.10'", "mkdocs>=1.6.0", "mkdocs-material>=9.6.0", "paramiko>=3.5.1", "dnspython", "flask", "networkx", "PyPDF2", ] classifiers = [ "Typing :: Typed", "Intended Audience :: Developers", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Intended Audience :: Developers", "Operating System :: OS Independent", "Topic :: Software Development :: Libraries :: Python Modules", "License :: OSI Approved :: MIT License", ] [project.urls] Homepage = "https://github.com/openai/openai-agents-python" Repository = "https://github.com/openai/openai-agents-python" [project.optional-dependencies] voice = ["numpy>=2.2.0, <3; python_version>='3.10'", "websockets>=15.0, <16"] viz = ["graphviz>=0.17"] [dependency-groups] dev = [ "mypy", "ruff==0.9.2", "pytest", "pytest-asyncio", "pytest-mock>=3.14.0", "rich", "mkdocs>=1.6.0", "mkdocs-material>=9.6.0", "mkdocstrings[python]>=0.28.0", "coverage>=7.6.12", "playwright==1.50.0", "inline-snapshot>=0.20.7", "pynput", "types-pynput", "sounddevice", "textual", "websockets", "litellm", "prisma", "graphviz", ] [tool.uv.workspace] members = ["agents"] [tool.uv.sources] agents = { workspace = true } [build-system] requires = ["hatchling"] build-backend = "hatchling.build" [tool.hatch.build] exclude = [ ".trunk/", ".git/", ".vscode/", ".devcontainer/", ".mypy_cache/", ".pytest_cache/", ".ruff_cache/", "venv/", ".venv/", "dist/", "build/", "*.egg-info/", "workspaces/", "benchmarks/", "logs/", "site/", ".cai/", "nohup.out" ] [tool.hatch.build.targets.wheel] packages = ["src/cai", "tools"] exclude = [ ".trunk/", ".git/", ".vscode/", ".devcontainer/", ".mypy_cache/", ".pytest_cache/", ".ruff_cache/", "venv/", ".venv/", "dist/", "build/", "*.egg-info/", "workspaces/", "benchmarks/", "logs/", "site/", ".cai/", "nohup.out" ] [tool.hatch.build.targets.wheel.sources] "src" = "" "tools" = "tools" [tool.ruff] line-length = 100 target-version = "py39" [tool.ruff.lint] select = [ "E", # pycodestyle errors "W", # pycodestyle warnings "F", # pyflakes "I", # isort "B", # flake8-bugbear "C4", # flake8-comprehensions "UP", # pyupgrade ] isort = { combine-as-imports = true, known-first-party = ["agents"] } [tool.ruff.lint.pydocstyle] convention = "google" [tool.ruff.lint.per-file-ignores] "examples/**/*.py" = ["E501"] [tool.mypy] strict = true disallow_incomplete_defs = false disallow_untyped_defs = false disallow_untyped_calls = false [[tool.mypy.overrides]] module = "sounddevice.*" ignore_missing_imports = true [tool.coverage.run] source = ["tests", "src/cai/sdk/agents"] [tool.coverage.report] show_missing = true sort = "-Cover" exclude_also = [ # This is only executed while typechecking "if TYPE_CHECKING:", "@abc.abstractmethod", "raise NotImplementedError", "logger.debug", ] [tool.pytest.ini_options] asyncio_mode = "auto" asyncio_default_fixture_loop_scope = "session" filterwarnings = [ # This is a warning that is expected to happen: we have an async filter that raises an exception "ignore:coroutine 'test_async_input_filter_fails..invalid_input_filter' was never awaited:RuntimeWarning", ] markers = [ "allow_call_model_methods: mark test as allowing calls to real model implementations", ] [tool.inline-snapshot] format-command = "ruff format --stdin-filename {filename}" [project.scripts] cai = "cai.cli:main" cai-replay = "tools.replay:main" cai-asciinema = "tools.asciinema:main" cai-gif = "tools.gif:main"