Commit Graph

85 Commits

Author SHA1 Message Date
João Moura
d2190c2a7d fix(agents): carry from_cache on the native tool path's ToolUsageFinishedEvent (#7501)
`_execute_single_native_tool_call` reads the tools handler's cache and
skips the tool body on a hit, but emitted its ToolUsageFinishedEvent
without `from_cache`, so the bus — and every trace built from it — saw a
replayed native function call as a live one. The text-protocol path
(ToolUsage.on_tool_use_finished) already carried the flag. One kwarg.

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-16 12:47:31 +05:30
João Moura
9393a47f31 fix(agents): request the forced final answer as a user turn (#7450)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Vulnerability Scan / Detect changes (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Check Documentation Broken Links / Check broken links (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
* fix(agents): request the forced final answer as a user turn

When an agent reaches max_iter, handle_max_iterations_exceeded appended
the "give your best final answer" instruction as an assistant message and
relied on assistant prefill to make the model continue it. Current Claude
models (Opus 5, Sonnet 5, Fable 5.x, the 4.6+ family) reject a request
that ends on an assistant turn with a 400, after the whole iteration
budget has already been spent.

The instruction is now appended as a user turn, which every provider
accepts. The handler's formatted_answer parameter is dropped: every
caller had already appended that text as the last assistant message, so
prefixing it again only duplicated history.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* fix(agents): stop the lite agent loop after the forced final answer

LiteAgent._invoke_loop fell through after handle_max_iterations_exceeded
and issued a regular LLM call on the same history, discarding the forced
answer. Break out of the loop the way CrewAgentExecutor already does, and
assert a single LLM call in the test.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-14 11:52:08 +05:30
monkscode
5704ea08eb fix(agents): keep null in the task output schema embedded in the prompt (#6775)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Vulnerability Scan / Detect changes (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Nightly Canary Release / Check for new commits (push) Has been cancelled
Nightly Canary Release / Build nightly packages (push) Has been cancelled
Nightly Canary Release / Publish nightly to PyPI (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
Check Documentation Broken Links / Check broken links (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
* fix(agents): keep null in the task output schema embedded in the prompt

build_task_prompt_with_schema embeds the task output schema into the prompt
via generate_model_description, whose strip_null_types defaults to True.
Combined with ensure_all_properties_required, an Optional[str] = None field
reaches the model as a required, non-nullable string, contradicting the
provider-side response schema generated from the same model.

That sanitizer targets OpenAI strict function-calling schemas. This call site
produces prompt prose, where those constraints do not apply.

Pass strip_null_types=False, matching the existing call for tool schemas in
utilities/agent_utils.py.

Fixes #6774

* test(agents): cover the output_json branch of the prompt schema

build_task_prompt_with_schema embeds a schema on both the output_json and
the output_pydantic branch, and this PR changes both. The regression test
only built a Task with output_pydantic, so the output_json branch shipped
unpinned.

Parameterize over both output attributes. Checked on this branch with the
fix reverted: both cases fail on the missing anyOf, and both pass with it.

Also compare the anyOf members as a set, so member order is not part of the
test contract.

---------

Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-10 13:46:16 +05:30
Liangshanbobo
929a173575 test(agents): cover native result as answer (#7334) (#7336)
* test(agents): cover native result as answer (#7334)

* test(agents): document result as answer coverage

---------

Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-09 13:32:27 +05:30
Vinicius Brasil
381fef73be Add injectable client for CrewAI platform tools (#7177)
* Add injectable client for CrewAI platform tools

Define an integrations client contract for action discovery and
execution. Keep the existing platform API as the default client to
preserve current behavior.

Allow callers to provide a custom client through CrewaiPlatformTools.

* Fix platform action tool failure tests

* Remove redundant protocol placeholders
2026-08-31 16:01:54 -07:00
Lorenze Jay
5139078c6a fix(agents): preserve tool results when final answer is empty (#7133)
* fix(agents): preserve tool results when final answer is empty

Updated the StepExecutor to ensure that if the final answer from a tool call is empty, the last valid tool result is returned instead. This change enhances the reliability of the output in scenarios where the final answer may not provide useful information. Added tests to verify that both text and native steps correctly preserve tool results under these conditions.

* raise on empty string path
2026-08-27 22:10:11 +05:30
João Moura
6ad3bf9390 fix(agents): render message content parts as text, not a python repr (#7109)
* fix(agents): render message content parts as text, not a Python repr

A message whose `content` is a multimodal parts list collapsed to
`str(content)` wherever a message had to become a string, so the model
saw `[{'type': 'text', 'text': 'hello'}]` in Current Task, and memory
stored and searched that same repr.

Four sites flattened it that way: the turn promoted into the executor
prompt, the memory recall query, what `_save_kickoff_to_memory` writes,
and `_message_content_text` (token estimation and oversized-message
splitting).

The extraction already existed, inline in `_format_messages_for_summary`
-- text blocks joined, or `[multimodal content]` when a list carries
none. This lifts it to `_content_parts_text` and routes all five callers
through it, so summary, prompt, memory and token counting agree.

`_message_content_text` becomes `message_content_text`: it now has a
caller outside its module, and `agent/core.py` imports only public names
from `agent_utils`. It is not re-exported from any `__init__`, so no
public import path changes.

`test_list_content_uses_str` pinned the repr, so it is intentionally
rewritten to pin the text. Every other existing caller is unchanged:
30 failures on main, 30 on this branch, identical names.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VwxiogL9mQg9q8cx4qLfYJ

* fix(agents): skip a content part whose text is not a string

`_content_parts_text` joined `block["text"]` straight into a string, and
content blocks are `dict[str, Any]` arriving from a model, so a `text`
key holding an int, dict or None raised `TypeError`. That was contained
to summarization before; routing the prompt, memory and token-estimation
paths through the same helper widened it to `Agent.kickoff`, where the
old `str()` had merely produced an ugly string.

Such a block carries no usable text, so it is skipped. A list left with
nothing usable still falls back to `[multimodal content]`.

Writes the convention down in AGENTS.md rather than leaving it in a
review thread: never `str()` a message's content, use
`message_content_text`. Four sites had independently reached for
`str()`, which is what this whole change is undoing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VwxiogL9mQg9q8cx4qLfYJ

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-25 19:34:05 +00:00
João Moura
9652af6ae0 fix(agents): keep message roles when Agent.kickoff gets a conversation (#7065)
* fix(agents): keep message roles when Agent.kickoff gets a conversation

`Agent.kickoff` accepts `str | list[LLMMessage]`, but `_prepare_kickoff` joined
every message's content into one string. Measured with a recording LLM, a
three-turn conversation reached the provider as two messages:

    system | You are Support...
    user   | Current Task: my order id is 42\nthanks, checking\nwhere is it?

So the agent's own previous reply was presented as something the user said, and
the model could not tell who said what. `LiteAgent.kickoff` already did this
correctly, which is why the same list gave four messages with roles intact
there.

The last message is now this turn's request and the ones before it travel as
`inputs["history"]` -- the way `inputs["files"]` already does -- which both
executors splice in after the system prompt and before the user prompt. Memory
recall still runs over the whole conversation text, not just the last turn.

A plain string and a single-message list are byte-identical to before, which is
what every existing caller passes.

Also widens `LiteAgentExecutionStartedEvent.messages` from `list[dict[str, str]]`
to `list[LLMMessage]`: it raised a ValidationError for a message whose content
was `None` or a content-part list, both of which are valid `LLMMessage` shapes
that `Agent.kickoff` already accepts.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(agents): carry history without a system prompt, tool calls, or dup files

Three review findings on the message-role work, all real.

History was spliced only in the branch that builds a system prompt. With
`use_system_prompt=False` or a custom template there is one combined prompt, so
history went nowhere and only the last turn reached the model -- worse than the
flattening this PR replaced, which at least included the text. Both executors
now splice in either branch, via one `_append_history` helper each.

Filtering on truthy content dropped an assistant turn that only requests tool
calls, leaving a `tool` message with no preceding `tool_calls` message -- a
sequence providers reject. A message now counts when it has content, tool
calls, or a tool_call_id.

And `files` were unioned from every message onto the current request while
history messages kept their own, so prior attachments were sent twice. Only the
current request's attachments travel in `inputs["files"]` now.

Found by Cursor and CodeRabbit on #7065.

* fix(agents): treat an attachment as message payload

_carries_payload counted text, tool calls and tool results, but not files.
A final message whose only payload was an attachment was filtered out, so the
previous message became this turn request and the attachment never reached
inputs["files"].

Found independently by Cursor and CodeRabbit on #7065.

* fix(agents): promote the last user message, not the last message

build_agent_context() appends an agent private thread after the current user
turn, so on a later turn the trailing message is an assistant scratch. That
scratch became Current Task while the real question was demoted to history --
reproduced: the request came back as "internal note: checked warehouse".

The request is now the last user message, with everything else kept as history
in order; with no user message the last one stands in, which is what a
single-message caller has always got. Documented on kickoff and kickoff_async.

The old cross-check against LiteAgent only compared roles on a fixture already
ending in a user message, so it could not catch this. It now asserts what holds
for both -- nothing dropped, nothing duplicated -- since Agent has a task slot
in its prompt and LiteAgent does not.

Reported by Vidit-Ostwal on #7065.

* test(agents): cover history placement on the deprecated executor too

`CrewAgentExecutor` carries its own `_setup_messages`, and `Agent.kickoff`
builds an `AgentExecutor` unconditionally, so nothing reached the twin's
two `_append_history` sites. This drives that executor directly with the
real `SystemPromptResult` / `StandardPromptResult` shapes, so both its
branches are pinned.

Verified by mutation: removing either `_append_history` call in either
executor now fails the matching test.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VwxiogL9mQg9q8cx4qLfYJ

* fix(agents): keep turns that follow the request after it

`_prepare_kickoff` packed every non-request message into one `history`
list, and both executors spliced that list before the current user
prompt. A conversation ending on a tool result therefore reached the
provider as `assistant tool_calls -> tool -> user`, hoisting the tool
pair above the question it answers. `LiteAgent` sends the same list as
`user -> assistant -> tool`.

Splits the carried messages at the request instead: what came before
stays `history`, what came after travels as `trailing` and is appended
after the user prompt. Promoting the last user message to `{input}` is
unchanged.

`test_a_tool_call_sequence_survives` missed this because it ends on a
follow-up user line, so the tool pair was already before the request.

Reported by lorenzejay, who also confirmed gpt-4o-mini and gpt-5.6-sol
accept the reordered payload -- an order bug, not a provider 400.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VwxiogL9mQg9q8cx4qLfYJ

* test(agents): assert the ordering through kickoff_async too

`kickoff_async` shares `_prepare_kickoff`, and the async executor entry
points reach the same `_setup_messages`, but sharing a code path is not
the same as covering it. Pins the tool-result ordering through the async
path, and lifts the tool conversation to a module-level fixture so the
sync and async assertions cannot drift.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VwxiogL9mQg9q8cx4qLfYJ

* docs(agents): state where a kickoff conversation's turns land

`concepts/agents.mdx` documents the multi-message form but not which
message becomes the request or what happens to the turns around it --
the contract this branch changed. Corrects the `kickoff` /
`kickoff_async` docstrings to match.

en and ko only: the ar and pt-BR pages do not carry the "Multiple
Messages" section at all, which is a pre-existing translation gap rather
than one this change introduces.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VwxiogL9mQg9q8cx4qLfYJ

* feat(flow): let a declarative agent action receive the conversation (#7066)

* feat(flow): let a declarative agent action receive the conversation

A chat handler could only hand its agent a single string, so a declarative
conversational flow's `agent` action never saw prior turns. Both ends blocked
it: `AgentDefinition.input` was `str` with a validator rejecting anything else,
and `AgentAction.run` raised "agent input must render to a string" once a CEL
template rendered to a list.

`input` now takes a string or a list of messages, and the action normalizes
rather than rejecting. A whole-string `${...}` template keeps its evaluated
type, so `state.messages.map(m, {'role': m.role, 'content': m.content})`
renders the exact shape the agent wants -- no new CEL function needed.

Serialized messages carry `name: None` and `metadata` that the agent event
schema rejects, and `message_to_llm_dict` only drops `None` for a model input,
not the plain dicts a CEL render produces. The normalizer drops them, keeping
`content: None` since that is a valid message shape.

Declarative crews are unaffected: they use `CrewAgentDefinition`, which has no
`input` field at all.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* test(flows): pin content=None survival through agent input normalization

A filter-all-None change would silently drop the assistant turn that only
requests tool calls, and no test covered that key.

Found by CodeRabbit on #7066.

* test(flows): cover the agent action through kickoff, not the helper

The existing tests called _normalize_agent_input directly, so nothing pinned
that Expression.render_template -> normalization -> Agent.kickoff_async keeps a
message list intact. Removing the normalization call now fails this test.

Found by CodeRabbit on #7066.

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Lorenze Jay <63378463+lorenzejay@users.noreply.github.com>
2026-08-24 21:09:36 +00:00
Lorenze Jay
6c19669d63 refactor: update date injection functionality in agents (#6850)
* refactor: update date injection functionality in agents

- Changed the description of the  parameter to clarify that it injects the current date into the agent's prompt instead of tasks.
- Removed the  method as it was no longer needed.
- Implemented a new  method in the  class to handle date injection directly into the prompt.
- Updated tests to ensure the date is correctly injected into the system prompt and user messages based on the  flag.

* translations

* nit
2026-08-11 14:36:47 -03:00
João Moura
cc0759854d fix(skills): resolve registry skills through the runtime's CrewAI+ client (#6658)
* fix(skills): resolve registry skills through the installed AMP client

Skill downloads built their own `PlusAPI` and authenticated it from
`CREWAI_USER_PAT`, the platform integration token, or the saved CLI login.
Managed runtimes have no user credential to offer: they install a client of
their own, which `load_agent_from_repository` already resolves through, so
Agent Repository lookups worked while the skill downloads beside them failed
with 401.

Skills now resolve their client the same way, via `resolve_plus_client()` next
to the hook it reads. A client that can't fetch skills falls back to
environment credentials and warns, so older runtimes behave as they do today.
`resolve_plus_response()` shares the sync/async bridging both lookups need,
since `PlusAPI` is synchronous while managed clients are not.

Version pinning, which the same bug was hiding:

- Registry refs accept `@org/name@version`, and `@org/name@v1.2.0` since people
  write it both ways. `parse_skill_ref()` returns a `SkillRef(org, name,
  version)`; `parse_registry_ref()` keeps its `(org, name)` shape and drops the
  pin, so existing callers are unaffected
- Agent Repository agents record a version per skill, which was parsed off the
  response and dropped. Those pins now travel with the refs, so publishing a
  new version of a skill no longer changes every agent that uses it
- A pinned ref only accepts a project-local copy declaring that version in its
  `metadata.version` frontmatter, and the cache reports a miss when the version
  it recorded differs — so a pin re-resolves rather than loading another
  version. Unpinned refs keep hitting the cache as before
- An unknown pin fails instead of quietly falling back to the newest version

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(skills): reject a blank version pin instead of floating to latest

A blank `version` passed to `download_skill` read as "unpinned" and quietly
resolved the latest version, which is not what a caller supplying one asked
for — and it disagreed with `parse_skill_ref`, which already rejects empty
pins. Not reachable through `resolve_registry_ref` or the Agent Repository
auto-pinning, both of which only ever pass a non-empty version.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(skills): carry the caller's context into the worker thread

When resolve_plus_response bridges an async client from inside a running loop
it runs the coroutine on a worker thread, which starts with empty ContextVars.
A client reading runtime state there — the platform integration token, flow
context — would see defaults rather than the caller's values, which is hard to
diagnose from the resulting auth or routing failure.

Copy the context across, matching how the parallel-summarization bridge in this
module already does it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 13:27:29 -03:00
Vinicius Brasil
4e23bf6d45 Update dependencies with security fixes (#6580)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (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
* Pillow 12.1.1 → 12.3.0 (CVE-2026-55798, CVE-2026-54059, CVE-2026-54060,
  CVE-2026-55379, CVE-2026-55380, CVE-2026-59197, CVE-2026-59203)
* mcp 1.26.0 → 1.28.1 (CVE-2026-59950)
* couchbase 4.3.5 → 4.6.0
2026-07-17 09:12:45 -03:00
Vinicius Brasil
985cf52028 Fix null repository agent attributes (#6560)
Repository responses can include null optional fields such as
`reasoning`. Treat them as omitted so Agent defaults apply instead of
failing validation.
2026-07-16 10:13:45 -03:00
João Moura
a8b3ecb723 fix(agent): report per-call usage metrics on kickoff results (#6506)
* fix(agent): report per-call usage metrics on kickoff results

Agent.kickoff() populated result.usage_metrics from the LLM instance's
lifetime token accumulator, so counts grew across calls and pooled
across agents sharing one LLM object — a second agent's first turn
appeared to cost the whole preceding session.

Snapshot the accumulator when a kickoff starts and report the delta on
the result (guardrail retries included), via the new
UsageMetrics.delta_since(). The LLM instance's cumulative counters are
untouched: get_token_usage_summary() keeps lifetime totals for
crew-level aggregation, and its docstring now states that scope
explicitly. Applies to both Agent and the deprecated LiteAgent, sync
and async paths.

Fixes EPD-177.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor(agent): drop lite_agent.py diff, add guardrail-retry usage test

Per review: LiteAgent's kickoff path is no longer used, so the per-call
usage snapshot only needs to live in agent/core.py — revert the
lite_agent.py changes entirely. This also removes the duplicated
_current_usage_summary helper and the instance-attr baseline CodeRabbit
flagged.

Add the requested guardrail-retry regression test: a guardrail that
rejects the first attempt and accepts the second must yield
usage_metrics covering both attempts (2x a single-attempt kickoff).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 14:17:45 -07:00
Lorenze Jay
e55e710df0 Implement message setup and feedback handling in AgentExecutor (#6465)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Nightly Canary Release / Check for new commits (push) Has been cancelled
Nightly Canary Release / Build nightly packages (push) Has been cancelled
Nightly Canary Release / Publish nightly to PyPI (push) Has been cancelled
* Implement message setup and feedback handling in AgentExecutor

- Added  method to streamline message preparation for agent execution, allowing for integration with human input providers.
- Introduced  and  methods to manage the state during feedback processing.
- Enhanced  and  methods to re-run the executor flow using existing feedback messages.
- Updated tests to verify the new message setup and feedback handling functionality, ensuring compatibility with human input providers.

* dont commit runner

* Remove xfail marker from test_crew_train_success as training feedback migration to AgentExecutor is complete.

* fix runtype errors

* fix test

* revert

* mypy fix

* handled reset iterations
2026-07-06 15:28:37 -07:00
Vinicius Brasil
2b90117e88 Add repository agents to flow definitions (#6437)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Nightly Canary Release / Check for new commits (push) Has been cancelled
Nightly Canary Release / Build nightly packages (push) Has been cancelled
Nightly Canary Release / Publish nightly to PyPI (push) Has been cancelled
Mark stale issues and pull requests / stale (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
Inline agent and crew actions can now use repository-backed agents
without duplicating role, goal, and backstory in each definition.

Examples:
* `agent.with.from_repository: support_specialist`
* `crew.with.agents.researcher.from_repository: researcher`

`PlusAPI.get_agent` now uses the shared synchronous request path so
project loaders can fetch repository agents without nested event loops.
2026-07-02 14:28:01 -07:00
Vinicius Brasil
340d23ae5d Remove StateProxy from flow state access (#6327)
`StateProxy` looked like a thread-safety boundary, but it only protected
a small slice of state operations. Some examples of operations that were
not covered:

- `self.state.counter += 1`, `self.state["counter"] += 1` (increments)
- `self.state.user.profile.score += 1` (nested object mutations)
- `self.state.config["limits"]["max"] = 10` (mutation through model fields)
- `self.state.items[0].status = "done"` (list/container mutations)

This commit decided to remove it completely for simplicity and
performance:

- Simpler runtime code
- attr read: 24x faster, attr write: 27x faster, list append: 19x faster (local benchmark)
- Clearer concurrency contract (lifecycle locks remain, but arbitrary
  shared state mutation is not presented as thread-safe)
2026-06-24 16:37:51 -07:00
Vinicius Brasil
9db2d44766 Add typed output schemas for CrewAI tools (#6236)
Some checks failed
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
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 / pip-audit (push) Has been cancelled
Nightly Canary Release / Check for new commits (push) Has been cancelled
Nightly Canary Release / Build nightly packages (push) Has been cancelled
Nightly Canary Release / Publish nightly to PyPI (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
Currently, tools have a strong input contract through `args_schema`, but no
output contract. This means that anything a tool outputs is converted to
string.

Not only the contract is weak, but the "invisible" conversion to string can
have unexpected effects when the tool returns complex objects like dicts and
arrays.

With this PR, a tool can _optionally_ define an output contract with
`output_schema`. CrewAI validates the raw result and sends the agent JSON.

```python
class ProductResult(BaseModel):
    sku: str
    name: str
    in_stock: bool

class ProductLookupTool(BaseTool):
    name: str = "Product Lookup"
    description: str = "Look up product availability by SKU."

    def _run(self, sku: str) -> ProductResult:
        return ProductResult(sku=sku, name="USB-C dock", in_stock=True)
```

If the result does not match the schema, CrewAI warns and falls back to
`str(raw_result)` instead of failing the run:

```python
@tool("Product Lookup", output_schema=ProductResult)
def product_lookup(sku: str) -> dict[str, object]:
    return {"sku": sku, "name": "USB-C dock", "in_stock": True}

#=> RuntimeWarning: Failed to validate or serialize output from tool 'Bad Product Lookup' using output_schema 'ProductResult'... Falling back to str(raw_result).
```

This is additive and non-breaking. Existing tools do not need to change. Tools
without `output_schema` keep the old string behavior. Invalid typed outputs
warn and fall back to the old formatting path.
2026-06-19 14:33:51 -07:00
João Moura
bb477f8a91 JSON first crews (#6131)
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 / pip-audit (push) Has been cancelled
Nightly Canary Release / Check for new commits (push) Has been cancelled
Nightly Canary Release / Build nightly packages (push) Has been cancelled
Nightly Canary Release / Publish nightly to PyPI (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
* feat(cli): introduce JSON crew project support and TUI enhancements

- Added support for creating and running JSON-defined crew projects, allowing users to scaffold projects with a new `create_json_crew.py` file.
- Implemented a full-screen Textual TUI for crew execution in `crew_run_tui.py`, enhancing user interaction with a two-column layout.
- Updated `run_crew.py` to prioritize JSON crew projects and added daemon mode for running without TUI.
- Introduced interactive pickers in `tui_picker.py` for improved CLI prompts.
- Enhanced validation for JSON crew files in `validate.py` to ensure proper structure and agent definitions.
- Updated `.gitignore` to exclude demo and crewai directories.

* feat: update LLM model references to gpt-5.4-mini

- Changed default LLM model from gpt-4o-mini to gpt-5.4-mini across various files, including CLI options, JSON crew configurations, and agent definitions.
- Enhanced benchmark and human feedback functionalities to utilize the new model.
- Improved user interface elements in the TUI for better interaction and feedback during execution.
- Added support for new skills directory in JSON crew project creation.

* feat(benchmark): add crew-level benchmarking functionality

- Introduced a new `benchmark` command in the CLI for crew-level benchmarking, allowing users to specify agents, models, and timeout settings.
- Implemented `CrewBenchmarkCase` to handle crew-level benchmark cases with inputs and criteria.
- Enhanced the benchmark runner to support progress tracking and detailed reporting of results for multiple models.
- Added tests for loading crew benchmark cases and validating their structure.
- Updated existing benchmark functions to accommodate the new crew-level execution model.

* feat(cli): enhance JSON crew project functionality and TUI improvements

- Added optional agent-level guardrails and advanced options in JSON crew configurations to improve output validation and flexibility.
- Updated the TUI to better handle plan step statuses, including visual indicators for task completion and failure.
- Introduced methods for parsing and managing step observation events, ensuring accurate updates to task statuses during execution.
- Enhanced validation for JSON crew projects, ensuring proper structure and error handling for agent and task definitions.
- Added comprehensive tests for new features and validation logic, ensuring robustness in JSON crew project handling.

* refactor(cli): streamline JSON crew project handling and improve validation

- Refactored JSON crew project loading and validation logic to enhance clarity and maintainability.
- Introduced utility functions for finding JSON crew files, improving code reuse across modules.
- Removed deprecated benchmark functionality and associated tests to simplify the codebase.
- Updated CLI commands to utilize the new JSON project structure, ensuring compatibility with recent changes.
- Enhanced test coverage for JSON crew project features, ensuring robust validation and error handling.

* feat(cli): enhance activity log navigation and focus management

- Added functionality to focus on the activity log when navigating through log entries.
- Implemented refresh logic for the log panel to ensure updates are displayed correctly during navigation.
- Improved keyboard navigation for log entries, allowing users to expand and scroll through logs seamlessly.
- Added tests to verify the correct behavior of log navigation and focus management in the TUI.

* feat(cli): enhance JSON crew project interaction and input handling

- Introduced a new function to enable prompt line editing for better user experience during input prompts.
- Updated the JSON crew project wizards to show interpolation hints for dynamic values, improving user guidance.
- Enhanced the handling of missing input placeholders by prompting users for required values during crew setup.
- Refactored the crew run logic to ensure proper loading and preparation of JSON-defined crews, including runtime input management.
- Added tests to verify the correct behavior of new input handling features and JSON crew project interactions.

* feat(cli): improve crew project input prompts and event handling

- Enhanced the `_prompt_text` function to allow for configurable spacing before prompts, improving user experience during input collection.
- Updated the wizards for agent and task creation to utilize the new prompt configuration, ensuring a more compact and streamlined interaction.
- Introduced new plan step lifecycle events (`PlanStepStartedEvent`, `PlanStepCompletedEvent`) to better track the execution status of plan steps.
- Refactored the step executor to emit these events during the execution of tasks, improving observability and debugging capabilities.
- Added tests to verify the correct behavior of new prompt handling and event emissions during crew project execution.

* fix: refine json-first crew interactions

* fix: prioritize common json crew tools

* fix: make json crew more tools expandable

* fix: show json crew tools by category

* feat(memory): update default embedder to OpenAI text-embedding-3-large and enhance memory compatibility

- Changed the default embedding model for Memory to OpenAI text-embedding-3-large, which uses 3072-dimensional vectors.
- Added warnings regarding compatibility issues with existing local memory stores created with 1536-dimensional embeddings.
- Updated documentation to reflect the new default embedder and its configuration options.
- Enhanced the CLI and codebase to support the new embedding model across various components, ensuring a seamless transition for users.

* fix: address PR review feedback for JSON-first crews

Review blockers:
- Forward trained_agents_file to JSON crews: crewai run -f now exports
  CREWAI_TRAINED_AGENTS_FILE for the in-process JSON crew path
- Wizard agent picker: Esc/cancel now reprompts instead of silently
  assigning the first agent
- JSON tool resolution hard-fails: unknown tool names, missing custom
  tool files, and invalid custom tool modules raise JSONProjectError
  with actionable messages instead of warn-and-continue
- Embedding dimension mismatch: LanceDB and Qdrant Edge storages raise
  EmbeddingDimensionMismatchError with reset/pin guidance instead of
  silently zero-filling vectors or returning empty search results
- Custom tool code execution documented in loader docstring and the
  scaffolded project README

CI fixes:
- ruff format across lib/
- All 133 PR-introduced mypy errors fixed (llm.py lazy-litellm and
  cli.py lazy command shims now use TYPE_CHECKING imports; textual
  is_mounted misuse fixed; pick_many overloads; misc annotations)

Bot review comments:
- Empty except blocks now have explanatory comments or debug logging
- Removed unused _C_BG/_C_PANEL/_C_BORDER globals and redundant
  import re; tests use a single import style for create_json_crew

Tests: trained-agents propagation, wizard cancel, tool resolution
failures, and dimension mismatch guidance.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: address second round of PR review comments

Cursor Bugbot:
- Wizard agent slugs: strip to [a-z0-9_] and fall back to agent_<n> so
  symbol-only roles can't produce an empty agents/.jsonc filename
- Wizard task names: dedupe against prior task names and fall back to
  task_<n> for symbol-only descriptions

CodeRabbit:
- Agent.message(): import Task explicitly at runtime instead of relying
  on the namespace injection done by crewai/__init__
- Async executor: move the native-tools-unsupported fallback from
  _ainvoke_loop_react (self-recursion) to _ainvoke_loop_native_tools,
  mirroring the sync implementation
- StepExecutor downgrade: keep the in-step conversation and append the
  text-tooling instructions instead of rebuilding messages, so completed
  native tool calls are not re-executed
- crewai-files: extension-based MIME lookup now runs before byte
  sniffing so csv/xml types are not degraded to text/plain
- Memory storages: validate every record in a save() batch against a
  consistent embedding dimension (LanceDB previously checked only the
  first record); added mixed-batch tests
- _print_post_tui_summary now typed against CrewRunApp
- Docs: Azure OpenAI default embedder change called out in the memory
  migration warning and provider table

Code quality bots:
- Removed unused _C_YELLOW/_C_CYAN (crew_run_tui) and _GREEN (tui_picker)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(cli): accordion tool picker in JSON crew wizard

The flat tool list had grown to ~90 rows. The picker now shows:
- Common tools always visible at the top
- Every other category as a single expandable row with tool and
  selection counts (e.g. "Search & Research  (27 tools, 2 selected)")
- Expanding a category collapses the previously expanded one
- Selections persist across expand/collapse via new preselected
  support in pick_many; cursor follows the toggled category row

tui_picker gains preselected + initial_cursor options on pick_many,
and Esc in multi-select now confirms the current selection instead of
discarding it (required so collapsing can't silently drop choices).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor(cli): remove --daemon flag from crewai run

The flag only affected JSON crew projects — classic and flow projects
ignored it entirely, which made the behavior inconsistent. Removed the
option, the daemon code path (_run_json_crew_daemon), and its helper
(_load_json_crew_with_inputs).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test: update run command tests after --daemon removal

lib/crewai/tests/cli/test_run_crew.py still asserted the old
run_crew(trained_agents_file=..., daemon=False) call signature.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(cli): exit codes, mid-run quit, async statuses, hyphen placeholders

Addresses the latest Bugbot review round:

- Failed JSON crew runs now exit non-zero (SystemExit(1)) so scripts
  and CI don't treat failures as success, mirroring the classic path
- Quitting the TUI mid-run now ends the process (os._exit(130));
  kickoff runs in a thread worker that cannot be force-cancelled, so
  letting the CLI return would leave LLM/tool work burning tokens in
  the background
- Sidebar task statuses are now async-safe: completion/failure events
  resolve the task's own row via identity instead of assuming the most
  recently started task, and starting a task no longer blanket-marks
  earlier active rows as done
- The runtime-input prompt regex now accepts hyphenated placeholder
  names ({my-topic}), matching kickoff's interpolation pattern

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: validation safety, custom tool sandboxing, TUI log integrity, memory error surfacing

- Deploy validation no longer executes project code: validation mode
  checks tool declarations structurally (well-formed entries, custom
  tool file exists) without importing or instantiating anything.
  custom:<name> resolution only happens on the actual run path.
- custom:<name> is constrained to [A-Za-z_][A-Za-z0-9_]* and the
  resolved path must stay inside the project's tools/ directory, so
  custom:../foo or absolute-path names cannot execute code outside it.
  Tool paths resolve relative to the crew project root, not cwd.
- TUI task logs are built from per-task state captured at task start
  (idx, description, agent, start time); an out-of-order completion
  takes its output from the event and no longer steals or resets the
  current task's streamed steps/output.
- EmbeddingDimensionMismatchError now inherits ValueError instead of
  RuntimeError so background saves surface it through
  MemorySaveFailedEvent instead of silently dropping the save; the
  shutdown catch in _background_encode_batch is narrowed to the
  "cannot schedule new futures" case.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(cli): declared project type wins over crew.json presence

A flow project that also contains a crew.json(c) file now runs and
validates as the flow it declares in pyproject.toml instead of being
hijacked by the JSON crew path. Both crewai run (_has_json_crew) and
deploy validation (_is_json_crew) check tool.crewai.type; a missing or
unreadable pyproject still means a bare JSON crew project.

Also documents why StepObservationFailedEvent intentionally marks the
plan step "done": the event signals an observer failure, not a step
failure, and the executor continues past it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(cli): type the declared_type locals so mypy stays clean

Comparing an Any-typed .get() chain returns Any, which tripped
no-any-return on the previous commit.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-06-14 04:19:48 -03:00
Lorenze Jay
036b032ab6 handle supporting both custom prompts (#6108)
* handle supporting both custom prompts

* handle translations

* handle deprecation warnings better
2026-06-10 17:52:53 -07:00
Vini Brasil
a9e7c3a44f Simplify flow condition evaluation to be stateless per event (#6097)
Re-evaluate the whole `@listen`/`@router` condition tree against the set
of events seen so far, instead of tracking which AND sub-branches remain
pending.

Net effect:
* Fixes a regression where `or_()` short-circuited at the first
  satisfied branch, leaving a sibling `and_()` half-complete so a later
  trigger could spuriously re-fire the listener
* Removes the fragile per-branch pending state and `id()`-based keys
* Shrinks the evaluator to one readable predicate
2026-06-10 10:35:25 -07:00
Lorenze Jay
770d1b284f Lorenze/fix/file input not working reliably (#6020)
* fix filesystem

* Refine commit message formatting

* fix for async kickoffs

* added suggestion
2026-06-02 17:14:51 -07:00
Lorenze Jay
a9cb7867bb Add crew trained agents file support (#6012)
* Add crew trained agents file support

* Add crew trained agents file support
2026-06-02 09:38:34 -07:00
Lorenze Jay
a1033e4bfe Fix structured output leaks in tool-calling loops (#5897)
* Fix structured output leaks in tool-calling loops

* addressing comments

* drop scripts

* Update Gemini agent tests to include structured output with thoughts and bump model version to 2.5-flash

* merge

* Update Anthropic test cases to use new model and tool structure

- Changed the model from "claude-3-5-haiku-20241022" to "claude-sonnet-4-6" in the test setup.
- Updated the request and response formats in the YAML test cassette to reflect the new tool structure and improved content formatting.
- Adjusted the expected response body to match the new output format from the assistant, including changes in tool usage and response details.
- Increased rate limit values in the response headers for better testing scenarios.

* adjusted bedrock cassettes

* adjusting cassettes for bedrock

* fix test

* Update VCR configuration to use 'host' instead of 'bedrock_host' for request matching
2026-05-27 13:20:53 -07:00
Greyson LaLonde
fd10c64148 chore(crewai): drop self-explanatory comments 2026-05-26 10:23:33 -07:00
Lorenze Jay
77a61274dc feat(planning): enhance planning configuration and observation handling (#5913)
* feat(planning): enhance planning configuration and observation handling

- Introduced  attribute in  to control LLM calls after each step.
- Updated  to set default  to 1 when planning is enabled without explicit config.
- Modified  to support heuristic observations when LLM calls are disabled.
- Adjusted  to respect  and  settings for step observations.
- Added tests to verify behavior of new configurations and ensure correct observation handling across different reasoning efforts.

* fix(agent_executor): update handling of failed steps in low effort mode

- Adjusted logic to ensure that failed steps are recorded without marking them as completed when using low reasoning effort.

- Introduced feedback for failed steps, allowing the process to continue while tracking failures.
- Added a test to verify that failed steps are correctly marked without triggering a replan.

- And linted

* linted
2026-05-26 09:10:43 -07:00
Vini Brasil
32f5e74449 Skip lock acquisition in CrewTrainingHandler.load when file is missing (#5935)
Every agent kickoff calls _use_trained_data, which calls
CrewTrainingHandler(...).load(). Since #4827 wrapped load() in store_lock,
that means every kickoff acquires the cross-process (Redis-backed when
REDIS_URL is set) lock even on deployments that never train and have no
trained-agents file on disk.

Move the missing/empty-file short-circuit above store_lock so the lock is
only acquired when there is actually a file to read. save() and the real
read remain locked.
2026-05-26 12:52:31 -03:00
iris-clawd
3322634625 feat: deprecate CrewAgentExecutor, default Crew agents to AgentExecutor (#5745)
* feat: deprecate CrewAgentExecutor, default Crew agents to AgentExecutor

* regen cassettes

* fix tests

* addressing pr comments

---------

Co-authored-by: Lorenze Jay <63378463+lorenzejay@users.noreply.github.com>
Co-authored-by: lorenzejay <lorenzejaytech@gmail.com>
Co-authored-by: Greyson LaLonde <greyson.r.lalonde@gmail.com>
2026-05-12 11:22:13 -07:00
Greyson LaLonde
93e786d263 refactor: extract CLI into standalone crewai-cli package 2026-05-06 20:46:46 +08:00
Greyson LaLonde
184c228ae9 fix: prevent shared LLM stop words mutation across agents
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
2026-05-04 14:23:17 +08:00
Greyson LaLonde
4c74dc0f86 fix(executor): reset messages and iterations between invocations
CrewAgentExecutor is reused across sequential tasks but invoke/ainvoke
only appended to self.messages and never reset self.iterations, so
task 2 inherited task 1's history and iteration count.
2026-04-29 02:10:17 +08:00
Greyson LaLonde
4e9331a2c8 fix(agent): honor custom trained-agents file at inference 2026-04-28 22:09:34 +08:00
Greyson LaLonde
8e2a529d94 chore: add deprecation decorator to LiteAgent 2026-04-14 00:51:11 +08:00
Greyson LaLonde
0e590ff669 refactor: use shared I18N_DEFAULT singleton 2026-04-09 04:29:53 +08:00
Greyson LaLonde
0450d06a65 refactor: use shared PRINTER singleton
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Nightly Canary Release / Check for new commits (push) Has been cancelled
Nightly Canary Release / Build nightly packages (push) Has been cancelled
Nightly Canary Release / Publish nightly to PyPI (push) Has been cancelled
2026-04-08 07:17:22 +08:00
Greyson LaLonde
86ce54fc82 feat: runtime state checkpointing, event system, and executor refactor
- 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
2026-04-07 03:22:30 +08:00
Lucas Gomide
1b7be63b60 Revert "refactor: remove unused and methods from (#5172)" (#5243)
* Revert "refactor: remove unused  and  methods from (#5172)"

This reverts commit bb9bcd6823.

* test: fix tests
2026-04-02 18:02:59 -04:00
Greyson LaLonde
d6714a0e60 refactor: convert Flow to Pydantic BaseModel 2026-04-01 03:48:41 +08:00
Greyson LaLonde
dfc0f9a317 refactor: replace InstanceOf[T] with plain type annotations
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
* refactor: replace InstanceOf[T] with plain type annotations

InstanceOf[] is a Pydantic validation wrapper that adds runtime
isinstance checks. Plain type annotations are sufficient here since
the models already use arbitrary_types_allowed or the types are
BaseModel subclasses.

* refactor: convert BaseKnowledgeStorage to BaseModel

* fix: update tests for BaseKnowledgeStorage BaseModel conversion

* fix: correct embedder config structure in test
2026-03-31 08:11:21 +08:00
Lorenze Jay
bb9bcd6823 refactor: remove unused and methods from (#5172)
This commit cleans up the  class by removing the  and  methods, which are no longer needed. The changes help streamline the code and improve maintainability.
2026-03-30 15:01:58 -07:00
Greyson LaLonde
a49f9f982b refactor: deduplicate sync/async task execution and kickoff in agent 2026-03-25 19:39:42 +08:00
Greyson LaLonde
ec8d444cfc fix: resolve all mypy errors across crewai package 2026-03-25 06:03:43 +08:00
Greyson LaLonde
6495aff528 refactor: replace Any-typed callback and model fields with serializable types 2026-03-20 15:18:50 -04:00
Lorenze Jay
32d7b4a8d4 Lorenze/feat/plan execute pattern (#4817)
* feat: introduce PlanningConfig for enhanced agent planning capabilities (#4344)

* feat: introduce PlanningConfig for enhanced agent planning capabilities

This update adds a new PlanningConfig class to manage agent planning configurations, allowing for customizable planning behavior before task execution. The existing reasoning parameter is deprecated in favor of this new configuration, ensuring backward compatibility while enhancing the planning process. Additionally, the Agent class has been updated to utilize this new configuration, and relevant utility functions have been adjusted accordingly. Tests have been added to validate the new planning functionality and ensure proper integration with existing agent workflows.

* dropping redundancy

* fix test

* revert handle_reasoning here

* refactor: update reasoning handling in Agent class

This commit modifies the Agent class to conditionally call the handle_reasoning function based on the executor class being used. The legacy CrewAgentExecutor will continue to utilize handle_reasoning, while the new AgentExecutor will manage planning internally. Additionally, the PlanningConfig class has been referenced in the documentation to clarify its role in enabling or disabling planning. Tests have been updated to reflect these changes and ensure proper functionality.

* improve planning prompts

* matching

* refactor: remove default enabled flag from PlanningConfig in Agent class

* more cassettes

* fix test

* refactor: update planning prompt and remove deprecated methods in reasoning handler

* improve planning prompt

* Lorenze/feat planning pt 2 todo list gen (#4449)

* feat: introduce PlanningConfig for enhanced agent planning capabilities

This update adds a new PlanningConfig class to manage agent planning configurations, allowing for customizable planning behavior before task execution. The existing reasoning parameter is deprecated in favor of this new configuration, ensuring backward compatibility while enhancing the planning process. Additionally, the Agent class has been updated to utilize this new configuration, and relevant utility functions have been adjusted accordingly. Tests have been added to validate the new planning functionality and ensure proper integration with existing agent workflows.

* dropping redundancy

* fix test

* revert handle_reasoning here

* refactor: update reasoning handling in Agent class

This commit modifies the Agent class to conditionally call the handle_reasoning function based on the executor class being used. The legacy CrewAgentExecutor will continue to utilize handle_reasoning, while the new AgentExecutor will manage planning internally. Additionally, the PlanningConfig class has been referenced in the documentation to clarify its role in enabling or disabling planning. Tests have been updated to reflect these changes and ensure proper functionality.

* improve planning prompts

* matching

* refactor: remove default enabled flag from PlanningConfig in Agent class

* more cassettes

* fix test

* feat: enhance agent planning with structured todo management

This commit introduces a new planning system within the AgentExecutor class, allowing for the creation of structured todo items from planning steps. The TodoList and TodoItem models have been added to facilitate tracking of plan execution. The reasoning plan now includes a list of steps, improving the clarity and organization of agent tasks. Additionally, tests have been added to validate the new planning functionality and ensure proper integration with existing workflows.

* refactor: update planning prompt and remove deprecated methods in reasoning handler

* improve planning prompt

* improve handler

* linted

* linted

* Lorenze/feat/planning pt 3 todo list execution (#4450)

* feat: introduce PlanningConfig for enhanced agent planning capabilities

This update adds a new PlanningConfig class to manage agent planning configurations, allowing for customizable planning behavior before task execution. The existing reasoning parameter is deprecated in favor of this new configuration, ensuring backward compatibility while enhancing the planning process. Additionally, the Agent class has been updated to utilize this new configuration, and relevant utility functions have been adjusted accordingly. Tests have been added to validate the new planning functionality and ensure proper integration with existing agent workflows.

* dropping redundancy

* fix test

* revert handle_reasoning here

* refactor: update reasoning handling in Agent class

This commit modifies the Agent class to conditionally call the handle_reasoning function based on the executor class being used. The legacy CrewAgentExecutor will continue to utilize handle_reasoning, while the new AgentExecutor will manage planning internally. Additionally, the PlanningConfig class has been referenced in the documentation to clarify its role in enabling or disabling planning. Tests have been updated to reflect these changes and ensure proper functionality.

* improve planning prompts

* matching

* refactor: remove default enabled flag from PlanningConfig in Agent class

* more cassettes

* fix test

* feat: enhance agent planning with structured todo management

This commit introduces a new planning system within the AgentExecutor class, allowing for the creation of structured todo items from planning steps. The TodoList and TodoItem models have been added to facilitate tracking of plan execution. The reasoning plan now includes a list of steps, improving the clarity and organization of agent tasks. Additionally, tests have been added to validate the new planning functionality and ensure proper integration with existing workflows.

* refactor: update planning prompt and remove deprecated methods in reasoning handler

* improve planning prompt

* improve handler

* execute todos and be able to track them

* feat: introduce PlannerObserver and StepExecutor for enhanced plan execution

This commit adds the PlannerObserver and StepExecutor classes to the CrewAI framework, implementing the observation phase of the Plan-and-Execute architecture. The PlannerObserver analyzes step execution results, determines plan validity, and suggests refinements, while the StepExecutor executes individual todo items in isolation. These additions improve the overall planning and execution process, allowing for more dynamic and responsive agent behavior. Additionally, new observation events have been defined to facilitate monitoring and logging of the planning process.

* refactor: enhance final answer synthesis in AgentExecutor

This commit improves the synthesis of final answers in the AgentExecutor class by implementing a more coherent approach to combining results from multiple todo items. The method now utilizes a single LLM call to generate a polished response, falling back to concatenation if the synthesis fails. Additionally, the test cases have been updated to reflect the changes in planning and execution, ensuring that the results are properly validated and that the plan-and-execute architecture is functioning as intended.

* refactor: enhance final answer synthesis in AgentExecutor

This commit improves the synthesis of final answers in the AgentExecutor class by implementing a more coherent approach to combining results from multiple todo items. The method now utilizes a single LLM call to generate a polished response, falling back to concatenation if the synthesis fails. Additionally, the test cases have been updated to reflect the changes in planning and execution, ensuring that the results are properly validated and that the plan-and-execute architecture is functioning as intended.

* refactor: implement structured output handling in final answer synthesis

This commit enhances the final answer synthesis process in the AgentExecutor class by introducing support for structured outputs when a response model is specified. The synthesis method now utilizes the response model to produce outputs that conform to the expected schema, while still falling back to concatenation in case of synthesis failures. This change ensures that intermediate steps yield free-text results, but the final output can be structured, improving the overall coherence and usability of the synthesized answers.

* regen tests

* linted

* fix

* Enhance PlanningConfig and AgentExecutor with Reasoning Effort Levels

This update introduces a new  attribute in the  class, allowing users to customize the observation and replanning behavior during task execution. The  class has been modified to utilize this new attribute, routing step observations based on the specified reasoning effort level: low, medium, or high.

Additionally, tests have been added to validate the functionality of the reasoning effort levels, ensuring that the agent behaves as expected under different configurations. This enhancement improves the adaptability and efficiency of the planning process in agent execution.

* regen cassettes for test and fix test

* cassette regen

* fixing tests

* dry

* Refactor PlannerObserver and StepExecutor to Utilize I18N for Prompts

This update enhances the PlannerObserver and StepExecutor classes by integrating the I18N utility for managing prompts and messages. The system and user prompts are now retrieved from the I18N module, allowing for better localization and maintainability. Additionally, the code has been cleaned up to remove hardcoded strings, improving readability and consistency across the planning and execution processes.

* Refactor PlannerObserver and StepExecutor to Utilize I18N for Prompts

This update enhances the PlannerObserver and StepExecutor classes by integrating the I18N utility for managing prompts and messages. The system and user prompts are now retrieved from the I18N module, allowing for better localization and maintainability. Additionally, the code has been cleaned up to remove hardcoded strings, improving readability and consistency across the planning and execution processes.

* consolidate agent logic

* fix datetime

* improving step executor

* refactor: streamline observation and refinement process in PlannerObserver

- Updated the PlannerObserver to apply structured refinements directly from observations without requiring a second LLM call.
- Renamed  method to  for clarity.
- Enhanced documentation to reflect changes in how refinements are handled.
- Removed unnecessary LLM message building and parsing logic, simplifying the refinement process.
- Updated event emissions to include summaries of refinements instead of raw data.

* enhance step executor with tool usage events and validation

- Added event emissions for tool usage, including started and finished events, to track tool execution.
- Implemented validation to ensure expected tools are called during step execution, raising errors when not.
- Refactored the  method to handle tool execution with event logging.
- Introduced a new method  for parsing tool input into a structured format.
- Updated tests to cover new functionality and ensure correct behavior of tool usage events.

* refactor: enhance final answer synthesis logic in AgentExecutor

- Updated the finalization process to conditionally skip synthesis when the last todo result is sufficient as a complete answer.
- Introduced a new method to determine if the last todo result can be used directly, improving efficiency.
- Added tests to verify the new behavior, ensuring synthesis is skipped when appropriate and maintained when a response model is set.

* fix: update observation handling in PlannerObserver for LLM errors

- Modified the error handling in the PlannerObserver to default to a conservative replan when an LLM call fails.
- Updated the return values to indicate that the step was not completed successfully and that a full replan is needed.
- Added a new test to verify the behavior of the observer when an LLM error occurs, ensuring the correct replan logic is triggered.

* refactor: enhance planning and execution flow in agents

- Updated the PlannerObserver to accept a kickoff input for standalone task execution, improving flexibility in task handling.
- Refined the step execution process in StepExecutor to support multi-turn action loops, allowing for iterative tool execution and observation.
- Introduced a method to extract relevant task sections from descriptions, ensuring clarity in task requirements.
- Enhanced the AgentExecutor to manage step failures more effectively, triggering replans only when necessary and preserving completed task history.
- Updated translations to reflect changes in planning principles and execution prompts, emphasizing concrete and executable steps.

* refactor: update setup_native_tools to include tool_name_mapping

- Modified the setup_native_tools function to return an additional mapping of tool names.
- Updated StepExecutor and AgentExecutor classes to accommodate the new return value from setup_native_tools.

* fix tests

* linted

* linted

* feat: enhance image block handling in Anthropic provider and update AgentExecutor logic

- Added a method to convert OpenAI-style image_url blocks to Anthropic's required format.
- Updated AgentExecutor to handle cases where no todos are ready, introducing a needs_replan return state.
- Improved fallback answer generation in AgentExecutor to prevent RuntimeErrors when no final output is produced.

* lint

* lint

* 1. Added failed to TodoStatus (planning_types.py)

  - TodoStatus now includes failed as a valid state: Literal[pending, running, completed, failed]
  - Added mark_failed(step_number, result) method to TodoList
  - Added get_failed_todos() method to TodoList
  - Updated is_complete to treat both completed and failed as terminal states
  - Updated replace_pending_todos docstring to mention failed items are preserved

  2. Mark running todos as failed before replan (agent_executor.py)

  All three effort-level handlers now call mark_failed() on the current todo before routing to replan_now:

  - Low effort (handle_step_observed_low): hard-failure branch
  - Medium effort (handle_step_observed_medium): needs_full_replan branch
  - High effort (decide_next_action): both needs_full_replan and step_completed_successfully=False branches

  3. Updated _should_replan to use get_failed_todos()

  Previously filtered on todo.status == failed which was dead code. Now uses the proper accessor method that will actually find failed items.

  What this fixes: Before these changes, a step that triggered a replan would stay in running status permanently, causing is_complete to never
  return True and next_pending to skip it — leading to stuck execution states. Now failed steps are properly tracked, replanning context correctly
  reports them, and LiteAgentOutput.failed_todos will actually return results.

* fix test

* imp on failed states

* adjusted the var name from AgentReActState to AgentExecutorState

* addressed p0 bugs

* more improvements

* linted

* regen cassette

* addressing crictical comments

* ensure configurable timeouts, max_replans and max step iterations

* adjusted tools

* dropping debug statements

* addressed comment

* fix  linter

* lints and test fixes

* fix: default observation parse fallback to failure and clean up plan-execute types

When _parse_observation_response fails all parse attempts, default to
step_completed_successfully=False instead of True to avoid silently
masking failures. Extract duplicate _extract_task_section into a shared
utility in agent_utils. Type PlanningConfig.llm as str | BaseLLM | None
instead of str | Any | None. Make StepResult a frozen dataclass for
immutability consistency with StepExecutionContext.

* fix: remove Any from function_calling_llm union type in step_executor

* fix: make BaseTool usage count thread-safe for parallel step execution

Add _usage_lock and _claim_usage() to BaseTool for atomic
check-and-increment of current_usage_count. This prevents race
conditions when parallel plan steps invoke the same tool concurrently
via execute_todos_parallel. Remove the racy pre-check from
execute_single_native_tool_call since the limit is now enforced
atomically inside tool.run().

---------

Co-authored-by: Greyson LaLonde <greyson.r.lalonde@gmail.com>
Co-authored-by: Greyson LaLonde <greyson@crewai.com>
2026-03-15 18:33:17 -07:00
Lucas Gomide
e72a80be6e Addressing MCP tools resolutions & eliminates all shared mutable connection (#4792)
* fix: allow hyphenated tool names in MCP references like notion#get-page

The _SLUG_RE regex on BaseAgent rejected MCP tool references containing
hyphens (e.g. "notion#get-page") because the fragment pattern only
matched \w (word chars)

* fix: create fresh MCP client per tool invocation to prevent parallel call races

When the LLM dispatches parallel calls to MCP tools on the same server, the executor runs them concurrently via ThreadPoolExecutor. Previously, all tools from a server shared a single MCPClient instance, and even the same tool called twice would reuse one client. Since each thread creates its own asyncio event loop via asyncio.run(), concurrent connect/disconnect calls on the shared client caused anyio cancel-scope errors ("Attempted to exit cancel scope in a different task than it was entered in").

The fix introduces a client_factory pattern: MCPNativeTool now receives a zero-arg callable that produces a fresh MCPClient + transport on every
_run_async() invocation. This eliminates all shared mutable connection state between concurrent calls, whether to the same tool or different tools from the same server.

* test: ensure we can filter hyphenated MCP tool
2026-03-10 14:00:40 -04:00
Greyson LaLonde
cd42bcf035 refactor(memory): convert memory classes to serializable
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Nightly Canary Release / Check for new commits (push) Has been cancelled
Nightly Canary Release / Build nightly packages (push) Has been cancelled
Nightly Canary Release / Publish nightly to PyPI (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
* refactor(memory): convert Memory, MemoryScope, and MemorySlice to BaseModel

* fix(test): update mock memory attribute from _read_only to read_only

* fix: handle re-validation in wrap validators and patch BaseModel class in tests
2026-03-08 23:08:10 -04:00
Greyson LaLonde
ea70976a5d fix: adjust executor listener value to avoid recursion (#4705)
* fix: adjust executor listener value to avoid recursion

* fix: clear call count to ensure zero state

* feat: expose max method call kwarg
2026-03-04 10:47:22 -08:00
Greyson LaLonde
1ac5801578 fix: inject tool errors as observations and resolve name collisions
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
2026-03-01 00:46:04 -05:00
Lucas Gomide
d259150d8d Enhance MCP tool resolution and related events (#4580)
* feat: enhance MCP tool resolution

* feat: emit event when MCP configuration fails

* feat: emit event when MCP tool execution has failed

* style: resolve linter issues

* refactor: use clear and natural mcp tool name resolution

* test: fix broken tests

* fix: resolve MCP connection leaks, slug validation, duplicate connections, and httpx exception handling

---------

Co-authored-by: Greyson LaLonde <greyson.r.lalonde@gmail.com>
Co-authored-by: Greyson LaLonde <greyson@crewai.com>
2026-02-26 13:59:30 -08:00
João Moura
86d3ee022d feat: update lancedb version and add lance-namespace packages
* chore(deps): update lancedb version and add lance-namespace packages

- Updated lancedb dependency version from 0.4.0 to 0.29.2 in multiple files.
- Added new packages: lance-namespace and lance-namespace-urllib3-client with version 0.5.2, including their dependencies and installation details.
- Enhanced MemoryTUI to display a limit on entries and improved the LanceDBStorage class with automatic background compaction and index creation for better performance.

* linter

* refactor: update memory recall limit and formatting in Agent class

- Reduced the memory recall limit from 10 to 5 in multiple locations within the Agent class.
- Updated the memory formatting to use a new `format` method in the MemoryMatch class for improved readability and metadata inclusion.

* refactor: enhance memory handling with read-only support

- Updated memory-related classes and methods to support read-only functionality, allowing for silent no-ops when attempting to remember data in read-only mode.
- Modified the LiteAgent and CrewAgentExecutorMixin classes to check for read-only status before saving memories.
- Adjusted MemorySlice and Memory classes to reflect changes in behavior when read-only is enabled.
- Updated tests to verify that memory operations behave correctly under read-only conditions.

* test: set mock memory to read-write in unit tests

- Updated unit tests in test_unified_memory.py to set mock_memory._read_only to False, ensuring that memory operations can be tested in a writable state.

* fix test

* fix: preserve falsy metadata values and fix remember() return type

---------

Co-authored-by: lorenzejay <lorenzejaytech@gmail.com>
Co-authored-by: Greyson LaLonde <greyson@crewai.com>
2026-02-26 15:05:10 -05:00
João Moura
8102d0a6ca feat: enhance JSON argument parsing and validation in CrewAgentExecutor and BaseTool
* feat: enhance JSON argument parsing and validation in CrewAgentExecutor and BaseTool

- Added error handling for malformed JSON tool arguments in CrewAgentExecutor, providing descriptive error messages.
- Implemented schema validation for tool arguments in BaseTool, ensuring that invalid arguments raise appropriate exceptions.
- Introduced tests to verify correct behavior for both valid and invalid JSON inputs, enhancing robustness of tool execution.

* refactor: improve argument validation in BaseTool

- Introduced a new private method  to handle argument validation for tools, enhancing code clarity and reusability.
- Updated the  method to utilize the new validation method, ensuring consistent error handling for invalid arguments.
- Enhanced exception handling to specifically catch , providing clearer error messages for tool argument validation failures.

* feat: introduce parse_tool_call_args for improved argument parsing

- Added a new utility function, parse_tool_call_args, to handle parsing of tool call arguments from JSON strings or dictionaries, enhancing error handling for malformed JSON inputs.
- Updated CrewAgentExecutor and AgentExecutor to utilize the new parsing function, streamlining argument validation and improving clarity in error reporting.
- Introduced unit tests for parse_tool_call_args to ensure robust functionality and correct handling of various input scenarios.

* feat: add keyword argument validation in BaseTool and Tool classes

- Introduced a new method `_validate_kwargs` in BaseTool to validate keyword arguments against the defined schema, ensuring proper argument handling.
- Updated the `run` and `arun` methods in both BaseTool and Tool classes to utilize the new validation method, improving error handling and robustness.
- Added comprehensive tests for asynchronous execution in `TestBaseToolArunValidation` to verify correct behavior for valid and invalid keyword arguments.

* Potential fix for pull request finding 'Syntax error'

Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>

---------

Co-authored-by: lorenzejay <lorenzejaytech@gmail.com>
Co-authored-by: Lorenze Jay <63378463+lorenzejay@users.noreply.github.com>
Co-authored-by: Greyson LaLonde <greyson.r.lalonde@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
2026-02-25 13:13:31 -05:00