Commit Graph

2899 Commits

Author SHA1 Message Date
ViditOstwal
aecdbfc7d7 docs(cli): guide assistants to platform tools 2026-09-18 19:40:06 +05:30
ViditOstwal
0a8ecf30c1 test(platform): update missing token assertion 2026-09-18 19:40:05 +05:30
ViditOstwal
92552e88d5 feat(cli): prioritize platform integrations 2026-09-18 19:40:05 +05:30
João Moura
bbcebffbf9 fix(llm_overlay): a role and a key that differ only by surrounding whitespace match (#7572)
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
* fix(llm_overlay): a role and a key that differ only by surrounding whitespace match

A role that comes from a YAML file often ends in a newline — `role: >`
folds to "Researcher\n" — and a caller writes the key for the clean text,
"Researcher". The two never matched, so the agent kept its declared llm
without a word: the overlay looked active and did nothing.

`llm_overlay(mapping)` now sets a copy of the mapping with the whitespace
around each key dropped, and `overlay_model_for(role)` strips the role
before looking it up; an empty or None role matches nothing. Matching is
otherwise unchanged: exact text, no case folding. The mapping the caller
passed is not touched. The three readers (Agent at construction and after
interpolation, LiteAgent at construction) already go through
overlay_model_for, so they pick this up with no change of their own.

Tests: a key "Researcher" matches "Researcher\n" and "  Researcher "; a
key written with a trailing newline matches a clean role; case and inner
whitespace still miss, as do "" and None; the caller's mapping is not
mutated; a YAML-folded template role matches after interpolation.

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

* fix(llm_overlay): two keys that are one role with different models are refused

Review on #7572 (CodeRabbit, iris-clawd): after stripping, "Researcher" and " Researcher " are one key, and the
later entry silently won — the model an agent ran on depended on dictionary order. `_stripped` now refuses a
mapping that names one role twice with different models (ValueError naming the role and both models) and keeps a
harmless duplicate that names the same model once. A test pins both.

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

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-18 10:02:33 -03:00
Vidit Ostwal
17feaf48fb fix(deps): upgrade soupsieve security patch (#7571)
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
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
Mark stale issues and pull requests / stale (push) Has been cancelled
2026-09-18 09:13:52 +02:00
João Moura
c3f83cd866 feat(llm): re-resolve llm_overlay after input interpolation rewrites an agent's role (#7518)
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
* feat(llm): re-resolve llm_overlay after input interpolation rewrites an agent's role

llm_overlay (#7500) resolves an agent's model at construction, by its role text.
A CrewBase crew declares roles as templates in YAML — "Researcher for {repo}" —
that Crew._interpolate_inputs rewrites at kickoff, after construction. An overlay
keyed by the interpolated role, which is the text every trace records, never
matched: on a production flow a plan routed 3 of 5 agents and left the two
templated ones on their declared model.

Agent.interpolate_inputs now looks the overlay up again when the rewrite changed
the role: a key sets llm to the mapped model (create_llm, as construction does),
carrying the streaming flag Crew.kickoff(stream=True) set on the instance it
replaces; a miss, no active overlay, or an unchanged role leaves llm exactly as
it is — construction's resolution and instance stand, nothing reverts. The
executor binds agent.llm per task, after interpolation, so the task runs on the
new model (pinned through prepare_kickoff). Not followed by the swap, documented:
a task's string guardrail LLM, an auto-created Memory LLM, the crew_creation span.

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

* fix(llm): read llm_overlay once per agent — a re-validation must not replace an llm the agent already runs on

Found while battle-testing the previous commit with real calls: the event bus registers
an agent in its RuntimeState the first time it emits, and RuntimeState(root=[agent])
re-runs Agent.post_init_setup on the same object. Inside a block that maps the agent's
role, the construction-time overlay read (#7500) then replaced the llm the agent was
already running on and dropped the state set on it (stream=True). An agent built outside
the block picked the mapped model up on its second standalone kickoff inside one, against
#7500's own contract; Crew.replay inside a block did the same.

A private flag marks the construction-time read as done; a re-validation keeps the llm the
agent has — the one construction resolved, or the one interpolate_inputs set when the
role changed. Copies (kickoff_for_each) are new instances and read the overlay as before.
Zero-cost tests through RuntimeState; docstrings corrected (a crew Memory built at kickoff
does follow the swap; a stream must be iterated inside the block).

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

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-17 16:54:00 -03:00
Vidit Ostwal
977aa0c6ec feat(cli): improve platform integration setup UX (#7453)
* fix(cli): silence tool import warnings during platform setup

* feat(cli): validate platform integrations concurrently

* fix(cli): persist platform token during crew setup

* fix(core): make settings write probe concurrency-safe

* test(cli): simplify event loop fallback stub
2026-09-17 11:35:32 -07:00
gaoanze888
597b99fb57 fix(tools): preserve directory listing paths (#7548)
Co-authored-by: gaoanze <gaoanze@meituan.com>
Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-17 22:47:38 +05:30
mairaarshad19
b9629cfb8f feat: add native Gemini 3.8 Flash support (#7284)
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
* feat(llm): add Gemini 3.8 Flash support

- Register Gemini 3.8 Flash in CrewAI and CLI model catalogs
- Add 1,048,576-token context window mapping
- Add native Gemini provider support
- Add Gemini 3.8 Flash to the CLI model picker
- Add native model detection coverage for gemini/ and google/ formats
- Add context window regression coverage

Closes #7241

* test: add VCR cassette for gemini-3.8-flash

* chore: stop tracking .env.test

* Bringing back .env.test

---------

Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
Co-authored-by: ViditOstwal <viditostwal@gmail.com>
2026-09-17 08:59:36 -07:00
Sharoon Sharif
5c33fe4c71 fix: close sqlite connections in flow persistence and sqlite provider (#7511)
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
Vulnerability Scan / Detect changes (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
Apply the same contextlib.closing pattern accepted in #7493 to the nine
remaining library-side sqlite3.connect sites: SQLiteFlowPersistence
(init_db, save_state, load_state, save_pending_feedback,
load_pending_feedback, clear_pending_feedback) and SqliteProvider
(checkpoint, prune, from_checkpoint). The connection context manager
only commits or rolls back, so the connections survived in a reference
cycle and kept flow_states.db / checkpoint databases locked on Windows.
Also close the read-back connections in test_checkpoint.py, which made
its TemporaryDirectory cleanup fail on Windows for the same reason.
Add lifecycle and failure-path regression tests.

Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-17 07:37:38 +00:00
子涵的代码日记
b34023d6bc fix(llm): collapse multimodal content with the shared helper (#7527)
For response_model calls the messages are flattened into one prompt for
InternalInstructor with an f-string, so a multimodal content list reached the
model as its Python repr. AGENTS.md's "Message Content" section says never to
str() the content; use message_content_text() instead.
2026-09-17 12:44:06 +05:30
Lorenze Jay
7a01af2791 [docs-freeze] docs: snapshot and changelog for v1.15.22 (#7521)
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
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
1.15.22
2026-09-16 15:09:40 -07:00
Lorenze Jay
b0343eb75f feat: bump versions to 1.15.22 (#7520) 2026-09-16 22:04:49 +00:00
Vinicius Brasil
64ab0112bd Support aliases as connection identifiers (#7519)
* Support private app connections

App selectors only accepted UUID connection identifiers, so apps=["github@private"] failed validation.

Accept connection aliases and route them through Clipper like UUID identifiers. This supports private connections and future platform aliases without client releases.

* chore: update tool specifications

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-09-17 00:54:00 +05:30
João Moura
5990ead5ec feat(cli): record why a deployment create failed (#7451)
* feat(cli): record why a deployment create failed

`crewai deploy create` counts every attempt (`Create Crew Deployment`) and every
success (`Crew Deployment Created`), but the gap between them carried no cause:
among clients able to emit the success span, the CLI succeeds 96.7% of the time
and the run TUI 36.4%, and nothing said why. A third span, `Crew Deployment
Failed`, now fires for every failure after the attempt is counted, with a closed
vocabulary `reason` (api_4xx, api_5xx, invalid_response, network_error,
zip_error, user_declined, unexpected), the HTTP `status_code` when the API
answered, and the existing `source`. Never the error message.

The request path is factored into `_request_crew_creation`; every exception is
classified, reported and re-raised unchanged, so CLI and TUI behaviour is the
same as before. HTTP failures are classified before `_validate_response`, which
still prints and exits as it did.

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

* fix(cli): classify deploy create failures by status and by stage

Review fixes on the failure span. Check the HTTP class before the body so a
gateway's HTML page counts as api_4xx / api_5xx with its code. Treat a 2xx
whose body is not a JSON object carrying uuid and status as invalid_response
and exit cleanly, instead of emitting a success span and crashing in the
display step. Recognise archive failures by a dedicated ArchiveError
(a ValueError) raised from create_project_zip, so the git helpers' own
ValueErrors no longer read as zip_error; a failed ZIP write is wrapped and
its partial file removed.

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

* fix(cli): treat staging and temp-file failures as archive errors

`create_project_zip` only wrapped the ZIP write, so an `OSError` while
staging files or creating the temporary archive escaped as a bare
`OSError` and the deploy command recorded it as `unexpected` instead of
`zip_error`. The archive boundary now covers staging, temp-file creation
and the write; the staging directory is removed on every path, and no
partial archive is left behind.

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

* feat(cli): tell a non-JSON 2xx apart from a non-creation 2xx

A proxy's 200 HTML page and a JSON body missing the creation fields were
both recorded as `invalid_response`. They are different failures, one in
the network path and one in the API contract, so the deploy failure span
now records `invalid_json` for the first and `invalid_creation_response`
for the second. Requested in review.

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-16 23:37:14 +05:30
João Moura
32a9d2ae7b feat(tracing): collect human feedback and pause events in the trace (#7499)
* feat(tracing): collect human feedback and pause events in the trace

The trace listener subscribed to method and conversation events but not to
the review-gate events or the pause events, so a `@human_feedback` gate
reached the trace only as method_execution_started/finished. A trace could
not say that a run stopped for review, what the reviewer was shown, or what
they answered.

Subscribe to HumanFeedbackRequestedEvent, HumanFeedbackReceivedEvent,
MethodExecutionPausedEvent and FlowPausedEvent through `_handle_action_event`,
as the conversation events are, with the event's own type as the trace type.
Each is a whole-event payload via the default serialization path; no change
to `_build_event_data` or `complex_events`.

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

* fix(tracing): register the gate and pause handlers through _on, keeping the execution-uuid gate

The four new handlers, and the conversation handler this branch had switched by
mistake, registered with event_bus.on and so ran while a kickoff owned an execution
uuid — the case where the OTEL session records these events and the legacy collector
must stay idle. Restored to self._on like every other handler; a test binds an
execution uuid and asserts none of the five are collected into a legacy batch.
Docstrings on the handlers (review bot coverage note).

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

* test(tracing): under a tracing kickoff the session records the gate and pause events and the legacy batch stays empty

Two real flows under an in-memory tracing session (the lifecycle tests' pattern): a
@human_feedback gate answered at the console records human_feedback_requested and
human_feedback_received as spans; an async provider that parks the flow records
method_execution_paused and flow_paused. In both the legacy collector, gated by _on,
collects none of the four. Review bot: the uuid-gated test alone would have passed
with the session registrations missing.

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-16 16:41:09 +00:00
wangtao
c0af9badb8 fix(skills): accept CRLF in inline skill definitions (#7504)
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
Co-authored-by: wangtaotaotao95 <328929485+wangtaotaotao95@users.noreply.github.com>
Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-16 19:35:35 +05:30
Ray
b4fd395d8d fix(rag): load text file URLs through the safe fetcher (#7506) 2026-09-16 13:51:05 +00:00
Sharoon Sharif
2c24b95eae fix(memory): close sqlite connections in kickoff task outputs storage (#7493)
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(memory): close sqlite connections in kickoff task outputs storage

`with sqlite3.connect(...) as conn` only commits or rolls back; it never
closes the connection, which then survives in a reference cycle until a
cyclic GC pass. Every Crew kept an open handle on
latest_kickoff_task_outputs.db, so on Windows the file stayed locked and
any later delete, rename or temp-dir cleanup failed with PermissionError
(WinError 32). Wrap each connection in contextlib.closing, keeping the
existing commit/rollback semantics, and add regression tests.

* test(memory): cover rollback and close on a failed write

---------

Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-16 07:47:39 +00:00
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
c1beddf1a6 feat(llm): add llm_overlay contextvar to route agent roles to models (#7500)
A per-run caller sometimes needs specific agents on a different model
without editing the code that builds them. `crewai.llm_overlay` adds a
process-context `role -> model` overlay:

    with llm_overlay({"Researcher": "openai/gpt-4o"}):
        crew.kickoff()

The overlay is read in the only two places an agent resolves its model from
its role: `Agent.post_init_setup` and `LiteAgent.setup_llm`. When the role is
a key, `create_llm` receives the mapped model instead of the declared `llm`;
otherwise, and outside the block, nothing changes. `create_llm` itself stays
role-blind.

The overlay is a ContextVar, so it follows the calling context and is always
reset on exit. It does not cross plain threads; callers threading agents must
propagate the context with `contextvars.copy_context().run(...)`. The module
docstring says so and a test pins the behaviour.

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:41:47 +05:30
Swapnil Yadav
a59cf26f56 fix(files): raise ValueError instead of bare raise in get_uploader (#7283)
* fix(files): return None instead of bare raise in get_uploader

get_uploader is documented to return None for an unsupported provider, and
every caller branches on `if uploader is None`. Two fallthrough paths ran a
bare `raise` with no active exception, so an unknown provider and a Bedrock
provider without a configured S3 bucket raised
"RuntimeError: No active exception to reraise" instead of returning None.

Return None in both paths and widen the return types to `... | None`. The
Bedrock "not configured" guard now treats a falsy bucket_name (None or "") as
unconfigured, not only an absent one. The except ImportError re-raises are
unaffected.

Fixes #7282

* fix(files): raise ValueError from get_uploader for unknown/unconfigured providers

Per review, raise a ValueError with a concrete reason instead of returning
None. Returning None let the resolver silently fall back to inline and hid the
misconfiguration from the user, so the docstring no longer promises None and
the return types drop `| None`. The Bedrock guard also treats a falsy
bucket_name (None or "") as unconfigured. The ImportError re-raises are
unchanged.

cleanup skips providers it cannot build an uploader for, so it routes
get_uploader through a local helper that treats the ValueError as
"unavailable" and continues the pass.

* refactor(files): surface get_uploader errors through the resolver

Follow-up to review. get_uploader now raises ValueError, so _get_uploader no
longer promises FileUploader | None: it returns the uploader and lets the error
propagate through resolve() to the caller instead of swallowing it and falling
back to inline. Drop the now-dead `if uploader is None` checks at the two
upload call sites.

Also make the unknown-provider ValueError list the supported providers, and add
a happy-path test that a configured provider returns its uploader.

* fix(files): surface uploader lookup errors in async batch resolution

aresolve_files gathers with return_exceptions=True, which was silently dropping
files when _get_uploader raised (a missing provider SDK, or an unknown or
unconfigured provider). A batch shares one provider, so such a lookup failure
applies to every file: re-raise ValueError and ImportError to surface it,
matching the sync resolve_files path. Genuine per-file upload errors are still
logged and skipped.

* fix(files): only re-raise uploader config errors in async batch resolution

The earlier fix re-raised any ValueError or ImportError from
asyncio.gather(return_exceptions=True), so one unrelated per-file error
(for example a stream that raises ValueError when read) aborted the whole
batch instead of the intended log-and-skip.

_get_uploader now translates the lookup failure into a dedicated
UploaderConfigurationError, and aresolve_files re-raises only that, since
it applies to every file for the provider. Ordinary per-file failures stay
best-effort. Adds regression tests for the wrap, a provider-setup error
surfacing from the batch, and an unrelated per-file error skipped while
the rest resolve.

* style(files): apply ruff import sort and formatting to resolver tests

---------

Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-16 06:41:25 +00:00
João Moura
1c64c84cd8 feat(tracing): carry task_prompt and output in agent_execution payloads (#7498)
`agent_execution_started` and `agent_execution_completed` are in
`complex_events`, so `_build_event_data` hand-builds their payloads. Those
payloads shipped only agent_role/goal/backstory and dropped two required bus
fields: `AgentExecutionStartedEvent.task_prompt` and
`AgentExecutionCompletedEvent.output`. A trace therefore said which agent ran
but not what it was asked or what it answered.

Add `task_prompt` to the started payload and `output` to the completed one,
whole and untruncated. No new event types, no TraceEvent change.

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 11:56:33 +05:30
Rohit Kanithi
9473098af5 fix(flow): support non-primitive types in SQLiteFlowPersistence (#7358) (#7376)
* fix(flow): support non-primitive types in SQLiteFlowPersistence (#7358)

* test(flow): add docstrings to test classes and step methods

* fix(flow): serialize Decimal and Path as strings in SQLite persistence

* fix(flow): dump BaseModel with mode=python to allow fallback serialization on Any fields

* fix(flow): prioritize model_dump mode=json with fallback to mode=python

* ci: re-trigger test suite

---------

Co-authored-by: Rohit Kanithi <rohitkanithi@users.noreply.github.com>
Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-16 06:01:07 +00:00
João Moura
6b6a39d503 fix(events): Improve coding agents instructions (#7447)
* feat: scaffold project with assistant instruction files

- Updated project creation to include `CLAUDE.md` and `GEMINI.md` that import `AGENTS.md`, ensuring consistent guidance across coding assistants.
- Implemented utility functions to copy assistant instruction files during project setup.
- Enhanced documentation in `AGENTS.md` to emphasize the importance of keeping telemetry enabled for optimal performance.
- Added tests to verify the correct scaffolding of assistant instruction files and their contents.

* fix(cli): neutral observability guidance in scaffolded AGENTS.md

- State the observability rule as the user's decision, never a fix for
  console warnings, speed, or a "clean" configuration
- Rewrite the AMP section as built-in capabilities: no "free",
  "proactively", "sales pitch", or scripted pitches
- Turn the research mandate into a list of sources to consult when
  version details matter
- Retarget the scaffold tests to the new wording

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

* fix(cli): scaffold assistant files for JSON crews and harden telemetry tests

- create_json_crew, the default `crewai create crew` path, now copies
  AGENTS.md, CLAUDE.md and GEMINI.md; AGENTS.md documents the JSON layout
- span helper no longer depends on OTEL_SDK_DISABLED being popped by an
  earlier test; thread-scope test stops its worker before leaving the mock
- single import style in the shutdown test

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

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 02:07:57 -03:00
Lorenze Jay
993a96c4e0 feat(tracing): port trace events sessions to OSS (#7464)
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 / 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
* feat(tracing): port enterprise event sessions to OSS

* fix(tracing): address review findings and verify concurrent exports

* fix(tracing): keep redactor ownership in enterprise integrations

* test(tracing): isolate intentional failures from cleanup assertions
2026-09-15 13:09:40 -07:00
Sharoon Sharif
756d8d33c8 fix(cli): read json checkpoints as utf-8 (#7491)
JsonProvider writes checkpoints with encoding="utf-8" and the runtime
serialises non-ASCII text verbatim, but the checkpoint CLI still opened
them with the platform default encoding. On Windows (cp1252) `crewai
checkpoint info` raised UnicodeDecodeError and `list` showed a 0-byte
entry for any checkpoint containing non-ASCII text. Open the files as
UTF-8 and add regression tests for the three readers.
2026-09-15 16:52:54 +00:00
Vidit Ostwal
667420f207 ci: grant PR comment fallback permission (#7489) 2026-09-15 21:19:35 +05:30
Sharoon Sharif
0e2fa7ec24 fix(cli): overwrite stale poetry.lock backup on windows (#7463)
Some checks failed
CodeQL Advanced / Analyze (python) (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
* fix(cli): overwrite stale poetry.lock backup on windows

os.rename raises FileExistsError on Windows when poetry-old.lock already
exists from a previous run, so a second `crewai update` crashed there
while POSIX silently replaced the file. Use os.replace, which overwrites
on every platform, and add a regression test.

* test(cli): add docstrings to update_crew tests

---------

Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-15 15:37:03 +00:00
哈基米
b66f3f215a fix(azure): key streamed tool calls by wire index (#7487)
Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-15 20:57:04 +05:30
絜矩
7b79662372 fix(gemini): preserve fileData content parts (#7479)
* fix(gemini): preserve fileData content parts

* test(gemini): cover media-only fileData messages
2026-09-15 14:52:07 +00:00
Roli Bosch
c6ff78650e fix(memory): honor read_only on update() and recall() access times (#7369)
`Memory.read_only` was enforced only on `remember()` and `remember_many()`.
Two other paths still mutated the backing store:

- `update()` re-embedded the supplied content and wrote the record back.
- `recall()` refreshed `last_accessed` through `touch_records()`, so simply
  reading a read-only memory left a persistent trace.

Both now respect the flag, so a read-only Memory leaves stored records
unchanged. `update()` returns the existing record untouched rather than
raising, matching the silent no-op behaviour of `remember()`. Explicit
deletion through `forget()`/`reset()` is deliberately unaffected.


Claude-Session: https://claude.ai/code/session_01HkDjVYVzHFEj5re9B8JH9p

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-15 11:20:49 +00:00
João Moura
66ef97c73e fix(llms): send reasoning_effort to every openai reasoning model (#7187)
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
Mark stale issues and pull requests / stale (push) Has been cancelled
* fix(llms): send reasoning_effort to every openai reasoning model

The completions path gated the parameter behind
is_o1_model = "o1" in model.lower(), a literal substring test. gpt-5, o3 and
o4-mini contain no "o1", so an explicitly configured effort was dropped and the
model thought at the server default. The request still succeeded, so nothing
surfaced -- one measured extraction ran 6.2s with the setting applied against
149.7s with it dropped.

The gate could not be widened: is_o1_model also drives
supports_function_calling, supports_stop_words and the system->user message
rewrite, so marking gpt-5 as an o1 model would report that it cannot call
tools. The parameter is forwarded unconditionally instead, matching the
responses path, and a model that genuinely does not support it says so in a 400
that is retried once without the key.

Also adds "minimal" to LLM.reasoning_effort, which gpt-5 accepts and the
Literal omitted, so the cheapest setting was unreachable on the typed surface.

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

* refactor(llms): gate reasoning_effort on model shape, not every model

Forwarding to every model made a non-reasoning model pay a rejected request
and a retry on every call. `_supports_reasoning_effort` matches on shape
instead -- the o-series, and GPT generation 5 onwards -- so gpt-4o and gpt-4.1
never send the parameter at all.

Matched by shape rather than by a list of names so a new member of an existing
family works without a release here; gpt-6 and o5 already classify correctly.
The unsupported-parameter retry stays as a safety net for the case the shape
match is wrong for a future family, where it costs nothing when the match is
right.

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

* fix(llms): honour reasoning_effort on compatible servers and fine-tunes

Review follow-ups. A fine-tune (ft:<base>:...) is judged by its base model.
On an OpenAI-compatible server -- anything whose effective base URL is not
api.openai.com, whether set explicitly, via env, or by a provider subclass --
the model name is the server's namespace and says nothing about support, so an
explicit setting is sent as configured; a 400 naming the parameter, in whatever
words the server uses, is recovered by retrying without it, unless it reads as
a complaint about the value. A model that rejected the parameter is remembered
per (endpoint, model) for the process so the rejected call is paid once, and
the drop is logged as a warning since a configured setting is not being
applied. The Literal also gains "xhigh", the remaining value the SDK accepts.

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

* fix(llms): recover reasoning_effort only on evidence the parameter is unknown

Two review follow-ups. The endpoint check now uses the same base URL precedence
as the client itself, so a `client_params` override selects the server. And a
rejection is recovered only when the message says the field is not one the
server knows -- OpenAI's two shapes plus the common compatible-server wordings
("unknown field", "Extra inputs are not permitted") -- rather than any 400 that
lacks a value-sounding word. A pydantic enum complaint such as "Input should be
'low', 'medium' or 'high'" names the parameter but is about its value, and
surfaces instead of being dropped.

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

* fix(llms): remember a reasoning_effort rejection only after the retry succeeds

Two review points on the reasoning_effort fallback. The rejection was recorded
before the retry ran, so a retry that died for an unrelated reason (a dropped
connection, say) silently stopped sending the configured effort for the rest of
the process even though a call without it had never succeeded; the (endpoint,
model) is now remembered only once the retry returns. And _effective_base_url
accepted only a str override in client_params while the SDK, and
_get_client_params, accept httpx.URL too, so a compatible deployment configured
with a URL object was detected as OpenAI and its rejection keyed under the wrong
endpoint; both forms are normalised to the string the client calls.

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

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-14 19:14:39 +00:00
theater
a225c1b373 fix(cli): don't crash the run TUI when streamed output contains a literal [...] (#7435)
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
* fix(cli): reject non-serializable literal_eval results in TUI JSON formatting

_try_parse_structured() accepted any dict/list coming out of
ast.literal_eval(), including values json.dumps() cannot encode such as
[Ellipsis] from a literal [...]. _format_json_in_text() then raised
TypeError: Object of type ellipsis is not JSON serializable, which
propagated through _tick and cancelled the whole crew run.

Validate the parsed object with json.dumps() inside
_try_parse_structured() so only JSON-serializable dict/list values are
returned; anything else falls back to the original text. Fixes #7434.

* fix(cli): contain RecursionError in the TUI JSON formatting boundary

A streamed structure nested deeper than the JSON backend can walk could
raise RecursionError out of _try_parse_structured (from json.loads) or
out of the render-path dumps, escaping _tick and losing the TUI update.

Catch RecursionError when loading, and validate literal_eval results
with the exact kwargs the render path uses, so any structure the render
cannot encode is rejected at the boundary and the raw text renders
instead.

---------

Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-14 20:41:33 +05:30
Shivangi
a328710007 fix: reject replay when stored tasks differ (#7155)
* fix: reject replay when stored tasks differ

* fix: validate replay task descriptions

* fix: reject ambiguous replay task identities

* fix: persist stable replay task keys

* test: align legacy replay fixture

---------

Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-14 15:52:31 +05:30
Modusensus
7e80d94921 fix: use sys.platform guards so mypy passes on Windows (#7401)
mypy does not narrow on `platform.system()`, so Windows-based contributors
get 8 spurious attr-defined/unused-ignore errors from the termios and
resource imports. Switch to `sys.platform` comparisons, which mypy
understands natively, and drop the now-unneeded type-ignore comments.

Fixes #7400

Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-14 14:38:50 +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
Melanie Hart Buehler
21678f8ac6 docs(rag): add xpu to embedding device options (#6808)
* docs(rag): add xpu to embedding device options

* address copilot review

* docs(rag): sync Korean and Portuguese RagTool pages

---------

Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-14 05:51:43 +00:00
Vidit Ostwal
894898f84c ci: welcome first-time contributors after merge (#7397)
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
Mark stale issues and pull requests / stale (push) Has been cancelled
* ci: welcome first-time contributors after merge

* ci: welcome first-time contributors after merge

* ci: support fork contributor welcome comments

* ci: minimize contributor welcome permissions
2026-09-12 01:16:17 +05:30
Vidit Ostwal
93ad4d67c4 feat: validate platform integrations during crew setup (#7385)
* feat: validate platform integrations during crew setup

* fix: clarify platform integration validation

* refactor: split platform authentication workflow

* feat: list connected platform integrations
2026-09-11 12:20:33 -07:00
Vidit Ostwal
d20845f0a3 feat: add platform tools to JSON crew wizard (#7384)
* feat: support platform tools in JSON crews

* style: clarify platform integration labels

* fix: avoid repeating tool picker title

* fix(platform): surface JSON tool discovery errors
2026-09-11 12:13:55 -07:00
Vidit Ostwal
e1f3c4bdd4 feat: expose CrewAI Platform application catalog (#7383)
* feat: expose platform application catalog

* refactor: centralize platform application catalog

* fix: preserve platform application typing

* chore: remove unused platform app export
2026-09-11 21:02:00 +05:30
Vidit Ostwal
d5c7bac505 chore: update OpenRouter tool specifications (#7387) 2026-09-11 12:16:05 -03:00
Vidit Ostwal
004f7b58d5 test(bedrock): isolate session credential test (#7388) 2026-09-11 14:23:03 +00:00
Vidit Ostwal
c5759ce854 test(bedrock): verify environment credentials (#7375)
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
* test(bedrock): verify environment credentials

* test(bedrock): isolate credential environment test
2026-09-10 23:07:50 -07:00
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
8616dca5c0 docs: list all workspace packages (#6678)
Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-10 12:51:37 +05:30
Gamal Osama
c860613c7a feat(embeddings): add openrouter as a supported embedding provider (#7127)
* feat(embeddings): add openrouter provider type definitions

* feat(embeddings): implement OpenRouterProvider

* feat(embeddings): export openrouter provider package symbols

* feat(embeddings): register openrouter in allowed embedding providers

* feat(embeddings): register openrouter provider and overloads in factory

* feat(tools): add openrouter embedding service support

* test(embeddings): add comprehensive openrouter provider and factory tests

* test(embeddings): add openrouter build test in embedding factory

* test(embeddings): add openrouter model key alias and env tests

* test(tools): add openrouter tests for embedding service

* docs: add openrouter embedder configuration example

* docs(ar): sync openrouter embedder translation

* docs(ko): sync openrouter embedder translation

* docs(pt-BR): sync openrouter embedder translation

* feat(embeddings): allow model alias and None fields in OpenRouterProviderConfig

* fix(tools): resolve EMBEDDINGS_OPENROUTER_API_KEY before OPENROUTER_API_KEY

* test(tools): add regression tests for openrouter env var precedence and fallback

* feat(embeddings): drop organization_id and resolve api_key via OPENROUTER_API_KEY only

* fix(tools): use OPENROUTER_API_KEY in embedding service and update tests

* docs: switch openrouter knowledge example to model_name and document OPENROUTER_API_KEY

* fix(tools): default openrouter model to namespaced openai/text-embedding-3-small

---------

Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-10 12:24:15 +05:30
Rohit Kanithi
4bfdb0df67 fix(tools): align DOCXSearchTool with standard RAG fixed schema pattern (#7356) (#7357)
Co-authored-by: Rohit Kanithi <rohitkanithi@users.noreply.github.com>
Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-10 11:16:08 +05:30
Lorenze Jay
a8d330de00 [docs-freeze] docs: snapshot and changelog for v1.15.21 (#7363) 1.15.21 2026-09-09 22:54:07 +00:00