mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-08-10 08:21:54 +00:00
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Check Documentation Broken Links / Check broken links (push) Has been cancelled
Vulnerability Scan / Detect changes (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Build uv cache / build-cache (3.10) (push) Has been cancelled
Build uv cache / build-cache (3.11) (push) Has been cancelled
Build uv cache / build-cache (3.12) (push) Has been cancelled
Build uv cache / build-cache (3.13) (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
* feat(telemetry): split runtime context from coding agent, add project id The coding-agent field answered two questions at once. A run with no TTY reported "non_interactive" and an editor's integrated terminal reported "vscode_terminal", both in the same field as the assistant name, so a run that never had an assistant to detect was indistinguishable from one whose assistant we failed to recognize. Together those two values were the majority of what the field reported. detect_coding_agent now answers only which assistant, returning "unknown" when no marker matches. detect_runtime_context answers where the process runs: ci, serverless, hosted_ide, notebook, container, the editor terminals, and the interactive/non_interactive fallback. Both ride on every span, so an assistant running inside CI reports both rather than one masking the other. The runtime markers are published platform contracts - CI providers, container and serverless runtimes, hosted IDEs - so unlike the assistant table they need no per-tool verification step. Presence is checked; no value is read. The assistant table is unchanged: its entries still require a confirmed, session-scoped variable, and the existing guard test still enforces that. Spans also carry project_id when the project declares one. It is read through the read-only accessor, since minting an id belongs to the CLI commands a user invoked rather than to a library call during execution, and it is omitted entirely for projects without one. The attributes are computed once per process and memoized, so the project file is not re-read for each provider. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * docs: document execution environment telemetry attributes Adds the execution-environment row to the data table in en, ar, ko and pt-BR. Covers the assistant and runtime fields this branch splits apart and the project id, and states that detection reads only whether known environment variables are set. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(telemetry): detect runtime markers by presence, split paas from serverless Three findings from the CodeRabbit, code-quality and Cursor reviews. The runtime loop tested truthiness while constants.py documented presence, so a platform exporting a bare CI= fell through to the TTY fallback and was mislabelled as an ordinary local run. Presence is now what it says. The assistant markers keep truthiness deliberately: there an empty value means the tool set a placeholder rather than claiming the session. DYNO and WEBSITE_INSTANCE_ID marked Heroku dynos and Azure App Service instances as serverless, and since serverless is checked first they could never reach the container label. They move to a paas context, which is what they are: long-lived containers rather than per-invocation functions. AWS_EXECUTION_ENV is dropped entirely - it is set on ECS and EC2 as well as Lambda, and AWS_LAMBDA_FUNCTION_NAME already covers Lambda without the collision. The container probe no longer wraps os.path.exists in a try/except. os.path.exists handles OSError internally and returns False, so the handler guarded a condition that cannot occur and only hid the intent. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * feat(telemetry): widen assistant detection from published marker sets The table previously covered three assistants because the rest were unverified. They are documented after all: vercel/detect-agent publishes a machine-readable detection matrix (agents.json), corroborated by the proposal in agentsmd/agents.md#136 and by microsoft/vscode#311734. Adds cline, gemini_cli, augment, opencode, antigravity and junie, plus CLAUDE_CODE alongside CLAUDECODE. Gemini's marker is confirmed by its own docs, which state that run_shell_command sets GEMINI_CLI=1 in the subprocess environment. Rule 2 excluded several entries those sources list. Goose's GOOSE_PROVIDER and Copilot's COPILOT_MODEL and COPILOT_GITHUB_TOKEN are user configuration, and a committed .env carrying one would relabel every ordinary run - the AIDER_MODEL trap the guard test already pins, now parametrized over all four. Replit's REPL_ID names a hosted environment rather than an assistant, so it stays a runtime context. Copilot sets no session marker at all today; that is an open request upstream. The new assistants are ordered ahead of Cursor, since CURSOR_* is set for every integrated terminal and would otherwise mask anything spawned inside it - the same ordering Codex already needed. Also adds the proposed cross-vendor AI_AGENT marker as a last resort, reported as "other". It establishes that an assistant is present without naming one, and its value is an arbitrary vendor string, so the value is never read. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(deps): raise gitpython and pypdf floors for new advisories gitpython 3.1.57 carries GHSA-9rj7-rf2p-w77r, GHSA-4gmw-gg2m-w46p, GHSA-hh9p-6wh2-4mfc, GHSA-wvpp-8hx9-p66j and GHSA-jm78-9fvv-mhgr: further unguarded git option forwarding in Repo.init, read-tree and git-config, plus arbitrary file read via --pathspec-from-file. Fixed in 3.1.58. pypdf 6.14.2 carries GHSA-fwg2-594c-jp42 and GHSA-fp3f-mc75-235c, unbounded runtime and memory on large content and /ToUnicode streams. Fixed in 6.15.0. Both floors were already pinned, so only the versions move. Their exclude-newer-package cutoffs had to move with them - 3.1.58 landed 2026-08-04 and 6.15.0 on 2026-08-06, both past the existing dates, so the resolver could not have seen either release. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(telemetry): share assistant precedence with the env-context path Four findings from the Cursor and CodeRabbit reviews, three of them the same root cause. get_env_context restated the precedence the shared table already defines, so every marker added for telemetry was invisible to it: a session exposing only CLAUDE_CODE reported claude_code on spans while emitting DefaultEnvEvent, and an assistant running inside a Cursor terminal reported that assistant on spans while emitting CursorEnvEvent. It now walks CODING_AGENT_ENV_MARKERS and maps the three assistants that have an event class of their own, defaulting the rest to DefaultEnvEvent. A test now asserts the two paths agree for every marker in the table, so they cannot drift again. The generic AI_AGENT marker was documented as presence-only but ran through the truthiness loop with everything else, so an empty value fell through to unknown. It moves out of the table and is checked by presence after it, which also keeps the named markers' truthiness intact. Azure Functions run on the App Service host and inherit WEBSITE_INSTANCE_ID, so moving that marker to paas would have relabelled them. The FUNCTIONS_* markers are checked first to keep them serverless. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(telemetry): stop export assertions depending on test order test_all_common_attributes_land_on_exported_spans failed in CI with an IndexError on an empty span list, and only in one shard: the suite runs with OTEL_SDK_DISABLED set, so TracerProvider hands out no-op tracers and an export-based assertion sees zero spans rather than a wrong attribute. It passed only when it happened to run after a test whose fixture flips the variable, which random ordering decides. Adds an otel_enabled fixture that sets the variable for the four tests asserting on exported spans. Three of them predate this branch and had the same latent dependency - they are fixed here because the new test made the ordering hit reachable, and leaving them would keep the required check red. Verified by running every test in the file individually, all of which previously exposed the dependency, and the telemetry suite three times under random ordering. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
280 lines
12 KiB
TOML
280 lines
12 KiB
TOML
name = "crewai-workspace"
|
|
description = "Cutting-edge framework for orchestrating role-playing, autonomous AI agents. By fostering collaborative intelligence, CrewAI empowers agents to work together seamlessly, tackling complex tasks."
|
|
readme = "README.md"
|
|
requires-python = ">=3.10,<3.14"
|
|
authors = [
|
|
{ name = "Joao Moura", email = "joao@crewai.com" }
|
|
]
|
|
|
|
[dependency-groups]
|
|
dev = [
|
|
"ruff==0.15.1",
|
|
"mypy==1.19.1",
|
|
"pre-commit==4.5.1",
|
|
"bandit==1.9.2",
|
|
"pytest==9.0.3",
|
|
"pytest-asyncio==1.3.0",
|
|
"pytest-subprocess==1.5.3",
|
|
"vcrpy==8.2.1", # pinned, lower versions break pytest-recording
|
|
"pytest-recording==0.13.4",
|
|
"pytest-randomly==4.0.1",
|
|
"pytest-timeout==2.4.0",
|
|
"pytest-xdist==3.8.0",
|
|
"pytest-split==0.11.0",
|
|
"types-requests~=2.31.0.6",
|
|
"types-pyyaml==6.0.*",
|
|
"types-regex==2026.1.15.*",
|
|
"types-appdirs==1.4.*",
|
|
"boto3-stubs[bedrock-runtime]==1.42.40",
|
|
"types-psycopg2==2.9.21.20251012",
|
|
"types-pymysql==1.1.0.20250916",
|
|
"types-aiofiles~=25.1.0",
|
|
"types-redis~=4.6",
|
|
"commitizen>=4.13.9",
|
|
"pip-audit==2.9.0",
|
|
]
|
|
|
|
|
|
[tool.ruff]
|
|
src = ["lib/*"]
|
|
extend-exclude = [
|
|
"lib/crewai/src/crewai/cli/templates",
|
|
"lib/cli/src/crewai_cli/templates",
|
|
"lib/crewai/tests/",
|
|
"lib/crewai-tools/tests/",
|
|
"lib/cli/tests/",
|
|
]
|
|
respect-gitignore = true
|
|
force-exclude = true
|
|
fix = true
|
|
target-version = "py310"
|
|
|
|
[tool.ruff.format]
|
|
docstring-code-format = true
|
|
|
|
[tool.ruff.lint]
|
|
future-annotations = true
|
|
extend-select = [
|
|
"E", # pycodestyle errors (style issues)
|
|
"F", # Pyflakes (code errors)
|
|
"B", # flake8-bugbear (bug prevention)
|
|
"S", # bandit (security issues)
|
|
"RUF", # ruff-specific rules
|
|
"N", # pep8-naming (naming conventions)
|
|
"W", # pycodestyle warnings
|
|
"I", # isort (import formatting)
|
|
"T", # flake8-print (print statements)
|
|
# "D", # pydocstyle (docstring conventions) disabled until
|
|
"PERF", # performance issues
|
|
"PIE", # flake8-pie (unnecessary code)
|
|
"TID", # flake8-tidy-imports (import best practices)
|
|
"ASYNC", # async/await best practices
|
|
"RET", # flake8-return (return improvements)
|
|
"SIM118", # use `key in dict` instead of `key in dict.keys()`
|
|
"UP006", # use collections.abc
|
|
"UP007", # use X | Y for unions
|
|
"UP035", # use dict/list instead of typing.Dict/List
|
|
"UP037", # remove quotes from type annotations
|
|
"UP045", # use X | None instead of Optional[X]
|
|
"UP004", # use isinstance instead of type
|
|
"UP008", # use super() instead of super(Class, self)
|
|
"UP010", # use isinstance for type checks
|
|
"UP018", # use str() instead of "string"
|
|
"UP031", # use f-strings for .format()
|
|
"UP032", # use f-strings for .format() with positional
|
|
"I001", # sort imports
|
|
"I002", # remove unused imports
|
|
]
|
|
ignore = ["E501"] # ignore line too long globally
|
|
|
|
[tool.ruff.lint.flake8-tidy-imports]
|
|
ban-relative-imports = "all"
|
|
|
|
[tool.ruff.lint.flake8-type-checking]
|
|
runtime-evaluated-base-classes = ["pydantic.BaseModel"]
|
|
|
|
[tool.ruff.lint.isort]
|
|
no-sections = false
|
|
case-sensitive = true
|
|
combine-as-imports = true
|
|
force-single-line = false
|
|
force-sort-within-sections = true
|
|
known-first-party = []
|
|
section-order = ["future", "standard-library", "third-party", "first-party", "local-folder"]
|
|
lines-after-imports = 2
|
|
split-on-trailing-comma = true
|
|
|
|
[tool.ruff.lint.pydocstyle]
|
|
convention = "google"
|
|
ignore-decorators = ["typing.overload"]
|
|
|
|
[tool.ruff.lint.per-file-ignores]
|
|
"lib/crewai/tests/**/*.py" = ["S101", "RET504", "S105", "S106"] # Allow assert statements, unnecessary assignments, and hardcoded passwords in tests
|
|
"lib/crewai-tools/tests/**/*.py" = ["S101", "RET504", "S105", "S106", "RUF012", "N818", "E402", "RUF043", "S110", "B017"] # Allow various test-specific patterns
|
|
"lib/crewai-files/tests/**/*.py" = ["S101", "RET504", "S105", "S106", "B017", "F841"] # Allow assert statements and blind exception assertions in tests
|
|
"lib/cli/tests/**/*.py" = ["S101", "RET504", "S105", "S106"] # Allow assert statements in tests
|
|
"lib/crewai-core/tests/**/*.py" = ["S101", "RET504", "S105", "S106"] # Allow assert statements in tests
|
|
"lib/devtools/tests/**/*.py" = ["S101"]
|
|
|
|
|
|
[tool.mypy]
|
|
strict = true
|
|
disallow_untyped_defs = true
|
|
disallow_any_unimported = true
|
|
no_implicit_optional = true
|
|
check_untyped_defs = true
|
|
warn_return_any = true
|
|
show_error_codes = true
|
|
warn_unused_ignores = true
|
|
python_version = "3.12"
|
|
exclude = "(?x)(^lib/crewai/src/crewai/cli/templates/|^lib/cli/src/crewai_cli/templates/|^lib/crewai/tests/|^lib/crewai-tools/tests/|^lib/crewai-files/tests/|^lib/cli/tests/|^lib/devtools/tests/)"
|
|
plugins = ["pydantic.mypy"]
|
|
|
|
|
|
[tool.bandit]
|
|
exclude_dirs = ["lib/crewai/src/crewai/cli/templates", "lib/cli/src/crewai_cli/templates"]
|
|
|
|
|
|
[tool.pytest.ini_options]
|
|
markers = [
|
|
"telemetry: mark test as a telemetry test (don't mock telemetry)",
|
|
]
|
|
testpaths = [
|
|
"lib/crewai/tests",
|
|
"lib/crewai-tools/tests",
|
|
"lib/crewai-files/tests",
|
|
"lib/cli/tests",
|
|
"lib/crewai-core/tests",
|
|
]
|
|
asyncio_mode = "strict"
|
|
asyncio_default_fixture_loop_scope = "function"
|
|
addopts = "--tb=short -n auto --timeout=60 --dist=loadfile --max-worker-restart=2 --block-network --import-mode=importlib"
|
|
python_files = "test_*.py"
|
|
python_classes = "Test*"
|
|
python_functions = "test_*"
|
|
|
|
[tool.commitizen]
|
|
name = "cz_customize"
|
|
version_provider = "scm"
|
|
tag_format = "$version"
|
|
allowed_prefixes = ["Merge", "Revert"]
|
|
changelog_incremental = true
|
|
update_changelog_on_bump = false
|
|
|
|
[tool.commitizen.customize]
|
|
schema = "<type>(<scope>): <description>"
|
|
schema_pattern = "^(feat|fix|refactor|perf|test|docs|chore|ci|style|revert)(\\(.+\\))?!?: .{1,72}"
|
|
bump_pattern = "^(feat|fix|perf|refactor|revert)"
|
|
bump_map = { feat = "MINOR", fix = "PATCH", perf = "PATCH", refactor = "PATCH", revert = "PATCH" }
|
|
info = "Commits must follow Conventional Commits 1.0.0."
|
|
|
|
|
|
[tool.uv]
|
|
exclude-newer = "3 days"
|
|
# These security fixes are newer than the global supply-chain cutoff.
|
|
exclude-newer-package = { pypdf = "2026-08-07T00:00:00Z", msgpack = "2026-06-20T00:00:00Z", pydantic-settings = "2026-06-20T00:00:00Z", langsmith = "2026-06-20T00:00:00Z", gitpython = "2026-08-05T00:00:00Z" }
|
|
|
|
# composio-core pins rich<14 but textual requires rich>=14.
|
|
# onnxruntime 1.24+ dropped Python 3.10 wheels; cap it so qdrant[fastembed] resolves on 3.10.
|
|
# fastembed 0.7.x and docling 2.63 cap pillow<12; the removed APIs don't affect them.
|
|
# langchain-core <1.2.31 has GHSA-926x-3r5x-gfhw and is required by langchain-text-splitters 1.1.2+.
|
|
# langchain-core 1.0.0-1.3.2 has GHSA-pjwx-r37v-7724 (unsafe deserialization via broad load() allowlists); force 1.3.3+.
|
|
# langchain-text-splitters <1.1.2 has GHSA-fv5p-p927-qmxr (SSRF bypass in split_text_from_url).
|
|
# transformers 4.57.6 has CVE-2026-1839; force 5.4+ (docling 2.84 allows huggingface-hub>=1).
|
|
# cryptography 46.0.6 has CVE-2026-39892; force 46.0.7+.
|
|
# cryptography <=48.0.x has GHSA-m2h6-j472-rp4c, GHSA-jwv3-5hgf-82ww; fixed in 49.0.0.
|
|
# cryptography <50.0.0 has GHSA-g6cj-pr64-35w5 (PKCS#7 Bleichenbacher oracle); force 50.0.0+.
|
|
# pypdf <6.10.2 has GHSA-4pxv-j86v-mhcw, GHSA-7gw9-cf7v-778f, GHSA-x284-j5p8-9c5p.
|
|
# pypdf <6.14.2 has GHSA-jm82-fx9c-mx94 and GHSA-5qjq-93h5-hrgp/GHSA-55h5-xmcq-c37v/GHSA-g867-7843-wf8q/GHSA-5xf7-4p34-54qr; force 6.14.2+.
|
|
# pypdf <6.15.0 has GHSA-fwg2-594c-jp42 and GHSA-fp3f-mc75-235c (unbounded runtime/memory on large content
|
|
# and /ToUnicode streams); force 6.15.0+. Its exclude-newer-package cutoff is bumped to 2026-08-07 to admit
|
|
# that release.
|
|
# uv <0.11.15 has GHSA-4gg8-gxpx-9rph (and earlier GHSA-pjjw-68hj-v9mw); force 0.11.15+.
|
|
# python-multipart <0.0.27 has GHSA-pp6c-gr5w-3c5g (DoS via unbounded multipart headers).
|
|
# gitpython <3.1.50 has GHSA-mv93-w799-cj2w (config_writer newline injection bypassing the 3.1.49 patch -> RCE via core.hooksPath).
|
|
# gitpython <3.1.51 has GHSA-2f96-g7mh-g2hx, GHSA-v396-v7q4-x2qj, and GHSA-956x-8gvw-wg5v.
|
|
# gitpython <=3.1.51 has GHSA-rwj8-pgh3-r573; fixed in 3.1.52.
|
|
# gitpython 3.1.52 has GHSA-3rp5-jjmw-4wv2, GHSA-fjr4-x663-mwxc, GHSA-6p8h-3wgx-97gf, and GHSA-r9mr-m37c-5fr3; force 3.1.55+.
|
|
# gitpython <3.1.56 has GHSA-p538-c434-8v24 (arbitrary file truncation via `git rev-list --output` argument
|
|
# injection) and <3.1.57 has GHSA-3f7w-8rr8-f37f (unguarded git option forwarding in IndexFile.checkout and
|
|
# TagReference); force 3.1.57+.
|
|
# gitpython <3.1.58 has GHSA-9rj7-rf2p-w77r, GHSA-4gmw-gg2m-w46p, GHSA-hh9p-6wh2-4mfc, GHSA-wvpp-8hx9-p66j and
|
|
# GHSA-jm78-9fvv-mhgr (further unguarded git option forwarding in Repo.init, read-tree and git-config, plus
|
|
# arbitrary file read via --pathspec-from-file); force 3.1.58+. Its exclude-newer-package cutoff is bumped to
|
|
# 2026-08-05 to admit that release.
|
|
# pyasn1 <0.6.4 has GHSA-8ppf-4f7h-5ppj and GHSA-hm4w-wwcw-mr6r; force 0.6.4+.
|
|
# urllib3 <2.7.0 has GHSA-qccp-gfcp-xxvc (ProxyManager cross-origin redirect leaks Authorization/Cookie) and GHSA-mf9v-mfxr-j63j (streaming decompression-bomb bypass); force 2.7.0+.
|
|
# langsmith <0.8.18 has GHSA-3644-q5cj-c5c7 (public prompt manifest deserialization, SSRF/secret disclosure)
|
|
# and GHSA-f4xh-w4cj-qxq8; force 0.8.18+.
|
|
# authlib <1.6.12 has GHSA-jj8c-mmj3-mmgv (CSRF bypass in cache-based state storage) and PYSEC-2026-188.
|
|
# pip 26.1.1 has PYSEC-2026-196; force 26.1.2+.
|
|
# aiohttp <=3.13.x has GHSA-jg22-mg44-37j8, GHSA-hg6j-4rv6-33pg; fixed in 3.14.0; force 3.14.0+.
|
|
# aiohttp <=3.14.1 has GHSA-mq44-7p77-q5h7, GHSA-mfx4-hv73-q22v; fixed in 3.14.2.
|
|
# aiohttp <=3.14.2 has GHSA-cq5v-8q36-5273 (C parser OOB read); force 3.14.3+.
|
|
# docling-core 2.74.0 has GHSA-j5xp-7m2f-49jv, GHSA-jmmv-h3mp-59v8; force 2.74.1+.
|
|
# pip <26.1.1 has GHSA-58qw-9mgm-455v (archive handling); OSV considers 26.1.1 unaffected.
|
|
# paramiko <5.0.0 has GHSA-r374-rxx8-8654 (SHA-1 in rsakey.py); OSV considers 5.0.0 unaffected. Transitive via composio-core.
|
|
# starlette <1.3.1 has PYSEC-2026-161, GHSA-jp82-jpqv-5vv3, and GHSA-82w8-qh3p-5jfq. Transitive via fastapi.
|
|
# msgpack <1.2.1 has GHSA-6v7p-g79w-8964; transitive via pip-audit[filecache].
|
|
# nltk <3.10.0 has GHSA-qvv7-cg9c-w4x3 (DNS-rebinding SSRF bypass in
|
|
# nltk.pathsec.urlopen), GHSA-fg7f-2386-8897 (ReDoS in ReviewsCorpusReader), and
|
|
# GHSA-xh95-f55m-82fw (path traversal in FramenetCorpusReader.frame); all fixed
|
|
# in 3.10.0. 3.10.0 also clears PYSEC-2026-597, whose last affected version is
|
|
# 3.9.4, so that ignore is no longer needed. Transitive via
|
|
# crewai-tools[xml] -> unstructured.
|
|
# pydantic-settings <2.14.2 has GHSA-4xgf-cpjx-pc3j.
|
|
# h2 <=4.4.0 has GHSA-6hr6-w5qg-qmwg (CVE-2026-71554): duplicate Host headers
|
|
# can facilitate request smuggling; fixed in 4.4.1. Transitive via
|
|
# qdrant-client -> httpx[http2].
|
|
# Keep OpenAI on the SDK range required by CrewAI when transitive dependencies
|
|
# loosen or pin their own lower versions.
|
|
override-dependencies = [
|
|
"openai>=2.30.0,<3",
|
|
"rich>=13.7.1",
|
|
"onnxruntime<1.24; python_version < '3.11'",
|
|
"pillow>=12.3.0",
|
|
"langchain-core>=1.3.3,<2",
|
|
"langchain-text-splitters>=1.1.2,<2",
|
|
"urllib3>=2.7.0",
|
|
"transformers>=5.4.0; python_version >= '3.10'",
|
|
"cryptography>=50.0.0",
|
|
"pypdf>=6.15.0,<7",
|
|
"uv>=0.11.15,<1",
|
|
"python-multipart>=0.0.27,<1",
|
|
"gitpython>=3.1.58,<4",
|
|
"pyasn1>=0.6.4",
|
|
"langsmith>=0.8.18,<1",
|
|
"authlib>=1.6.12",
|
|
"pip>=26.1.2",
|
|
"aiohttp>=3.14.3",
|
|
# [chunking] carried here because override-dependencies replace the whole
|
|
# requirement; without it the docling extra's chunking deps get stripped.
|
|
"docling-core[chunking]>=2.74.1",
|
|
"paramiko>=5.0.0",
|
|
"starlette>=1.3.1",
|
|
"msgpack>=1.2.1",
|
|
"pydantic-settings>=2.14.2",
|
|
"setuptools>=83.0.0", # PYSEC-2026-3447
|
|
"nltk>=3.10.0",
|
|
"h2>=4.4.1",
|
|
]
|
|
|
|
[tool.uv.workspace]
|
|
members = [
|
|
"lib/crewai",
|
|
"lib/crewai-tools",
|
|
"lib/devtools",
|
|
"lib/crewai-files",
|
|
"lib/cli",
|
|
"lib/crewai-core",
|
|
]
|
|
|
|
|
|
[tool.uv.sources]
|
|
crewai = { workspace = true }
|
|
crewai-tools = { workspace = true }
|
|
crewai-devtools = { workspace = true }
|
|
crewai-files = { workspace = true }
|
|
crewai-cli = { workspace = true }
|
|
crewai-core = { workspace = true }
|