BaseTool could not serialize to JSON because args_schema (a class
reference) and cache_function (a lambda) are not JSON-serializable.
This caused checkpointing to crash for any crew with tools.
- Add PlainSerializer to args_schema so it round-trips via JSON schema
- Replace default cache_function lambda with named _default_cache_function
and type it as SerializableCallable
- Add computed_field tool_type storing the fully qualified class name
- Add __init_subclass__ registry and __get_pydantic_core_schema__ on
BaseTool so any list[BaseTool] field automatically dispatches to the
concrete subclass during deserialization via tool_type lookup
- No changes needed to BaseAgent.validate_tools or Task — Pydantic
handles it natively through the custom core schema
BaseTool could not serialize to JSON because args_schema (a class
reference) and cache_function (a lambda) are not JSON-serializable.
This caused checkpointing to crash for any crew with tools.
- Add PlainSerializer to args_schema so it round-trips via JSON schema
- Replace default cache_function lambda with named _default_cache_function
and type it as SerializableCallable so it serializes to a dotted path
- Add computed_field tool_type that stores the fully qualified class name
- Add restore_tool_from_dict to reconstruct the concrete subclass from
checkpoint dicts, pre-resolving callback strings to callables
- Update BaseAgent.validate_tools and Task._restore_tools_from_checkpoint
to handle dict inputs from checkpoint deserialization
* 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>
Use BeforeValidator/PlainSerializer with create_model_from_schema to
serialize type[BaseModel] as its JSON schema dict and reconstruct a
dynamic model on deserialization.
- Add Literal type discriminators to all 119 event subclasses
- Add BeforeValidator + PlainSerializer on EventNode.event to
deserialize events into the correct subclass using a type registry
- Falls back to BaseEvent for unrecognized or incomplete event dicts
Set task_id and task_name in _set_task_fingerprint so events carry
task identity through serialization. Use task_id to find the correct
task_started event when restoring the scope stack on checkpoint resume.
Add type discriminator fields to BaseLLM subclasses and
BaseAgentExecutor subclasses so checkpoint deserialization restores
the correct provider class instead of always creating LLM/CrewAgentExecutor.
Switch RuntimeState serializer from mode="wrap" to mode="plain" with
dict return type so pydantic doesn't re-serialize entities through the
Entity union pipeline. Also switch to string-based field discriminator
for Entity union.
* 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>
Replay the event record during _restore_runtime to rebuild
_event_id_stack with correct event IDs. Remove manual push_event_scope
calls from task and crew resume paths that used task UUIDs instead
of event IDs.
Extract _prepare_event to set previous_event_id, triggered_by_event_id,
emission_sequence, parent/child scoping, and event_record tracking.
Both emit and aemit now call it, fixing aemit's missing metadata.
litellm 1.83.0 fixes CVE-2026-35029 (proxy config privilege escalation)
and CVE-2026-35030 (proxy JWT auth bypass), and is the first release
after the supply chain incident. Bump openai to 2.x to satisfy litellm's
dependency.
- Bump uv-pre-commit from 0.9.3 to 0.11.3 to support relative
exclude-newer values in pyproject.toml
- Use checkpoint_kickoff_event_id to detect resume, preventing
second kickoff() from skipping tasks or suppressing events
- Return len(tasks) from _get_execution_start_index when all tasks
complete, preventing full re-execution of finished checkpoints
- Add _get_execution_start_index call to _aexecute_tasks so async
resume skips completed tasks like the sync path does
- Cache inspect.signature results per handler to avoid repeated
introspection on every event emission
- Disable union-attr/arg-type at file level in the two executor files
where agent/task/crew are always set at runtime but typed as optional
- Fix Liskov override in OpenAICompletion: use BaseAgent instead of Agent
- Remove stale type: ignore comments now covered by file-level disables
After model_rebuild, BaseAgentExecutor rejects plain MagicMock for
typed fields. Construct with defaults then assign mocks post-init.
Also guard RuntimeState tests for environments where model_rebuild fails.