Add crewai deploy validate to check project structure, dependencies, imports, and env usage before deploy
Run validation automatically in deploy create and deploy push with skip flag support
Return structured findings with stable codes and hints
Add test coverage for validation scenarios
refactor: defer LLM client construction to first use
Move SDK client creation out of model initialization into lazy getters
Add _get_sync_client and _get_async_client across providers
Route all provider calls through lazy getters
Surface credential errors at first real invocation
refactor: standardize provider client access
Align async paths to use _get_async_client
Avoid client construction in lightweight config accessors
Simplify provider lifecycle and improve consistency
test: update suite for new behavior
Update tests for lazy initialization contract
Update CLI tests for validation flow and skip flag
Expand coverage for provider initialization paths
func_info.get('arguments', '{}') returns '{}' (truthy) when no
'function' wrapper exists (Bedrock format), causing the or-fallback
to tool_call.get('input', {}) to never execute. The actual Bedrock
arguments are silently discarded.
Remove the default so get('arguments') returns None (falsy) when
there's no function wrapper, allowing the or-chain to correctly
fall through to Bedrock's 'input' field.
Fixes#5275
Pydantic schemas intermittently fail strict tool-use on openai, anthropic,
and bedrock. All three reject nested objects missing additionalProperties:
false, and anthropic also rejects keywords like minLength and top-level
anyOf. Adds per-provider sanitizers that inline refs, close objects, mark
every property required, preserve nullable unions, and strip keywords each
grammar compiler rejects. Verified against real bedrock, anthropic, and
openai.
Substring checks like `'0.1' not in json_str` collided with timestamps
such as `2026-04-10T13:00:50.140557` on CI. Round-trip through
`model_validate_json` to verify structurally that the embedding field
is absent from the serialized output.
- Rewrite TUI with Tree widget showing branch/fork lineage
- Add Resume and Fork buttons in detail panel with Collapsible entities
- Show branch and parent_id in detail panel and CLI info output
- Auto-detect .checkpoints.db when default dir missing
- Append .db to location for SqliteProvider when no extension set
- Fix RuntimeState.from_checkpoint not setting provider/location
- Fork now writes initial checkpoint on new branch
- Add from_checkpoint, fork, and CLI docs to checkpointing.mdx
The OpenAI-format tool schema sets strict: true but this was dropped
during conversion to Anthropic/Bedrock formats, so neither provider
used constrained decoding. Without it, the model can return string
"None" instead of JSON null for nullable fields, causing Pydantic
validation failures.
Accept CheckpointConfig on Crew and Flow kickoff/kickoff_async/akickoff.
When restore_from is set, the entity resumes from that checkpoint.
When only config fields are set, checkpointing is enabled for the run.
Adds restore_from field (Path | str | None) to CheckpointConfig.
Write the crewAI package version into every checkpoint blob. On restore,
run version-based migrations so older checkpoints can be transformed
forward to the current format. Adds crewai.utilities.version module.
resume_async() was missing trace infrastructure that kickoff_async()
sets up, causing flow_finished to never reach the platform after HITL
feedback. Add FlowStartedEvent emission to initialize the trace batch,
await event futures, finalize the trace batch, and guard with
suppress_flow_events.
Launch a Textual TUI via `crewai checkpoint` to browse and resume
from checkpoints. Uses run_async/akickoff for fully async execution.
Adds provider auto-detection from file magic bytes.
Wrapping sys.stdout and sys.stderr at import time with a
threading.Lock is not fork-safe and adds overhead to every
print call. litellm.suppress_debug_info already silences the
noisy output this was designed to filter.
Replace the Protocol with a BaseModel + ABC so providers serialize and
deserialize natively via pydantic. Each provider gets a Literal
provider_type field. CheckpointConfig.provider uses a discriminated
union so the correct provider class is reconstructed from checkpoint JSON.
* fix: add path and URL validation to RAG tools
Add validation utilities to prevent unauthorized file reads and SSRF
when RAG tools accept LLM-controlled paths/URLs at runtime.
Changes:
- New crewai_tools.utilities.safe_path module with validate_file_path(),
validate_directory_path(), and validate_url()
- File paths validated against base directory (defaults to cwd).
Resolves symlinks and ../ traversal. Rejects escape attempts.
- URLs validated: file:// blocked entirely. HTTP/HTTPS resolves DNS
and blocks private/reserved IPs (10.x, 172.16-31.x, 192.168.x,
127.x, 169.254.x, 0.0.0.0, ::1, fc00::/7).
- Validation applied in RagTool.add() — catches all RAG search tools
(JSON, CSV, PDF, TXT, DOCX, MDX, Directory, etc.)
- Removed file:// scheme support from DataTypes.from_content()
- CREWAI_TOOLS_ALLOW_UNSAFE_PATHS=true env var for backward compat
- 27 tests covering traversal, symlinks, private IPs, cloud metadata,
IPv6, escape hatch, and valid paths/URLs
* fix: validate path/URL keyword args in RagTool.add()
The original patch validated positional *args but left all keyword
arguments (path=, file_path=, directory_path=, url=, website=,
github_url=, youtube_url=) unvalidated, providing a trivial bypass
for both path-traversal and SSRF checks.
Applies validate_file_path() to path/file_path/directory_path kwargs
and validate_url() to url/website/github_url/youtube_url kwargs before
they reach the adapter. Adds a regression-test file covering all eight
kwarg vectors plus the two existing positional-arg checks.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: address CodeQL and review comments on RAG path/URL validation
- Replace insecure tempfile.mktemp() with inline symlink target in test
- Remove unused 'target' variable and unused tempfile import
- Narrow broad except Exception: pass to only catch urlparse errors;
validate_url ValueError now propagates instead of being silently swallowed
- Fix ruff B904 (raise-without-from-inside-except) in safe_path.py
- Fix ruff B007 (unused loop variable 'family') in safe_path.py
- Use validate_directory_path in DirectorySearchTool.add() so the
public utility is exercised in production code
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* style: fix ruff format + remaining lint issues
* fix: resolve mypy type errors in RAG path/URL validation
- Cast sockaddr[0] to str() to satisfy mypy (socket.getaddrinfo returns
sockaddr where [0] is str but typed as str | int)
- Remove now-unnecessary `type: ignore[assignment]` and
`type: ignore[literal-required]` comments in rag_tool.py
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: unroll dynamic TypedDict key loops to satisfy mypy literal-required
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* test: allow tmp paths in RAG data-type tests via CREWAI_TOOLS_ALLOW_UNSAFE_PATHS
TemporaryDirectory creates files under /tmp/ which is outside CWD and is
correctly blocked by the new path validation. These tests exercise
data-type handling, not security, so add an autouse fixture that sets
CREWAI_TOOLS_ALLOW_UNSAFE_PATHS=true for the whole file. Path/URL
security is covered by test_rag_tool_path_validation.py.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* test: allow tmp paths in search-tool and rag_tool tests via CREWAI_TOOLS_ALLOW_UNSAFE_PATHS
test_search_tools.py has tests for TXTSearchTool, CSVSearchTool,
MDXSearchTool, JSONSearchTool, and DirectorySearchTool that create
files under /tmp/ via tempfile, which is outside CWD and correctly
blocked by the new path validation. rag_tool_test.py has one test
that calls tool.add() with a TemporaryDirectory path.
Add the same autouse allow_tmp_paths fixture used in
test_rag_tool_add_data_type.py. Security is covered separately by
test_rag_tool_path_validation.py.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* chore: update tool specifications
* docs: document CodeInterpreterTool removal and RAG path/URL validation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: address three review comments on path/URL validation
- safe_path._is_private_or_reserved: after unwrapping IPv4-mapped IPv6
to IPv4, only check against IPv4 networks to avoid TypeError when
comparing an IPv4Address against IPv6Network objects.
- safe_path.validate_file_path: handle filesystem-root base_dir ('/')
by not appending os.sep when the base already ends with a separator,
preventing the '//'-prefix bug.
- rag_tool.add: path-detection heuristic now checks for both '/' and
os.sep so forward-slash paths are caught on Windows as well as Unix.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: remove unused _BLOCKED_NETWORKS variable after IPv4/IPv6 split
* chore: update tool specifications
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* refactor: remove CodeInterpreterTool and deprecate code execution params
CodeInterpreterTool has been removed. The allow_code_execution and
code_execution_mode parameters on Agent are deprecated and will be
removed in v2.0. Use dedicated sandbox services (E2B, Modal, etc.)
for code execution needs.
Changes:
- Remove CodeInterpreterTool from crewai-tools (tool, Dockerfile, tests, imports)
- Remove docker dependency from crewai-tools
- Deprecate allow_code_execution and code_execution_mode on Agent
- get_code_execution_tools() returns empty list with deprecation warning
- _validate_docker_installation() is a no-op with deprecation warning
- Bedrock CodeInterpreter (AWS hosted) and OpenAI code_interpreter are NOT affected
* fix: remove empty code_interpreter imports and unused stdlib imports
- Remove empty `from code_interpreter_tool import ()` blocks in both
crewai_tools/__init__.py and tools/__init__.py that caused SyntaxError
after CodeInterpreterTool was removed
- Remove unused `shutil` and `subprocess` imports from agent/core.py
left over from the code execution params deprecation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: remove redundant _validate_docker_installation call and fix list type annotation
- Drop the _validate_docker_installation() call inside the allow_code_execution
block — it fired a second DeprecationWarning identical to the one emitted
just above it, making the warning fire twice.
- Annotate get_code_execution_tools() return type as list[Any] to satisfy mypy
(bare `list` fails the type-arg check introduced by this branch).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* ci: retrigger
* fix: update test_crew.py to remove CodeInterpreterTool references
CodeInterpreterTool was removed from crewai_tools. Update tests to
reflect that get_code_execution_tools() now returns an empty list.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* chore: update tool specifications
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* feat: add guardrail_type to distinguish between hallucination, function, and LLM
* feat: introduce guardrail_name into guardrail events
* feat: propagate guardrail type and name on guardrail completed event
* feat: remove unused LLMGuardrailFailedEvent
* fix: handle running event loop in LLMGuardrail._validate_output
When agent.kickoff() returns a coroutine inside an already-running event loop, asyncio.run() fails
- Pass RuntimeState through the event bus and enable entity auto-registration
- Introduce checkpointing API:
- .checkpoint(), .from_checkpoint(), and async checkpoint support
- Provider-based storage with BaseProvider and JsonProvider
- Mid-task resume and kickoff() integration
- Add EventRecord tracking and full event serialization with subtype preservation
- Enable checkpoint fidelity via llm_type and executor_type discriminators
- Refactor executor architecture:
- Convert executors, tools, prompts, and TokenProcess to BaseModel
- Introduce proper base classes with typed fields (CrewAgentExecutorMixin, BaseAgentExecutor)
- Add generic from_checkpoint with full LLM serialization
- Support executor back-references and resume-safe initialization
- Refactor runtime state system:
- Move RuntimeState into state/ module with async checkpoint support
- Add entity serialization improvements and JSON-safe round-tripping
- Implement event scope tracking and replay for accurate resume behavior
- Improve tool and schema handling:
- Make BaseTool fully serializable with JSON round-trip support
- Serialize args_schema via JSON schema and dynamically reconstruct models
- Add automatic subclass restoration via tool_type discriminator
- Enhance Flow checkpointing:
- Support restoring execution state and subclass-aware deserialization
- Performance improvements:
- Cache handler signature inspection
- Optimize event emission and metadata preparation
- General cleanup:
- Remove dead checkpoint payload structures
- Simplify entity registration and serialization logic
* fix: exclude embedding vector from MemoryRecord serialization
MemoryRecord.embedding (1536 floats for OpenAI embeddings) was included
in model_dump()/JSON serialization and repr. When recall results flow
to agents or get logged, these vectors burn tokens for zero value —
agents never need the raw embedding.
Added exclude=True and repr=False to the embedding field. The storage
layer accesses record.embedding directly (not via model_dump), so
persistence is unaffected.
* test: validate embedding excluded from serialization
Two tests:
1. MemoryRecord — model_dump, model_dump_json, and repr all exclude
embedding. Direct attribute access still works for storage layer.
2. MemoryMatch — nested record serialization also excludes embedding.
* fix: bump litellm to >=1.83.0 to address CVE-2026-35030
Bump litellm from <=1.82.6 to >=1.83.0 to fix JWT auth bypass via
OIDC cache key collision (CVE-2026-35030). Also widen devtools openai
pin from ~=1.83.0 to >=1.83.0,<3 to resolve the version conflict
(litellm 1.83.0 requires openai>=2.8.0).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: resolve mypy errors from litellm bump
- Remove unused type: ignore[import-untyped] on instructor import
- Remove all unused type: ignore[union-attr] comments (litellm types fixed)
- Add hasattr guard for tool_call.function — new litellm adds
ChatCompletionMessageCustomToolCall to the union which lacks .function
* fix: tighten litellm pin to ~=1.83.0 (patch-only bumps)
>=1.83.0,<2 is too wide — litellm has had breaking changes between
minors. ~=1.83.0 means >=1.83.0,<1.84.0 — gets CVE patches but won't
pull in breaking minor releases.
* ci: bump uv from 0.8.4 to 0.11.3
* fix: resolve mypy errors in openai completion from 2.x type changes
Use isinstance checks with concrete openai response types instead of
string comparisons for proper type narrowing. Update code interpreter
handling for outputs/OutputImage API changes in openai 2.x.
* fix: pre-cache tiktoken encoding before VCR intercepts requests
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Alex <alex@crewai.com>
Co-authored-by: Greyson LaLonde <greyson@crewai.com>
* chore: update uv.lock with new dependency groups and versioning adjustments
- Added a new revision number and updated resolution markers for Python version compatibility.
- Introduced a 'dev' dependency group with specific versions for various development tools.
- Updated sdist and wheels entries to include upload timestamps for better tracking.
- Adjusted numpy dependencies to specify versions based on Python version markers.
* feat: bump versions to 1.14.0a1
The `save_content` method wrote to `output/post.md` without ensuring the
`output/` directory exists, causing a FileNotFoundError when the directory
hasn't been created by another step.
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>