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.
The spec generator previously used a hardcoded list of field names to
exclude from init_params_schema. Any new field or computed_field added
to BaseTool (like tool_type from 86ce54f) would silently leak into
tool.specs.json unless someone remembered to update that list.
Now _extract_init_params() dynamically computes BaseTool's fields at
import time via model_fields + model_computed_fields, so any future
additions to BaseTool are automatically excluded.
Fields from intermediate base classes (RagTool, BraveSearchToolBase,
SerpApiBaseTool) are correctly preserved since they're not on BaseTool.
TDD:
- RED: 3 new tests confirming BaseTool field leak, intermediate base
preservation, and future-proofing — all failed before the fix
- GREEN: Dynamic allowlist applied — all 10 tests pass
- Regenerated tool.specs.json (tool_type removed from all tools)
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 SSRF and path traversal protections
CVE-2026-2286: validate_url blocks non-http/https schemes, private
IPs, loopback, link-local, reserved addresses. Applied to 11 web tools.
CVE-2026-2285: validate_path confines file access to the working
directory. Applied to 7 file and directory tools.
* fix: drop unused assignment from validate_url call
* fix: DNS rebinding protection and allow_private flag
Rewrite validated URLs to use the resolved IP, preventing DNS rebinding
between validation and request time. SDK-based tools use pin_ip=False
since they manage their own HTTP clients. Add allow_private flag for
deployments that need internal network access.
* fix: unify security utilities and restore RAG chokepoint validation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* refactor: move validation to security/ package + address review comments
- Move safe_path.py to crewai_tools/security/; add safe_url.py re-export
- Keep utilities/safe_path.py as a backwards-compat shim
- Update all 21 import sites to use crewai_tools.security.safe_path
- files_compressor_tool: validate output_path (user-controlled)
- serper_scrape_website_tool: call validate_url() before building payload
- brightdata_unlocker: validate_url() already called without assignment (no-op fix)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* refactor: move validation to security/ package, keep utilities/ as compat shim
- security/safe_path.py is the canonical location for all validation
- utilities/safe_path.py re-exports for backward compatibility
- All tool imports already point to security.safe_path
- All review comments already addressed in prior commits
* fix: move validation outside try/except blocks, use correct directory validator
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: use resolved paths from validation to prevent symlink TOCTOU, remove unused safe_url.py
---------
Co-authored-by: Alex <alex@crewai.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* 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>
* fix: add tool repository credentials to crewai install
crewai install (uv sync) was failing with 401 Unauthorized when the
project depends on tools from a private package index (e.g. AMP tool
repository). The credentials were already injected for 'crewai run'
and 'crewai tool publish' but were missing from 'crewai install'.
Reads [tool.uv.sources] from pyproject.toml and injects UV_INDEX_*
credentials into the subprocess environment, matching the pattern
already used in run_crew.py.
* refactor: extract duplicated credential-building into utility function
Create build_env_with_all_tool_credentials() in utils.py to consolidate
the ~10-line block that reads [tool.uv.sources] from pyproject.toml and
calls build_env_with_tool_repository_credentials for each index.
This eliminates code duplication across install_crew.py, run_crew.py,
and cli.py, reducing the risk of inconsistent bug fixes.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: add debug logging for credential errors instead of silent swallow
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix: add tool repository credentials to uv build in tool publish
When running 'uv build' during tool publish, the build process now has access
to tool repository credentials. This mirrors the pattern used in run_crew.py,
ensuring private package indexes are properly authenticated during the build.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: add env kwarg to subprocess.run mock assertions in publish tests
The actual code passes env= to subprocess.run but the test assertions
were missing this parameter, causing assertion failures.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
security_context was being injected into tool arguments by
_add_fingerprint_metadata(), causing Pydantic validation errors
(extra_forbidden) on MCP and integration tools with strict schemas.
Move fingerprint data to the `config` parameter that invoke/ainvoke
already accept, keeping it available to consumers without polluting
the tool args namespace.
Co-authored-by: Lorenze Jay <63378463+lorenzejay@users.noreply.github.com>
- Added telemetry spans for various skill events: discovery, loading, activation, and load failure.
- Introduced telemetry spans for memory events: save, query, and retrieval completion.
- Updated event listener to include new MCP tool execution and connection events with telemetry tracking.
Introduce the A2UI extension for declarative UI generation, including
support for both v0.8 and v0.9 protocol specs. Add A2UI content type
integration in A2A utils, along with schema definitions, catalog models,
and client extension improvements.
Enhance models with explicit defaults, field descriptions, and ConfigDict,
and improve typing and instance state handling across the extension.
Add schema conformance tests and align test structure.
Add and register A2UI documentation, including extension guide and
navigation updates.