Files
composiohq__composio/python/noxfile.py
T
Alberto Schiabel 503b50ab02 chore(deps): refresh SDK, Python, and CI dependencies (#3955)
This PR:

- splits https://github.com/ComposioHQ/composio/pull/3953 in two: this
PR carries every dependency and GitHub Actions bump **except** the docs
site, which follows in a stacked PR
- consolidates and supersedes Dependabot PRs #3915, #3916, and #3934
through #3942
- adopts TypeScript 7.0.2 for primary compilation while retaining the
`@typescript/typescript6` API lane that TypeScript-ESLint still
requires, following the upstream side-by-side guidance
- refreshes Python core and provider dependencies, lockfiles, and the
Ruff 0.16 lint configuration
- updates every GitHub Action with a verified newer official release,
including majors, while retaining immutable commit SHA pins and
migrating setup-uv cache pruning
- deletes four per-package `eslint.config.mjs` shims: under ESLint 10
the default per-file config lookup re-anchors the root config's globs
into each package, so `pnpm lint` stayed green while the CLI's
try/catch, `process.env` and node-builtin bans went unenforced
- bounds and documents the new `brace-expansion` and `@hono/node-server`
security overrides, raising the `@hono/node-server` floor to 2.0.10 to
clear GHSA-9mqv-5hh9-4cgg
- preserves intentional compatibility fixtures and lanes for AI SDK 6,
Zod 3, TypeScript 5.8, Mastra AI SDK 5, and Python provider constraints

## Context

The docs site is a separate Bun workspace with its own `bun.lock` and is
not a pnpm workspace member, so the two halves share no lockfile and no
build. Splitting them keeps the Fumadocs 11 migration (a breaking API
change with real refactoring) reviewable on its own, independently of
the mechanical version bumps here.

The `brace-expansion` override deliberately spans majors:
GHSA-mh99-v99m-4gvg (HIGH) is published as a single `<=5.0.7` range with
no 1.x or 2.x backport, so narrowing it to the 5.x line puts
`brace-expansion` 2.1.2 back under `core>minimatch>brace-expansion` and
`pnpm audit --prod --audit-level=high` exits 1. Verified both ways; the
trade-off it buys is recorded inline in `pnpm-workspace.yaml`.

Verified on this branch standalone: `pnpm install --frozen-lockfile`,
`pnpm lint`, `pnpm typecheck`, `pnpm build:packages`, `pnpm test` (963
tests, 26/26 tasks), and `pnpm audit --prod --audit-level=high`.
2026-07-27 17:57:29 +05:30

176 lines
5.5 KiB
Python

import nox
from nox.sessions import Session
nox.options.default_venv_backend = "uv"
# Modules for both ruff and mypy
modules_for_mypy = [
"composio/",
"providers/",
"tests/",
"scripts/",
]
# Modules for ruff only (includes examples)
modules_for_ruff = [
"composio/",
"providers/",
"tests/",
"examples/",
"scripts/",
]
# Type stubs and provider libraries installed solely so mypy can resolve
# imports across `providers/` and `tests/`. These can't live in the locked
# `dev` dependency group: the provider libraries (crewai, langchain,
# llama-index, ...) would drag conflicting transitive deps into the root
# resolution. Shared test/lint tooling (ruff, pytest, fastapi, semver,
# langchain-openai) is sourced from the `dev` group in pyproject.toml via
# `--group dev`, so every package is declared in exactly one place.
type_stubs = [
"types-requests==2.33.0.20260712",
"types-protobuf==7.34.1.20260518",
"anthropic==0.120.0",
# Keep this aligned with the CrewAI provider dependency metadata.
"crewai==1.15.7",
"langchain==1.3.14",
"langgraph==1.2.9",
"llama-index==0.14.23",
"openai-agents==0.18.3",
"google-cloud-aiplatform==1.162.0",
]
mypy = "mypy==2.3.0"
ruff = [
"ruff",
"--config",
"config/ruff.toml",
]
@nox.session
def fmt(session: Session):
"""Format code"""
session.install("--group", "dev")
session.run("ruff", "check", "--select", "I", "--fix", *modules_for_ruff)
session.run("ruff", "format", *modules_for_ruff)
@nox.session
def chk(session: Session):
"""Check for linter and type issues"""
session.install(".", "--group", "dev", mypy, *type_stubs)
session.run(*ruff, "check", *modules_for_ruff)
for module in modules_for_mypy:
session.run("mypy", "--config-file", "config/mypy.ini", module)
@nox.session
def fix(session: Session):
"""Fix linter issues"""
session.install("--group", "dev")
session.run(*ruff, "check", "--fix", *modules_for_ruff)
@nox.session
def tst(session: Session):
"""Run the Python unit test suite."""
session.install(".", "--group", "dev")
session.install("./providers/langchain")
session.install("./providers/autogen")
test_paths = session.posargs or ["tests/"]
session.run("pytest", *test_paths, "-v", "--tb=short")
@nox.session
def snt(session: Session):
"""Run fast sanity tests for imports and SDK initialization."""
session.install(".", "--group", "dev")
test_paths = session.posargs or ["tests/test_imports.py", "tests/test_sdk.py"]
session.run("pytest", *test_paths, "-v", "--tb=short")
@nox.session
def type_inference(session: Session):
"""Type check provider return type inference tests.
This session verifies that mypy correctly infers provider-specific return
types from `Composio.tools.get()` when using @overload signatures.
Unlike the `chk` session, this installs all provider packages so mypy can
resolve the provider types and verify the type inference works correctly.
"""
# Install core SDK, shared dev tooling, and mypy
session.install(".", "--group", "dev", mypy, *type_stubs)
# Install all provider packages for type resolution
session.install(
"./providers/anthropic",
"./providers/autogen",
"./providers/claude_agent_sdk",
"./providers/crewai",
"./providers/gemini",
"./providers/google",
"./providers/google_adk",
"./providers/langchain",
"./providers/langgraph",
"./providers/llamaindex",
"./providers/openai",
"./providers/openai_agents",
)
# Run mypy on type inference test files
# Note: explicitly listed files are checked even if they match the exclude pattern in `mypy.ini`
session.run(
"mypy",
"--config-file",
"config/mypy.ini",
"tests/test_type_inference.py",
"tests/test_type_inference_anthropic.py",
"tests/test_type_inference_autogen.py",
"tests/test_type_inference_claude_agent_sdk.py",
"tests/test_type_inference_crewai.py",
"tests/test_type_inference_gemini.py",
"tests/test_type_inference_google.py",
"tests/test_type_inference_google_adk.py",
"tests/test_type_inference_langchain.py",
"tests/test_type_inference_langgraph.py",
"tests/test_type_inference_llamaindex.py",
"tests/test_type_inference_openai_agents.py",
)
# Modules scanned for dead code (source only, no tests/examples/scripts)
modules_for_vulture = [
"composio/",
"providers/",
]
@nox.session(name="dead_code")
def dead_code(session: Session):
"""Report likely-dead code (unused functions, classes, variables).
Report-only: vulture exits 1 when it finds candidates, but we do not fail
the session on that so it never blocks CI on false positives. Vet the
output by hand; suppress confirmed false positives by adding the symbol to
``config/vulture_allowlist.py``. Ruff already covers unused imports (F401)
and unused locals (F841) in the `chk` session; vulture adds cross-module
unused functions/classes that ruff cannot see.
"""
session.install("vulture>=2.14")
session.run(
"vulture",
*modules_for_vulture,
"config/vulture_allowlist.py",
"--min-confidence",
"80",
"--exclude",
"*/build/*,*/dist/*,*/.venv/*,*/.nox/*,*/__pycache__/*",
# vulture exit codes: 0 = clean, 3 = candidates found. Report-only, so
# neither should fail the session. (1/2 are real usage/parse errors.)
success_codes=[0, 3],
)