Commit Graph
949 Commits
Author SHA1 Message Date
Marc BernardinoandLorenze Jay abb82030cb feat(rag): add standard-library jsonl loader (#8144)
* feat(rag): add standard-library jsonl loader

* fix(rag): enforce strict jsonl record validation

* docs(rag): document jsonl loader functions and tests

---------

Co-authored-by: Lorenze Jay <63378463+lorenzejay@users.noreply.github.com>
2026-10-19 14:26:38 -07:00
Vidit Ostwal b1c9279918 fix: store deferred tool results in tmp (#8229)
* fix: store deferred tool results in tmp

* chore: remove tool result artifact diagnostic
2026-10-19 17:43:43 +00:00
Ashh. 2282ab658b Fix JSONLoader escaping non-ASCII text when rendering JSON documents (#8278)
* Preserve non-ASCII characters in JSON loading

Updated json_loader.py to ensure non-ASCII characters are preserved when converting JSON data to text.

* Fix BOM handling in JSON loader tests

* Add tests for JSONLoader with non-ASCII characters

Add tests to verify JSONLoader handles non-ASCII text correctly.

* Preserve lone surrogate escapes in JSONLoader output

Added encoding to keep lone surrogates escaped in JSON output.

* Test JSONLoader scalar Unicode and surrogate handling
2026-10-19 21:41:57 +05:30
João MouraandClaude Opus 5.5 0b84f8e18b fix(core): send AMP requests through the proxy the environment names (#8186)
* fix(core): send AMP requests through the proxy the environment names

PlusAPI built its httpx clients with trust_env=False, so HTTP(S)_PROXY,
NO_PROXY and SSL_CERT_FILE were ignored and every AMP call tried a direct
connection. On a corporate network or inside a coding-agent sandbox
(Claude Code, Codex), which only allow traffic through that proxy, deploy,
eval, org, triggers, trace upload, skills and repository agents all failed
with "[Errno 8] nodename nor servname provided", while `crewai login`
(module-level httpx.post) worked.

trust_env=False dates from #1455, when the client used requests, where it
also stopped ~/.netrc credentials from replacing the AMP bearer token.
httpx 0.28 no longer reads .netrc, so the flag now only disables proxy and
CA-bundle variables. Remove it from the three clients (core request and
multipart, and the CLI's multipart override).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(core): keep the direct-request proxy test off the OS proxy settings

With no proxy variables set, httpx falls back to urllib's getproxies(),
which reads the macOS or Windows system proxy settings. On a machine
with a system proxy configured, the "no proxy variables" test would have
routed through it. Model a machine with none configured.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(cli): keep a project's .env from choosing how crewai eval sends the login

crewai eval already refuses to send the saved login to an AMP host that only
the project's .env names. With AMP requests now honoring proxy and CA
variables, the same .env could still pick the route: its own proxy and its own
CA bundle, past that check. eval and eval --models now leave *_proxy,
SSL_CERT_FILE and SSL_CERT_DIR out when they load the project's .env, say so,
and keep the machine's own settings (shell exports, OS proxy).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(core): take AMP's proxy and CA from the machine, not a project's .env

AMP requests carry the saved login. Honoring HTTP(S)_PROXY and SSL_CERT_FILE
from the live environment let a cloned project's .env choose both: `crewai run`
on a JSON crew or a declarative flow loads it with override=True, and
`crewai.llm` loads it again on import, which also undid the filter `crewai eval`
applied to its own loader.

PlusAPI now pins the proxy and CA variables when crewai_core.plus_api is first
imported, which the CLI does at startup, and hands them to httpx explicitly with
trust_env=False. With none set, the OS proxy settings apply, read live. The eval
loader goes back to main's, since the client now covers every command.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(cli): pin AMP's proxy and CA in the JSON-crew runner too

`crewai run` runs a JSON crew in a fresh `uv run python -c` interpreter that
never imports cli.py, and `_run_json_crew` loads the project's .env with
override=True before tracing first imports crewai_core.plus_api, so the pin
recorded the project's proxy and CA. The runner now imports plus_api before
anything else. Declarative flows re-run through `uv run crewai run`, which
already pins in cli.py.

Also keeps `_requests_sent_by` off machine and OS proxies, so a developer's
proxy can't mount a real transport ahead of its MockTransport.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(core): keep urllib's CGI proxy rule, and surface a broken plus_api import

The pinned proxy map dropped urllib's REQUEST_METHOD rule: in a CGI process
an uppercase HTTP_PROXY can come from a client's Proxy header, and AMP's
login and deployment ZIPs would follow it. REQUEST_METHOD is now pinned with
the other transport variables, and the map is read exactly as urllib reads it.

The JSON-crew runner skipped any ImportError from crewai_core.plus_api. It now
skips only a crewai-core too old to have the module; any other failure stops
the run with its own error instead of running with nothing pinned.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(cli): import the proxy pin with the project folder off sys.path

`python -c` puts the working directory, the project, first on sys.path, so a
project folder named crewai_core could supply the module that pins where the
saved login travels. The JSON-crew runner now imports the pin with the project
off the path and restores the path right after, so project code (custom tools
importing their neighbours) still finds its own modules.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(core): pin AMP's proxy and CA first thing in `import crewai`

A crew run in its own process (`uv run run_crew`) never imports the CLI, so
`import crewai` is where the pin happens there. It already preceded the
project's .env, loaded by crewai.llm on import, but only by import order. The
pin is now the first import in crewai/__init__.py, and a test runs a fresh
interpreter in a project whose .env names a proxy and CA: the .env loads, and
the pin still holds only what the machine set.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(cli): keep the machine's proxy and CA for the crew `crewai eval` runs

`crewai eval` loads the project's .env into its own process and then runs
the crew in a child that inherits that environment. The child pins what it
inherits, so a .env naming HTTPS_PROXY and SSL_CERT_FILE became the run's
machine transport, and that run's traces carry the saved login.

The proxy and CA variables go back to the machine's pin right after the
.env loads; the rest of the .env still applies, and the run loads the .env
itself after its own pin, as under `crewai run`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(core): keep a project's UV_ENV_FILE out of the crew `crewai eval` runs

`crewai eval` loads the project's .env and starts the crew with `uv run`.
A .env naming itself as UV_ENV_FILE had uv load it into the run before
Python started, so the run pinned the project's proxy and CA anyway.
UV_ENV_FILE now counts among the variables restored to the machine's.

The pin test starts the run through `uv run`, as the CLI does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 12:28:26 -03:00
João MouraandClaude Opus 5.5 3da49f872b feat(cli): crewai eval runs the crew itself, so a coding agent gets a verdict from one command (#8270)
Vulnerability Scan / Detect changes (push) Canceled after 0s
Vulnerability Scan / pip-audit (push) Canceled after 0s
CodeQL Advanced / Analyze (actions) (push) Canceled after 0s
CodeQL Advanced / Analyze (python) (push) Canceled after 0s
Check Documentation Broken Links / Check broken links (push) Canceled after 0s
* feat(cli): crewai eval runs the crew itself, so a coding agent gets a verdict from one command

Most `crewai eval` attempts stopped before an evaluation began because the
project had no traced run. Telemetry since Sept 25: 117 projects stopped as
"untraced", 97 of them with no terminal (coding agents), and 67 of those never
got further. With no terminal the command could only print steps, and without
a login those steps could not work: an unattended anonymous run never uploads
its trace.

- With no traced run, or when the project's files changed since the last one,
  `crewai eval` runs the crew and evaluates that run. No question, with or
  without a terminal: running the command is the request to have the run
  graded, and the grade is read off its trace. Tracing is on for that run only;
  nothing is written to the project's `.env`.
- crewAI's tracing approves the upload of that run through the existing
  handshake: a token in CREWAI_EVAL_AWAITING_RUN that counts only while its file
  exists in the user's crewAI data folder, so a `.env` cannot claim it. Shared
  as `crewai_core.eval_handshake`; the run app keeps its own copy because it
  also runs against a project's older crewai-core, and a test pins the two.
- The run app's Evaluate on an untraced run closes the app and runs the crew
  again, traced, through `crewai eval`'s own path, instead of a notice.
- Counts: `eval_ran_crew:{no_traced_run,project_changed,run_again}`,
  `eval_finished:{passed,failed,inconclusive,unknown}`, and
  `eval_stopped:untraced_after_run` replacing the catch-all `untraced`
  (`declined` is gone with the question). The CLI tests no longer send usage
  counts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(cli): a project that turned tracing off is asked before crewai eval runs it

`CREWAI_TRACING_ENABLED=false` is the project's no, and nothing overrules it,
not even a run `crewai eval` started.

- `crewai eval` at a terminal asks to turn tracing on before running the crew.
  A yes writes it to the project's `.env`; a no runs nothing (exit 0,
  `eval_stopped:declined`). With no terminal it stops and says how to turn it
  on (`eval_stopped:tracing_off`), which a coding agent can do itself.
- The run app's Evaluate on an untraced run asks the same question in a modal
  (TurnTracingOnScreen) before running the crew again. Otherwise it still runs
  it again with no question.
- crewAI's tracing respects an explicit off again: `should_enable_tracing`
  checks it before a run `crewai eval` started, and `execution._tracing_disabled`
  is back to what main has.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(tracing): the telemetry opt-out no longer turns tracing off; an evaluated run says where its trace goes

- `OTEL_SDK_DISABLED` is the telemetry opt-out, a separate setting from
  tracing, which has its own (`CREWAI_TRACING_ENABLED`, `tracing=`).
  `execution._tracing_disabled` no longer reads it. The trace session's own
  TracerProvider records even when the OpenTelemetry SDK is switched off
  (`session._trace_provider`), because the SDK otherwise hands out tracers that
  record nothing. A provider a host passes in is left as it is. Tests that used
  `OTEL_SDK_DISABLED` as a way to stop a trace now cover the two real switches;
  new tests show a traced run, anonymous or logged in, recorded and uploaded
  with it set.
- A run app opened to run the crew for an evaluation (`crewai eval`, or
  Evaluate on a run that was not traced) shows one plain note on mount: "This
  run will be evaluated: its trace is sent to CrewAI AMP, which grades it."

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(cli): say where the trace goes only when the yes is inferred from crewai eval

The note, in the run app ("This run will be evaluated: its trace is sent to
CrewAI AMP, which grades it.") and in `crewai eval`'s line, is for the case
where nobody turned tracing on: not `tracing=True` on the crew or flow, not
`CREWAI_TRACING_ENABLED=true`, not a consent a person gave once
(`crewai_core.user_data.is_tracing_enabled`), and not the yes they just gave to
turn it on. A project or a person who opted in is told nothing new.

The run `crewai eval` starts no longer sets `CREWAI_TRACING_ENABLED=true`:
the handshake alone turns tracing on for it, so the setting a run reads is the
project's own.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(cli): turn tracing on once with a note, pin the eval handshake, and keep the saved login to trusted AMPs

From the review on #8270, and João's call on the note:

- The first `crewai eval` that infers the yes turns tracing on for the
  project (`CREWAI_TRACING_ENABLED=true` in `.env` and for the run) and says
  so once, in the command and in the run app: "Tracing is now on for this
  project…". Afterwards the project traces and nothing more is said. A run
  whose crew or flow sets `tracing=False` is never told its trace is sent.
- The handshake's folder is found from the account's home in the account
  database, never `HOME` or `XDG_DATA_HOME`, so a project's `.env` cannot plant
  a token file that approves an upload. Both copies (crewai-core, the run app)
  are pinned to the same folder and file by a test.
- The token file carries the AMP origins `crewai eval` trusted before the
  project's `.env` was loaded. A run it started sends the saved login only
  there over HTTPS or loopback; an AMP the `.env` chose gets an anonymous
  grant.
- Evaluate on an untraced run carries that run's definition, inputs (prompted
  ones included) and trained-agents file into the re-run. The conversational
  flow consumes the request too, and a crew or flow that sets `tracing=False`
  says why it cannot be evaluated instead of paying for another run.
- "The project changed" also sees deleted files: each evaluation keeps the
  list of the project's files (`.crewai/eval_project_state.json`) and the next
  one compares against it. That list is taken after this command's own
  project-id write, so the write is no change.
- The OpenTelemetry override probes its provider and warns if an SDK version
  still records nothing, instead of failing silently.
- The stale `sdk` case of `test_disabled_execution_does_not_collect_or_request_grants`
  is gone; the handshake tests are typed (type-checker CI).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(cli): keep the saved login off a project's AMP on every path crewai eval runs

From the second review round on #8270:

- Evaluate's re-run runs in a process that already loaded the project's
  `.env`, so it passes this machine's AMPs (`_machine_amp_origins`) as the
  trusted set instead of reading `CREWAI_PLUS_URL` there (`eval_crew(
  trusted_amp_origins=…)`).
- A project's `.env` can neither set nor replace `crewai eval`'s token:
  `run_crew.load_project_env` keeps the token the process was started with and
  drops one a `.env` sets. The JSON-crew, declarative-flow and eval paths all
  load `.env` through it.
- `crewai eval` turns tracing on only when every credential this machine holds
  (the saved login, or a PAT or integration token from before the `.env`) may
  go to the AMP the run would trace to. A project's crewai older than the
  handshake would otherwise send it to an AMP the `.env` names. A newer crewai
  still traces the run anonymously through the handshake.
- A conversational flow named by its definition is re-run by that definition.
- Code quality: no redundant assignment in `_awaiting_dir`, no unused names in
  the credential test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(cli): crewai eval does not run a crew whose trace would carry the login to an untrusted AMP

When tracing is on for the run (the project's .env, or a consent given once)
and a credential of this machine would go to an AMP the command does not
trust, the crew is not run. A project's crewai older than the handshake would
send the login there, and the CLI cannot tell which crewai the project runs.
The command stops (`eval_stopped:untrusted_amp`) and says how to go on: log
in to that AMP, or remove CREWAI_PLUS_URL from the project's .env. A project
that turned tracing off is not asked to turn it on toward such an AMP. With
no credential on the machine, there is nothing to protect and the run goes on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Ask at a terminal before tracing is first turned on

A person running `crewai eval` at a terminal, in a project that never
turned tracing on, is now asked on crewAI's trace consent screen before
the crew runs; a yes turns tracing on for the project, a no (or the
screen timing out) runs nothing and is counted as `declined`. The run
app's Evaluate on an untraced run asks on its own consent screen the same
way. With nobody at a terminal (a coding agent, a script) the yes is
still inferred from the command, tracing is turned on and said once.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Keep main's Iterator import, which the rebase over #8187 dropped

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* A run-app test no longer leaves .crewai/last_eval.json in the repo

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Two run-app tests from #7963 no longer leave .crewai/last_eval.json in the repo

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Never run the crew toward an AMP the login must not reach; check before asking

`crewai eval` now refuses to run the crew whenever a credential of this
machine would go with the trace to an AMP it does not trust, whatever the
tracing setting: `tracing=True` in code is invisible to the CLI, and a
project's crewai older than the handshake sends the credential wherever
the run traces. The run app's Evaluate makes the same check before it
asks anything, so a yes can never write CREWAI_TRACING_ENABLED=true to
`.env` for a re-run that is then refused.

Which credentials are this machine's is read from the environment as it
was before any project `.env` was loaded (`run_crew.environment_before_project`),
so on Evaluate's re-run a CREWAI_USER_PAT the project's own `.env` brought
is the project's, as on any run of it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Run the crew only toward an AMP this machine trusts, login or not

Whether this machine holds a login right now no longer decides: with no
login yet, `crewai eval` still wrote CREWAI_TRACING_ENABLED=true toward a
CREWAI_PLUS_URL the project's `.env` chose, and the first run after
`crewai login` would have carried the login there. Toward an AMP this
command does not trust, the crew is now never run, nobody is asked and
nothing is written, in `crewai eval` and the run app's Evaluate alike.
That also drops the credential bookkeeping from b26ccaf44, which the
rule no longer needs.

The telemetry docs no longer say OTEL_SDK_DISABLED turns off everything:
it disables OpenTelemetry instrumentation and CrewAI's telemetry, not AMP
tracing, which has its own switches.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Pin that a project's own token never blocks Evaluate's re-run

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 04:11:15 -03:00
João MouraandClaude Opus 5.5 1410318b2e feat(cli): crewai eval export downloads an evaluation as files (#8187)
CodeQL Advanced / Analyze (actions) (push) Canceled after 0s
CodeQL Advanced / Analyze (python) (push) Canceled after 0s
Vulnerability Scan / Detect changes (push) Canceled after 0s
Vulnerability Scan / pip-audit (push) Canceled after 0s
* crewai eval export downloads an evaluation's full data as files

A coding agent that is asked to act on an evaluation needs more than the
brief: the report, every setup's outputs, every check with the judge's
words, and the traces. AMP serves them as one export; this writes them
into ./crewai-eval-<id>/ with a .gitignore of `*`, so customer data is
never committed by accident. `crewai eval` becomes a group so the
subcommand can live under it; every existing invocation is unchanged.

The paths come from whichever AMP answered, so only plain relative paths
that resolve inside the folder are written; the rest are skipped and
counted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* A .gitignore link already in the export folder is replaced, never followed

Writing through it would have put `*` into whatever file it points at,
outside the folder. The tests also read the export as UTF-8, as it is
written, so a Windows locale cannot misread its dashes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* The export writes through folder handles and refuses Windows device names

A name Windows keeps for a device (CON, PRN, AUX, NUL, COM0-9, LPT0-9, with
any extension) is skipped like any other unsafe path, on every platform: on
Windows `NUL.md` is the null device, and the export would report a file
written that nobody can read.

On Linux and macOS each folder of a path is opened inside the one before it,
never through a link, and the file inside the last: no path is checked and
then opened again, so a link another process swaps in while the export runs
is never gone through. A link where a folder goes skips that file; a link at
a file's own place, symbolic or hard, is removed and the file made anew; the
export folder itself being a link stops the export with one sentence.
Windows keeps the resolved-path check.

Reading an evaluation sends `can_export=1`, so the brief names
`crewai eval export` only when the CLI, AMP and the evaluation service all
serve it. An AMP without the export route (a 404 that is not AMP's
`not_found`) says it needs an update; AMP's `export_unsupported` and
`export_too_large` answers are printed in AMP's own words.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* A folder where an exported file goes is skipped; the path writer replaces hard links and refuses a junction

- A folder already standing where an exported file goes is skipped and
  counted, as a file where a folder goes already was, instead of
  stopping the export.
- On the path writer (Windows), whatever is at a file's place is removed
  and the file created anew. A hard link there is no longer written
  through.
- The export folder must resolve to itself. A Windows junction, which
  `is_symlink` does not see, stops the export like a link.
- The file handle is closed if wrapping it fails.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Say why a missing file is no error before the export makes it

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* A folder where the export's .gitignore goes stops the export before any data

The data never goes into the folder without the .gitignore that keeps it
out of git. The Windows path writer's comment now states the race it
leaves open, and why that loss is bounded.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 22:46:13 -07:00
João MouraandClaude Opus 5.5 9112709294 fix(cli): run JSON crews headless when there is no terminal (#8239)
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
Vulnerability Scan / Detect changes (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
`crewai run` on a JSON crew opened the Textual run screen unless CREWAI_DMN
was set. Without an interactive terminal (a coding agent's shell, CI, piped
input) the screen stayed open after the crew finished, so the command never
exited. It now opens only when is_interactive() is true, the convention
declarative flows already follow; otherwise the crew runs on plain output and
the command exits.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 17:52:56 -03:00
40bb2d3b58 fix(memory): escape scope and id values in LanceDB filters (#7820)
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
Mark stale issues and pull requests / stale (push) Has been cancelled
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
* fix(memory): escape scope and id values in LanceDB filters

LanceDBStorage built its where() filters by interpolating scope prefixes
and record ids into SQL strings. Route every interpolated value through a
quote-escaping helper, and match scope prefixes with LIKE ... ESCAPE '\'
so %, _ and \ in scope names match literally while the trailing prefix
wildcard is kept.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(memory): keep delete calls out of assert expressions

Run each storage.delete() on its own line and assert on the returned
count, so the deletion does not live inside an assert statement.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Craig Estep <craig.estep@crewai.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 21:04:46 +05:30
iris-clawdandVidit cf9f08a4a1 fix: resolve pip-audit dependency findings (#8221)
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
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.13) (push) Has been cancelled
Build uv cache / build-cache (3.12) (push) Has been cancelled
Raise the MCP Python SDK and TinyTag version floors to releases patched
for the two vulnerabilities reported by the pip-audit workflow.

- mcp: ~=1.28.1 / >=1.28.1 → >=1.30.0,<2
- tinytag: ~=2.2.1 → >=2.3.0,<3
- Regenerated uv.lock

Co-authored-by: Vidit <vidit@crewai.com>
2026-10-16 09:14:52 +00:00
Matt Aitchison 6115839576 fix(mcp): name tools from IP-addressed MCP servers so providers accept them (#8117)
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
Check Documentation Broken Links / Check broken links (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
Vulnerability Scan / Detect changes (push) Has been cancelled
* fix(mcp): name tools from IP-addressed MCP servers so providers accept them

Tools from an MCP server addressed by IP (http://127.0.0.1:8800/mcp) were named 127_0_0_1_8800_mcp_<tool>. validate_function_name requires a leading letter, so every provider rejected them. _extract_server_name now prepends mcp_ when the derived name starts with anything other than an ASCII letter; hostname-based names keep their current form.

The server name also copied the user:pass@ part of the URL into every tool name, which sends credentials to the model. It is now stripped.

* fix(mcp): prefix stdio server names that start with a digit

Stdio servers built their tool prefix from the command and args without the leading-letter check, so a command like 3d-server produced 3d_server_<tool>, which providers reject. Both stdio and URL server names now go through _ensure_letter_prefix.

The check now looks at the sanitized name. A non-ASCII host such as ñandu.example sanitizes to a leading n and keeps its name, and a path like /usr/bin/python never gets a prefix.
2026-10-15 17:55:00 -05:00
Vidit Ostwal c661df9816 feat(agents): promote AgentExecutor out of experimental (#8192)
* feat(agents): promote AgentExecutor out of experimental

The default executor was still imported from crewai.experimental. Move it to a stable module and keep the old import as a deprecation warning.

* fix(agents): stabilize executor discriminator

* feat(agents): remove CrewAgentExecutor

AgentExecutor is the only executor. Selecting the deleted class fails immediately, with no compatibility path.

* feat(agents): drop experimental AgentExecutor compatibility

The experimental import path and the legacy experimental discriminator are no longer accepted.

* docs: address executor review comments

Translate the remaining hook comments, document the full executor type, and stop the removal test from hiding an eager export.

* docs: keep translated hook sketches on AgentExecutor

The locale class sketches only needed the CrewAgentExecutor rename. LiteAgent and None stay on the English page, which documents the full type.
2026-10-15 14:33:38 -07:00
Vidit Ostwal 912f491b67 feat: proactively summarize oversized LLM context (#8191)
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
Vulnerability Scan / Detect changes (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
* feat(llm): summarize before context limit

* test(llm): cover proactive context compaction

* test(agent): cover proactive compaction routes

* test(agent): cover async proactive compaction

* test(lite-agent): cover proactive compaction

* test(agent): cover executor context preflight

* feat(agent): show context summarization status

* fix(llm): harden proactive context preflight

* test(llm): configure proactive preflight mocks

* test(agent): remove flaky async preflight coverage

* feat(events): emit context summarization lifecycle

* fix(agent): preserve sole pending request

* fix(agent): fail open proactive compaction

* fix(agent): offload proactive compaction

* test(agent): align proactive compaction fixture

* test(agent): add history to compaction fixtures

* fix(events): close failed summarization lifecycle
2026-10-15 23:59:13 +05:30
Gabe Milani c069653b83 fix: stop an agent that repeats the same tool call (#8164)
* fix: stop an agent that repeats the same tool call

* count tool calls within method only
2026-10-15 15:14:20 -03:00
Vidit Ostwal e9f682222a feat: defer oversized native tool results (#8110)
* feat: add temporary tool result artifacts

* feat: detect oversized tool results

* feat: allow deferred tool results in file reader

* feat: preview deferred tool results

* test: cover deferred native tool results

* test: cover multiple deferred tool results

* test: cover existing file reader with deferred results

* feat: clean up deferred tool result artifacts

* test: cover deferred tool result fallbacks

* feat(agent): describe deferred tool result size

* feat(agent): display deferred tool artifacts

* style(agent): label deferred results with emoji

* feat(agent): recommend deferred result chunks

* feat(agent): expose deferred artifact directory

* feat(agent): add better compaction flag

* feat(agent): add deferred result reader

* fix(agent): reference native deferred reader name

* fix(agent): render deferred results as plain text

* fix(agent): size deferred result reads by context

* fix(agent): reuse overflow token count for deferred reads

Keep the provider token count from the overflow check and store that same count so read-size recommendations do not recalculate it.

* fix(agent): keep deferred reader available after text tool downgrade

* fix: avoid re-deferring deferred tool results

* revert(tools): remove deferred file reader support
2026-10-15 23:34:07 +05:30
Vidit Ostwal 3da2d4e993 Filter platform actions while selecting them (#7991)
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
* Mark the platform action picker as searchable.

The flag is off for every other multi-select, and filtering comes in the next change.

* Filter picker labels by query while keeping their original indexes.

An empty query matches every label, and a typed query can match the display name or the slug.

* Let the platform action picker filter as the user types.

The arrow-key list shows the query and hides non-matching rows, and the numbered fallback uses the same filter without dropping checked actions.

* Erase leftover rows when a search result is shorter than the previous list.

A filtered action picker now shows only the matching actions.

* Show the action search in green under the navigation hint.

The line includes how many actions the query matched.
2026-10-15 10:00:00 +05:30
João MouraandClaude Opus 5.5 aa5f2acd9b deploy push reads AMP's comparison refusal by its code (#8161)
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
Mark stale issues and pull requests / stale (push) Has been cancelled
* deploy push reads AMP's comparison refusal by its code

AMP's 409 for a deployment with a models comparison running now carries
the sentence in `error`, because every released CLI prints a failed
request's `error` and none has `--force`; the refusal is named in
`code`. `crewai deploy push` recognises it by `code` and prints the
sentence as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Recognise AMP's refusal named in `error` too, on every route

An AMP from before the `code` field (a branch on staging, a factory that
upgrades later) names the refusal in `error`; recognising both keeps the
sentence for an upgraded CLI whichever AMP it talks to. A test covers
deploy by id, by name and the ZIP update in both shapes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 16:52:50 -03:00
Vidit Ostwal c7c0d8969a Rename the platform token and preselect default app actions (#7990)
* Rename the platform integration token to the Enterprise Action Auth Token.

The CLI now asks for that token under Settings → Account and stores it as CREWAI_ENTERPRISE_ACTION_AUTH_TOKEN.

* Add the latest Clipper platform applications to the catalog.

SharePoint Graph, Resend, Vercel, and Pinecone come from clipper v5 and are grouped in the platform picker.

* Preselect three default actions for every platform application.

The create wizard checks those actions in the picker, and a test keeps the defaults list the same length as the catalog.

* Fail the Clipper client test when the Enterprise Action Auth Token is absent.

A deployment instance id is not a substitute for that token, so the test no longer sets one.

* fix(agent): name the Enterprise Action Auth Token when apps resolve to no tools
2026-10-15 01:17:41 +05:30
Vidit Ostwal aaaa312cba feat(llm): add provider input token count support (#8109)
* feat(llm): add token estimation interface

* feat(openai): add input token count support

* test(openai): cover input token counting

* feat(anthropic): add input token count support

* feat(llm): extend input token count providers

* feat(litellm): add input token estimation

* fix(llm): address token count provider gaps

* fix(llm): count LiteLLM structured output tokens

* fix(anthropic): align token count payload

* fix(snowflake): reject unsupported token counts

* fix(openai): reject compatible token counts

* refactor(llm): simplify token count interface

* fix(llm): fall back to character token estimates

* fix(llm): warn on token count fallback

* fix(anthropic): fall back when token counting fails
2026-10-14 23:22:45 +05:30
João MouraandClaude Opus 5.5 b0c16c162a fix(cli): crewai eval waits out AMP's rate limit instead of quitting (#8148)
* fix(cli): crewai eval waits out AMP's rate limit instead of quitting

On prod (2026-10-14) a `crewai eval --models` comparison ended its CLI with
exit 1 on one poll AMP answered 429 ("Too many evaluation requests. Please
retry later." — AMP allows 30 evaluation requests a minute per IP), while
the deployment went on running the comparison. A 429 mid-poll is now waited
out: Retry-After seconds, never less than a poll's interval nor more than
RATE_LIMIT_MAX_WAIT_SECONDS (120), a missing or odd header a minute; then
the poll goes on, however many come. It is not counted as a miss: being
asked to slow down is no reason to stop waiting for a running evaluation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(cli): a rate limit that never lifts ends the wait; Retry-After as RFC 9110 has it

Review on #8148:
- Rate-limited without a break for RATE_LIMITED_FOR_AT_MOST_SECONDS (15
  minutes, counted over the waits the 429s asked for and reset by any other
  answer), the wait stops: "AMP kept rate-limiting this command for 15
  minutes, so it stopped waiting; the evaluation keeps running at <url>."
  A limit that passes is still ridden out; CI, agents and the TUI no longer
  wait without end.
- Retry-After is read in both forms RFC 9110 allows, delay-seconds and an
  HTTP-date (a date already past waits a poll's interval); a negative or
  non-finite number, or words, waits a minute, as documented — NaN and the
  infinities no longer slip past that.
- The test compares the whole list of waits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(cli): the passing-limit case checks every poll it made

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(cli): the rate-limit count never overruns, and any other answer restarts it

CodeRabbit on #8148 (outside the diff):
- A 5xx between 429s is an answer too: every non-429 answer now restarts
  the count, before the 5xx branch continues.
- The last wait is what is left of RATE_LIMITED_FOR_AT_MOST_SECONDS, so the
  wait never runs past fifteen minutes (it could overrun by up to 119 s).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(cli): a 429 breaks a streak of unreachable or 5xx polls

CodeRabbit on #8148: POLL_RETRIES counts a consecutive streak of
unreachable or 5xx polls, and a 429 is AMP answering. Four 503s, a 429 and
one more 503 stopped the wait; the 429 now resets the streak.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(cli): one deadline over every kind of refusal while waiting

iris on #8148: a 503 reset the rate-limit count and a 429 reset the 5xx
streak, so refusals taking turns could keep CI and agent callers waiting
without end. The two counts are now one monotonic deadline (_clock):
polls that get no answer about the evaluation — rate-limited, failing,
unreachable, in any mix — for UNANSWERED_FOR_AT_MOST_SECONDS (15 minutes)
without a break end the wait, and only AMP's answer (a 200) restarts it.
The last wait is still what is left of the deadline. The sentence names the
cause: "AMP kept rate-limiting this command for 15 minutes" when every
refusal was a 429, else "AMP gave this command no answer about the
evaluation for 15 minutes (rate limits, errors, no connection)".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 06:37:57 -07:00
João MouraandClaude Opus 5.5 8dcb00584f feat(cli): crewai deploy push --force, and why AMP held a push back (#8150)
* feat(cli): crewai deploy push --force, and why AMP held a push back

AMP now holds back a redeploy while a models comparison is running on the
deployment (crewAIInc/crewai-plus#4776): a redeploy restarts the workers
and the comparison loses its runs (pr_security_reviewer, 2026-10-14). It
answers 409 {"error": "comparison_running", "message": ...}.

- `crewai deploy push --force` goes ahead anyway: deploy_by_uuid /
  deploy_by_name send {"force": true} and update_crew_from_zip a force field
  (crewai-core and the CLI's own copy), only when asked — an unforced push
  sends exactly what it always did, and an older AMP ignores the field.
- A push AMP held back prints AMP's sentence (which names --force) and
  "Nothing was deployed.", and exits 1 — not the bare error code.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(llms): Claude 3.5 Sonnet v2 on Bedrock has a 200k window in the refreshed catalog

The 1.15.28 release refreshed the packaged LiteLLM catalog, which now lists
anthropic.claude-3-5-sonnet-20241022-v2:0 at 200,000 input tokens (it had
1,000,000), the model's documented window. The test still expected 1M, so
every PR's test job failed on main's own catalog.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(cli): AMP's hold-back sentence is printed literally

Review on #8150: the comparison_running message went through Rich markup,
so a bracketed word in it vanished and a stray closing tag raised
MarkupError before "Nothing was deployed." could print. It is printed with
markup=False now; a test sends one with both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 09:58:28 -03:00
João MouraandClaude Opus 5.5 acd4b33a17 test(llms): Claude 3.5 Sonnet v2 on Bedrock has a 200k window in the refreshed catalog (#8151)
The 1.15.28 release refreshed the packaged LiteLLM catalog, which now lists
anthropic.claude-3-5-sonnet-20241022-v2:0 at 200,000 input tokens (it had
1,000,000), the model's documented window. The test still expected 1M, so
every PR's test job failed on main's own catalog.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 09:39:57 -03:00
João Moura eb15c66cef [docs-freeze] docs: snapshot and changelog for v1.15.28 (#8147)
Mark stale issues and pull requests / stale (push) Has been cancelled
Check Documentation Broken Links / Check broken links (push) Has been cancelled
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
Vulnerability Scan / Detect changes (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
2026-10-14 01:46:47 -03:00
João Moura 7056fe1fe2 feat: bump versions to 1.15.28 (#8146) 2026-10-14 01:42:13 -03:00
João MouraandClaude Opus 5.5 75808b0eca fix(flow): learn from resumed human feedback and keep the reviewed output's type (#8142)
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
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Check Documentation Broken Links / Check broken links (push) Has been cancelled
Vulnerability Scan / Detect changes (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
* fix(flow): learn from human feedback that resumes a paused flow

With learn=True, lessons were distilled only when the reply arrived
during the same run. A reply that resumes a paused flow (resume /
resume_async after from_pending, which is how async providers such as
AMP's email review work) went through outcome collapse and routing but
never reached _distill_and_store_lessons, so it taught nothing.

Resume now stores lessons under the same conditions as an in-run reply:
memory available, non-empty feedback, the method's learn_source and
learn_strict, and the persisted LLM config. Both paths share one helper.
A strict distillation failure fails the resume before the pending review
is cleared, so it can be retried.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(flow): undo the recorded reply when strict learning fails on resume

_finalize_human_feedback appends the reply to human_feedback_history and
sets last_human_feedback before lessons are stored. With learn_strict, a
distillation failure re-raises and the review stays pending, so a retry
on the same instance recorded the reply twice. Restore both on failure.
Lesson storage stays after outcome collapse, so a collapse failure never
leaves lessons behind to be stored again on retry.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(flow): keep the reviewed output's type when learn=True pre-reviews it

Pre-review always returned PreReviewResult.improved_output, a str, so a
method returning a Pydantic model or a dict reached the reviewer, and
last_human_feedback.output, as a repr string. Text output is still
rewritten as text; a Pydantic model is now rewritten as the same model
(response_model=type(output)); other outputs are shown unchanged.

LiteLLM-routed models return structured output as a JSON string, which
PreReviewResult/DistilledLessons.model_validate rejected, so pre-review
and lesson storage silently did nothing for them. One parser now accepts
an instance, a JSON string, or a dict.

Docs (en, ar, ko, pt-BR): drop the nonexistent learn_limit, document
learn_source and learn_strict, say lessons are also learned from replies
that resume a paused flow, how each output type is pre-reviewed, and that
downstream steps should read last_human_feedback.output. Correct the
HumanFeedbackResult.output docstring and the learn/learn_strict field
descriptions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(flow): keep pre-review failures and unseen fields from leaking into the output

model_dump_json() ran before the pre-review try, so a Pydantic output that
cannot be serialized failed the feedback step even with learn_strict off.
It now runs inside the try and falls back to the original output.

A reviewed Pydantic model is rebuilt from what the LLM saw, so a SecretStr
(sent masked) or an excluded field (not sent) came back as the mask or the
default. Fields the review left unchanged now keep their original values.

Also pin that a retry after a persistence failure that follows lesson
storage offers the lessons to memory again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(flow): keep nested hidden values when pre-review edits sibling fields

The unchanged-field restore only looked at top-level fields, so editing a
sibling inside a nested model, or one item of a list of models, kept the
LLM's masked secret and default excluded values for that whole object.
The restore now recurses into nested models and same-length lists of
models.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(flow): skip pre-review for models holding secrets or excluded fields

Restoring hidden values after the review kept growing edge cases: aliased
fields compared by name discarded the review's edit, dicts of models were
not recursed, and reordered lists paired the wrong items, which could
copy one account's secret onto another. Drop the merge. A Pydantic output
is pre-reviewed only when the LLM sees all of it; one holding a Secret,
SecretStr, SecretBytes or Field(exclude=True) value at any depth reaches
the reviewer unchanged. Docs updated in en, ar, ko and pt-BR.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(flow): say a resumed review's Pydantic output arrives as a dict

PendingFeedbackContext persists method_output as JSON, so after
from_pending and resume, last_human_feedback.output is a dict even when
the method returned a model. The docstring and docs said "same type"
without that qualification. Also say learn_strict covers distillation
and submitting lessons, not the background memory write. Pin the dict
behavior with a pause/resume test. Docs in en, ar, ko and pt-BR.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 03:05:26 +00:00
João MouraandClaude Opus 5.5 ba36746169 fix(agent): warn when non-empty apps resolve to zero platform tools (#6469)
* fix(agent): warn when non-empty apps resolve to zero platform tools

When an agent declares `apps` (enterprise integrations) but they resolve to no
tools — unknown/misspelled app, app not connected, no actions, or a missing
CREWAI_PLATFORM_INTEGRATION_TOKEN — the agent silently runs without them and
can't do what those apps were for. CrewaiPlatformTools returns an empty list in
all those cases, and both resolution sites dropped it silently (agent kickoff
`if platform_tools:` and crew `_inject_platform_tools` merge), while the only
existing signal is a verbose-gated Logger.log.

Emit a loud UserWarning from Agent.get_platform_tools() — the shared choke point
for the agent-kickoff path (core.py:_prepare_kickoff), the crew task path
(crew.py:_inject_platform_tools), and declarative flows (agent actions route
through the same kickoff). The warning names the unresolved apps and the likely
causes.

Tests: warns on zero-tool resolution (direct + crew-prepare paths), stays quiet
when tools resolve.

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

* test(agent): cover empty platform-tool resolution through the real factory

Address review on the empty-apps warning: document get_platform_tools,
trim the inline comment, and use one import style for crewai_tools in the
tests. Two new tests run the real CrewaiPlatformTools factory (it returns
a plain list) with only requests.get mocked: a selector that matches no
action, and a missing integration token. Both reach the warning, and
messages are now asserted in full.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-10-13 17:18:20 -07:00
João MouraandClaude Opus 5.5 ddfa8517b8 feat(cli): crewai eval --models says at once where a stopped model broke (#8105)
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
* feat(cli): crewai eval --models says at once where a stopped model broke

The service's poll answer now lists the setups that stopped, with where in
the project each broke (step → crew → task → agent), the whole reason and
its plain words. The CLI says each one the moment that is known, while the
others keep running: a coding agent gets a block it can start fixing from,
the run's own words quoted as data; a person gets one red line. An older
service sends nothing and nothing changes. The AGENTS.md templates say to
run a comparison in the background and read its output as it goes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(cli): a stopped setup's location is a list of names, and the run's words come only from `reported`

Review (#8105): `where` from the service was used whenever it was truthy, so a
string skipped the wait and printed one character per place, and anything not
iterable raised. Each stopped setup is now parsed once into a checked record
(_Stop): only a list of non-empty strings is a location; the run's own words
are read only from `reported`, where the service (crew-optimize #25) puts them
beside its data-not-instructions note — top-level text is not the run's
channel. The AGENTS.md templates say a location prints when the service knows
it, and an unplaced stop after about 20 seconds or when the comparison ends.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(cli): pin when an unplaced stop is said, not just the order

Review (#8105): the ordering assertion passed even if an invalid `where` were
announced on the first poll, since the progress line prints first anyway. The
test now records the fake clock when the stop is said and asserts 30 s — after
the wait ran out, never at the first poll.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 14:58:03 -03:00
João MouraandClaude Opus 5.5 7b07ee5b6a fix(utilities): stop json-schema models warning about BaseModel-shadowing fields (#8085)
* fix(utilities): stop json-schema models warning about BaseModel-shadowing fields

Tool schemas legitimately name arguments schema, json or copy. Pydantic warns
that these shadow BaseModel attributes every time create_model_from_schema
builds such a model, which clutters CLI and agent output when platform or MCP
tools load. The fields already validate and dump under their own names, so
silence only that warning, and only while building a model that has a
colliding name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(utilities): serialize the shadow-warning filter swap across threads

Two threads building colliding models could overlap their catch_warnings
blocks; the later exit then restored a filter list that still held the
earlier build's ignore rule, leaking it to every later model. A lock now
serializes the swap. Also replace a class defined only for its warning
with create_model in the test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(utilities): pin that rebuilt recursive models emit no shadow warning

A recursive $defs schema builds one model incomplete and finishes it with
model_rebuild outside the suppression context. Pydantic only warns while
collecting fields at class creation, so the rebuild stays silent; this
test keeps that true.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 17:29:09 +00:00
João MouraandClaude Opus 5.5 18473adc33 fix(cli): flow add-crew finds the package from pyproject (#8082)
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Check Documentation Broken Links / Check broken links (push) Has been cancelled
Vulnerability Scan / Detect changes (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
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
`crewai flow add-crew` looked for `src/<folder name>/crews`, so a project
cloned or created under a different directory name failed with "Crews
folder does not exist". It now resolves the package from
`[project].name` (normalized like the scaffolder does) and falls back to
a single `src/*/crews`; several candidates or none fail with a message
naming what was expected or found.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 16:50:19 -07:00
Lorenze Jay bea8c03649 fix: preserve native tool aborts and post-hook cache identity (#8107)
* fix: preserve native tool aborts and post-hook cache identity

* fix: limit native hook changes to active executors
2026-10-12 19:32:15 -03:00
João MouraandClaude Opus 5.5 ab423144c1 docs: correct deploy and platform-tool guidance in the project AGENTS.md (#8084)
* docs: correct deploy and platform-tool guidance in the project AGENTS.md

The AGENTS.md that `crewai create` ships told coding agents that
`crewai deploy remove <id>` works (the CLI only takes `-u <uuid>`), that a
deploy needs a GitHub repository (with no origin it uploads a ZIP), that
PLATFORM_APPS is the source of truth for action selectors (some of its
action names resolve to no tool), and to measure quality with
`crewai test`. Its router example also declared no labels, so
`crewai flow plot` could not draw the branches.

- Template: platform token, selector syntax, `apps:` YAML example and
  selector check; router labels; deploy prerequisites, `-y`, `.env`
  upload, org commands, `project_id`; best practice points at
  `crewai eval` inside the eval markers.
- Docs: quickstart deploy prerequisite and `remove -u`, and router
  labels in concepts/flows, in en, ar, ko and pt-BR.
- Tests parse every documented deploy/org command against the real CLI,
  run the routing example through the plot builder, and check the best
  practices stay numbered without gaps for crew and tool projects.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs: base the quickstart ZIP-deploy note on any git origin

The CLI deploys from git whenever an `origin` exists, GitHub or not, and
uploads a ZIP only when there is none. The quickstart said "GitHub
origin ... without one", which reads as if a non-GitHub origin takes the
ZIP path.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 22:22:59 +00:00
João MouraandClaude Opus 5.5 744bf60367 fix(cli): show why a deployment failed and fix deploy remove and lockfile checks (#8083)
* fix(cli): show why a deployment failed and fix deploy remove and lockfile checks

- deploy status prints AMP's error_message and error_suggested_fix when a
  deployment has failed, verbatim (no Rich markup), instead of only
  "Provisioning Failed, try again."
- deploy remove -u names the removed UUID instead of the local project, and
  a failed removal prints the API's error.
- deploy validate asks `uv lock --check` (offline) whether uv.lock is current
  instead of comparing file times, which flagged metadata-only edits that
  `uv lock` never clears. File times remain the fallback without uv or for
  poetry.lock.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs: note that deploy status prints the failure reason

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(cli): print deploy validate findings without Rich markup

render_report printed codes, titles, details and hints as Rich markup, so
bracketed text vanished: `[stale_lockfile]`, `[project]`,
`[tool.hatch.build.targets.wheel]`, `crewai[tools]`. Raw `uv` stderr in
the new unverified_lockfile detail could also raise MarkupError on a stray
closing tag. Escape every finding field. Also bound the test fixture's
`uv lock` with a timeout.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:21:16 -03:00
João MouraandClaude Opus 5.5 6b9e62180e fix(core): give trigger list and payload requests a 60s timeout (#8081)
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
`crewai triggers list` timed out on every real organization: the apps
listing takes about 11s and these two calls fell back to httpx's 5s
default. Other PlusAPI calls keep their current timeouts.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 18:55:48 +00:00
Vidit Ostwal 13b7c3079f Refresh the LiteLLM catalog after the version-bump PR merges. (#8103)
The release docs PR now downloads the checked-in model catalog so context-window data ships with the tagged release.
2026-10-12 23:57:15 +05:30
João MouraandClaude Opus 5.5 9d5fd32661 fix(cli): deploy push reads AMP's source_type, so a ZIP deployment gets the new code (#7980)
#7345 made push follow how AMP holds a deployment's code, read from a
`zip_deployment` boolean on the status. AMP's status never sends that field:
it sends `source_type` ("zip", "studio", "github", "any_git"). So push always
fell back to the local origin remote, and a ZIP deployment whose project has a
git remote was redeployed by uuid — AMP rebuilt the ZIP it already held, not
the code being pushed.

Seen on a real deployment: after raising crewai to 1.15.26, `crewai deploy push`
rebuilt the stored 1.15.23 ZIP ("CrewAI version detected: 1.15.23"), with no
upload. `zip_deployment` is still read first when a server sends it.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-12 15:45:13 +00:00
Vidit Ostwal 60a55f565f Use the LiteLLM catalog for context windows (#8077)
* Use the LiteLLM catalog for context windows.

Handwritten provider limits drift from published model IDs, so look up each exact catalog entry instead.

* Restore context windows for routed model ID variants.

Exact catalog keys miss Bedrock revision suffixes, dated Claude inference IDs, and three Gemini Gemma models that CrewAI still routes.

* Revert "Restore context windows for routed model ID variants."

This reverts commit 6915db1358.

* Match context windows by bare catalog model name.

Exact IDs still win, and a miss falls back to the full catalog after provider, region, date, and version are removed.

* Move the LiteLLM catalog into litellm_catalog.

* Skip bare aliases when the same model id has conflicting context limits.

* Use the most common bare-name context limit, and the smaller one on a tie.

* Do not let an unknown provider prefix inherit the bare model context window.
2026-10-12 21:07:29 +05:30
SIDDARTHA REDDY 753d192366 Make evaluator regression test collectible; repair rotted tests (#8031)
Mark stale issues and pull requests / stale (push) Has been cancelled
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
Signed-off-by: SIDDARTHA REDDY <75976672+SIDDARTHAREDDY8@users.noreply.github.com>
2026-10-12 04:30:15 +00:00
Nagizaaz Shaik be64826f09 fix: emit call completed event for streamed anthropic tool calls (#8061) 2026-10-12 04:15:43 +00:00
Nagizaaz Shaik 74fe931a39 docs: fix RagTool and XMLSearchTool README imports (#8033) 2026-10-12 03:51:05 +00:00
エイカクandVidit Ostwal 53c355e0b3 fix(rag): decode local json files with utf-8 bom (#8023)
Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-10-12 03:45:05 +00:00
Lucas KimandClaude 6dd895fd72 fix(bedrock): allow image input_files for OpenAI GPT-6 Sol/Luna/Astra (#7733)
* fix(bedrock): allow image input_files for OpenAI GPT-6 Sol/Luna

supports_multimodal() only listed Claude and Nova ids, so the documented
files/input_files path raised "does not support multimodal input" for
GPT-6 Sol and Luna before any request was sent, although Bedrock accepts
image blocks for them. Add their bare, us. and global. ids to the
vision allow-list, following the existing us. entries. Bedrock
rejects image blocks for gpt-oss, so it stays excluded.

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

* fix(bedrock): accept image input_files for GPT-6 Astra too

GPT-6 Astra takes image input on Bedrock like Sol and Luna, but the
allow-list named only Sol and Luna, so files/input_files still raised
"does not support multimodal input" for Astra. Match the GPT-6 family
prefix instead, the way the Claude and Nova entries match their
families. gpt-oss has no image input and is still excluded.

The parametrized test now also covers the bare openai.gpt-6-* ids.

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-12 03:36:02 +00:00
Lorenze Jay d522c31339 feat: bump versions to 1.15.27 (#8001) 2026-10-09 19:25:10 -03:00
Melanie Hart Buehler 140bfcb89a docs(rag): add XPU to OpenCLIP provider device options (#7923)
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Check Documentation Broken Links / Check broken links (push) Has been cancelled
Vulnerability Scan / Detect changes (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
2026-10-09 14:05:39 +00:00
Lucas KimandClaude 107fab8c85 fix(bedrock): don't send stopSequences to OpenAI GPT-6/GPT-5.6/gpt-oss (#7731)
OpenAI models on Bedrock reject inferenceConfig.stopSequences with a 400,
and crewAI adds the "\nObservation:" stop word to every agent call, so
Agent.kickoff() and Crew.kickoff() failed on GPT-6 Sol/Luna, GPT-5.6 and
gpt-oss.

supports_stop_words() now returns False for "openai." model ids and
_get_inference_config() only sends stopSequences when it returns True,
mirroring the Azure provider. Stop words are still applied client-side
by _apply_stop_words, and executors fall back to use_stop_words=False.

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-09 13:16:55 +00:00
エイカク ce149db311 fix(rag): preserve github loader source attribution (#7983) 2026-10-09 10:45:25 +00:00
Georgi AtsevandJoão Moura d38ceafb68 feat(llms): add deepinfra as an openai-compatible provider (#7459)
Mark stale issues and pull requests / stale (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
Check Documentation Broken Links / Check broken links (push) Has been cancelled
Vulnerability Scan / Detect changes (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
* feat(llms): add deepinfra as an openai-compatible provider

Register deepinfra in the OpenAI-compatible provider registry so
LLM(model="deepinfra/<org>/<model>") routes natively with DEEPINFRA_API_KEY
and no LiteLLM install. Model ids keep their org/model form,
DEEPINFRA_BASE_URL overrides the endpoint, and the docs accordion is added
in en, ar, ko and pt-BR, stating that the provider uses the native OpenAI
client and needs no LiteLLM install.

The model id check requires exactly one slash with both parts non-empty, and
it also runs on the explicit provider="deepinfra" path, where a malformed id
raises a ValueError that shows the expected form.

deepinfra/ model strings previously routed through LiteLLM; is_litellm=True
keeps that path.

* fix(llms): reject malformed deepinfra/ ids before the LiteLLM fallback

A deepinfra/<model> reference that is not org/model fell through to
LiteLLM, so the same bad id failed later and differently depending on
what was installed. The prefixed form now raises the same ValueError as
provider="deepinfra", with the example and the echoed value written the
way the caller wrote the id; both branches share one helper.

---------

Co-authored-by: João Moura <joaomdmoura@gmail.com>
2026-10-09 05:12:19 -03:00
João MouraandClaude Opus 5.5 b3c4409bc5 feat(cli): record why an evaluation stopped before its verdict (#7963)
* feat(cli): record why an evaluation stopped before its verdict

`cli_usage:evaluate` counts presses of Evaluate and `cli_usage:eval` counts
evaluations that started, but about four in five presses never become an
evaluation and nothing said why. Every stop now counts once as
`cli_usage:eval_stopped:<reason>` from a closed list: untraced, declined,
no_project, login_unreadable, network_error, amp_401/403/404/4xx/5xx,
invalid_response, unexpected. The reason rides on EvaluationStoppedError from
where it is raised; messages, exit codes and screens are unchanged.

A run that `crewai eval` hands to the run app and that turns out untraced is
counted by the command only, so one stop is never counted twice.

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

* fix(cli): count each eval stop once, with the reason shown

- the run app answers for a delegated run it could not start, so the waiting crewai eval does not start it again and count the stop twice
- an unreadable saved login on the unattended path counts as login_unreadable, not untraced
- an evaluation AMP itself failed counts as evaluation_failed, in the CLI and the app; --models unchanged

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

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-09 04:50:12 -03:00
João MouraandClaude Opus 5.5 ed71a6f4d6 crewai eval --models: per-run cost and time, and no repeated progress lines (#7965)
* crewai eval --models: per-run cost and time, and no repeated progress lines

The comparison table printed each setup's cost and time summed over all
its runs, while the brief and the report say them per run. It now prints
cost_per_run / seconds_per_run under 'cost / run' and 'time / run' (the
totals, headed 'cost' / 'time', only when the service sends no per-run
figure; a column never mixes the two).

Progress deduped only against the previous line, so parallel setups made
polls alternate and the same lines printed again and again. Each line is
now said once per wait.

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

* Keep the per-run unit when a model is unpriced, and explain its dash

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

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 23:15:40 -07:00
Stoyan Dimitrov 274fba60f9 COR-891 Fix SQLite flow initialization contention (#7821)
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Check Documentation Broken Links / Check broken links (push) Has been cancelled
Vulnerability Scan / Detect changes (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Build uv cache / build-cache (3.10) (push) Has been cancelled
Build uv cache / build-cache (3.11) (push) Has been cancelled
Build uv cache / build-cache (3.12) (push) Has been cancelled
Build uv cache / build-cache (3.13) (push) Has been cancelled
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
* COR-891 Fix SQLite flow initialization contention

* fix: update vulnerable auth dependencies (COR-891)

* COR-891 Fix SQLite flow initialization contention
2026-10-08 16:19:30 -07:00
João MouraandClaude Opus 5.5 24a1ddf23f feat(cli): record what the run app's Deploy met before an attempt (#7964)
About half the presses of Deploy in the run app never reach a deployment
attempt, and nothing said why. With no saved login the press raises before the
attempt is counted and prompts for one. That prompt now counts once as
`cli_usage:deploy_login_prompted`, and a press that still never reaches an
attempt counts as `cli_usage:deploy_stopped:<reason>`: login_still_required,
login_abandoned or login_failed. Counting re-raises; what the user sees is
unchanged.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 20:03:47 -03:00
João Moura 1eff1d6bc9 feat: bump versions to 1.15.26 (#7961) 2026-10-08 18:42:32 -03:00