Compare commits

...

110 Commits

Author SHA1 Message Date
Joao Moura
de27566eb3 feat(cli): send the project's own id with the evaluation
crewAI mints a project id into pyproject.toml and it is committed, so it is
the same id on every machine, in CI, and for a teammate. `crewai eval`
already read it on its way past and threw it away; it now travels with the
request, so a project's evaluations can be shown together rather than each
run standing alone.

Omitted entirely outside a crewAI project, where there is no id to send.

85 passed; ruff and mypy clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-21 14:32:24 -07:00
Joao Moura
0185dc7a22 fix(cli): the login needs an encrypted connection, and a grade is an integer 1..5
Two CodeRabbit findings on the credential-routing change.

- _origin() accepted http://, so a trusted-but-cleartext AMP would still
  have received the bearer token in a header. The credential now also
  requires an encrypted connection: HTTPS, or plain HTTP to this machine
  (localhost, its subdomains, loopback), which is the rule
  TraceGrantClient already applies to collector grants. Anything else
  reads the run anonymously and says which of the two reasons applies.
- A verdict's grades were checked with isinstance(grade, int), which
  accepts True and 6; both would have printed as real grades and let the
  command exit 0. A grade is now an exact int in 1..5, or null.

Tests: a trusted http origin gets no credential, localhost does, the
encryption rule itself over nine origins, and four more malformed verdicts
(bool, 6, 0, 4.5). 56 passed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-21 08:34:42 -07:00
Joao Moura
0f6e499df5 fix(cli): the saved login goes only to an AMP this machine is logged in to; only a missing login reads as anonymous
Two review findings.

- Loading the project's .env (so `crewai eval` asks the AMP the run was
  traced to) also let a project's .env choose where the saved bearer token
  goes. The request still follows the project's CREWAI_PLUS_URL, because
  that is how a self-hosted project is wired and the run really is there,
  but the credential now goes only to an origin this machine is logged in
  to: `crewai enterprise configure`'s saved settings, an address already
  exported in this shell (read before .env is loaded), or app.crewai.com.
  Anywhere else the run is read anonymously and the command says so, naming
  `crewai enterprise configure`. The wider hole is not this command's:
  `crewai run` sends the same token to the same .env-chosen URL, and that
  is worth a separate look.
- saved_login() caught every exception and returned None, so an unreadable
  credential store — a rotated key, a directory left owned by root — read
  as "anonymous", quietly spending the run's one anonymous read and then
  refusing a user who believes they are logged in. Only AuthError means
  anonymous now; anything else is reported with its cause and a pointer to
  `crewai login`. This matches tracing_credential() in the library, which
  catches AuthError alone.

Tests: a project pointing elsewhere is read anonymously with the message
and no token; a shell-exported AMP is trusted; the configured AMP keeps the
token and says nothing; the origin rule itself; AuthError versus an
unreadable store. 41 passed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-20 22:42:43 -07:00
Joao Moura
d849f9d7d1 fix(cli): crewai eval — Enter accepts the offer to run the crew (y/n, Y default; the prompt names both effects)
João's call (2026-09-20): the confirm is y/n with Y as the default. The
prompt still says tracing stays on in .env and that the crew runs now.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-20 13:54:00 -07:00
Joao Moura
3f21d108d5 fix(cli): crewai eval — the credential goes only to the configured AMP; an explicit yes before running the crew; a done answer needs a well-formed verdict
Review findings (CodeRabbit, the PR gate):

- The record's amp_base_url was handed to PlusAPI beside the saved login,
  so a modified .crewai/last_run.json could send the token to any origin.
  The client is now built from the configured AMP only (CREWAI_PLUS_URL,
  the saved settings, app.crewai.com); the project's .env is loaded first,
  as `crewai run` loads it, so the configured AMP is the one the run was
  traced to. A record naming another address gets a one-line note and no
  credential.
- The offer to turn tracing on and run the crew defaults to no and says
  the .env change stays; Enter no longer spends a crew run.
- A `done` answer whose verdict is missing or malformed (no gate, grades
  not an object, a grade not an int or null) is a protocol error, exit 1,
  instead of an INCONCLUSIVE line with exit 0 or an AttributeError.

Tests for each: a foreign origin in the record with a saved token, the
.env-loaded same-AMP case, seven malformed verdicts, the prompt's text and
default. 59 passed (eval + plus_api); ruff and mypy clean.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-20 10:08:27 -07:00
Joao Moura
5ac9c052d8 fix(cli): crewai eval — guard the project, survive AMP blips, name the right subject, read the whole record
Review findings, each reproduced before the fix:

- The run-it-now offer wrote CREWAI_TRACING_ENABLED into ./.env before
  checking the directory is a crewAI project, then run_crew() died on a
  missing pyproject.toml with a traceback. Now: no pyproject.toml → one
  sentence, exit 1, nothing written.
- httpx errors (AMP unreachable, a timeout) surfaced as tracebacks. Now
  the start says "Could not reach AMP to start the evaluation: …"; while
  waiting, an unreachable AMP or a 5xx is retried up to POLL_RETRIES
  consecutive times, then reported with the URL — the evaluation keeps
  running server-side either way.
- The POST now carries a 120 s timeout (AMP reads the run's spans inside
  it), the poll 30 s.
- A 200 whose body has no known status (a non-dict, no status, a status
  outside queued/running/done/failed) polled forever. Now it stops with
  the status it saw and the URL.
- A 404 without a JSON message read "AMP holds no run <evaluation id>"
  while polling. _refused takes "run <id>" / "evaluation <id>" and says
  "AMP answered 404 for <subject>" — AMP's own message still wins.
- The record's amp_base_url was ignored; the CLI now evaluates the run at
  the AMP it was traced to. --run keeps the configured AMP.
- The post-run explanation names the third cause: a crewai older than the
  version that records the last run.

Tests for each, plus the previously untested paths: Ctrl-C exits 130, a
2xx without an id, a refusal mid-poll, DMN opens no browser, --run skips
the offer. 51 passed in lib/cli/tests (eval + plus_api).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-20 01:51:13 -07:00
Joao Moura
8640cda042 feat(cli): crewai eval evaluates the last traced run through AMP
`crewai eval` reads `.crewai/last_run.json` — the record crewAI writes
when a traced run's spans reach Wharf — and asks AMP to evaluate that
run: POST /crewai_plus/api/v1/tracing/evaluations with the execution id,
sending the saved `crewai login` when there is one and nothing otherwise.
AMP answers with an evaluation id and a URL; the command prints the URL,
opens it, waits for the verdict and prints it (goal gate and the four
grades), exit 1 only when the evaluation itself failed. `--run
EXECUTION_ID` evaluates another run.

With no traced run recorded it offers to turn tracing on for the project
(`CREWAI_TRACING_ENABLED=true` in .env, set_key so nothing else in the
file moves) and run the crew now with `crewai run`; without a terminal, or
declined, it prints the three steps instead. A run that leaves no record
behind is explained, never guessed at.

AMP's refusals are printed in its own words: a run that needs an account
(401 account_required), a refused credential (then `crewai login`), a run
AMP does not hold (404), rate limiting (429 with Retry-After), and any
other status with AMP's message. The two AMP calls live on the CLI's
PlusAPI subclass, so no crewai-core release is needed.

Who may evaluate what is AMP's decision, not the command's: an anonymous
run once without an account, then it needs one; a run traced while logged
in for that organization's members; a deployment execution for members
who may see its traces.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-20 00:53:52 -07:00
João Moura
0374c63129 feat(tracing): task spans say the declared output format and what came out, agent spans carry the prompt and answer, tool spans say whether the cache answered (#7597)
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
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
* feat(tracing): record the task's declared output format, the agent's prompt and answer, and the tool cache flag on their spans

A reader of a run's OTel spans could see a task's raw output but not the
format it declared, nor whether a Pydantic object or a JSON dict actually
came out of it; could see an agent's goal, backstory and model but not the
prompt it was handed or the answer it gave; and could see a tool's result
but not whether the tool ran or the cache answered.

execute task: crewai.task.output_format (json / pydantic / raw; from the
declaration on start and failure, from the TaskOutput on completion),
crewai.task.output_pydantic_produced, crewai.task.output_json_produced.

execute agent: gen_ai.input.messages carries the task prompt and
gen_ai.output.messages the answer, the spec shape the task span already
uses for its own text, under the existing per-attribute byte cap with the
.truncated / .original_size_bytes markers when cut.

call tool: crewai.tool.from_cache.

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

* test(tracing): the agent's prompt and answer leave under the two standard message keys and no other

Pins the review decision on #7597: the text travels as
gen_ai.input.messages / gen_ai.output.messages — the keys the call llm
span already exports its messages under — so a rule an exporter or a
redaction processor applies to LLM content by key name applies to the
agent span unchanged. A copy under a crewai.agent.* key would fail this.

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

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-19 19:38:04 -03:00
Lorenze Jay
3831e8b6c8 ensure link is shown after finalizing traces (#7593)
Some checks failed
Build uv cache / build-cache (3.10) (push) Has been cancelled
Build uv cache / build-cache (3.11) (push) Has been cancelled
Build uv cache / build-cache (3.12) (push) Has been cancelled
Build uv cache / build-cache (3.13) (push) Has been cancelled
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
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
2026-09-18 20:13:44 -03:00
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
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) 2026-09-09 22:54:07 +00:00
Lorenze Jay
d469e9fb2b feat: bump versions to 1.15.21 (#7362) 2026-09-09 22:29:18 +00:00
João Moura
d729cade6b fix(openai): surface gateway errors reported inside an HTTP 200 (#7342)
* fix(openai): surface gateway errors reported inside an HTTP 200

OpenAI-compatible gateways commit `200 OK` as soon as the upstream provider
accepts a request, so a later provider failure arrives in the body as an
`error` object with no `choices`. That reached the SDK's parse helper and
surfaced as `TypeError: 'NoneType' object is not iterable`, naming neither the
provider, the status, nor the fact that a timeout happened.

The four non-streaming paths now inspect the raw body before parsing and raise
the exception the upstream code maps to, so a masked 504 is catchable exactly
like an honest one. Streaming already had this guard inside the SDK.

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

* test(openai): teach the tool-cache fake about with_raw_response

The provider now reads the raw body before parsing, so a client double that
only implements `create` no longer satisfies it. Same shape as the fixes to the
reasoning-effort retry and Snowflake doubles.

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

* test(tracing): reset the TraceCollectionListener singleton between tests

TraceCollectionListener caches a TraceBatchManager on the class and
`_initialized` short-circuits `__init__`, so batch state survives for the whole
xdist worker. `test_nested_agent_executor_flow_does_not_finalize_parent_batch`
left `trace_batch_id="debug-trace-batch"` behind, which moved every later trace
POST from /tracing/ephemeral/batches to /tracing/batches/<id>/events. The
recorded cassette then stopped matching, the agent retried, and the second call
found the cassette consumed -- surfacing as ConnectionError in an unrelated
test hundreds of tests later.

Reproduced deterministically by running the leaking test followed by
tests/tracing/test_trace_enable_disable.py::test_trace_calls_when_enabled_via_env;
fails on a68b5e903 too, so this predates the gateway fix it was blocking.

An autouse fixture now clears the cached instance after each test. Two canaries
pin the invariant and fail without the fixture.

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

* test(tracing): drop the unwritable _listeners_setup canary

Both review bots flagged that the canary read `_listeners_setup` off the class,
where it is always False, so it could never fail. Correct, and the suggested fix
does not work either: `BaseEventListener.__init__` calls `setup_listeners`
(base_event_listener.py:16), which sets the flag on the instance
(trace_listener.py:229), so reading it back through `TraceCollectionListener()`
is always True. Neither read observes a leak, so the canary is deleted rather
than replaced, with the reasoning recorded so it is not re-added.

The same finding showed the fixture was resetting two class attributes that are
never assigned at class level. Only dropping `_instance` is load-bearing, so the
fixture is now one line.

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

* docs(tracing): correct why the _listeners_setup canary is unwritable

setup_listeners returns early when tracing is off and no override applies
(trace_listener.py:213-220), assigning the flag at :229 only when it actually
registers. Construction therefore does not always set it, as the previous note
claimed: with tracing disabled the flag never even reaches the instance dict.

The instance read reports ambient tracing state rather than isolation, which is
a better reason not to assert on it than the one recorded before.

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

* fix(tests): clear trace batch state in place instead of dropping the singleton

Dropping `TraceCollectionListener._instance` made the next construction re-run
`setup_listeners`, re-registering its handlers on the event bus. That broke
tests/telemetry/test_task_failure_instrumentation.py, which requires exactly one
handler per event: the re-registered `on_task_failed` made two. Verified against
a53ecc17f, where the same sequence passes -- the regression was mine.

The leak that needed fixing was batch state, not registration, so the fixture
now clears the manager's batch fields in place. Handler cleanup already belongs
to `cleanup_event_handlers`, and `first_time_handler` keeps its reference to the
same manager object.

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

* fix(tests): clear tracing context vars so the listener can re-register

Bugbot flagged that keeping the singleton leaves `_listeners_setup` set, so after
`cleanup_event_handlers` wipes the bus `setup_listeners` returns early
(trace_listener.py:208) and tracing silently registers nothing for the rest of
the worker. Confirmed: after a tracing-enabled run, re-running setup restores 0
of 119 handler entries.

Dropping the singleton fixes that but previously broke
test_task_failure_instrumentation. The real cause was a third leak: the
`_tracing_enabled` context var stayed set, so the replacement listener still
believed tracing was on and re-registered `on_task_failed` next to telemetry's.
Clearing the context vars is what makes replacing the listener safe, so the
fixture now does both, and a canary pins it (fails with `assert True is False`
without the drop).

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

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-09 15:12:57 -07:00
Vidit Ostwal
4ed4aba6cd fix(cli): keep deploy push on the AMP create source (#7345)
Push was choosing ZIP vs git from a local origin remote, so adding origin later rebuilt the last ZIP with no files. Prefer AMP zip_deployment from status, and fall back to the old origin heuristic when that field is missing.
2026-09-10 00:23:40 +05:30
Vidit Ostwal
57df7f5202 test(bedrock): restore provider module after import test (#7355)
Co-authored-by: Lorenze Jay <63378463+lorenzejay@users.noreply.github.com>
2026-09-09 23:46:37 +05:30
Daniel Barreto
b92e80be53 chore(tools): make the vision_tool more dynamic (#7350)
* chore(tools): make the vision_tool more dynamic

* tackle review comments

* chore: update tool specifications

* refactor(tools): simplify vision tool model selection

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: ViditOstwal <viditostwal@gmail.com>
Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-09 22:18:53 +05:30
Lorenze Jay
b0fd0a9fa3 feat(telemetry): track checkpoint runtime and CLI usage (#7348)
* feat(cli): track checkpoint command and TUI usage

* feat(telemetry): track runtime checkpoint operations

* fix(telemetry): count prune usage after argument validation

* style(cli): format checkpoint prune command

---------

Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-09 22:13:11 +05:30
Devulapalli Naga Sri Vaishnavi
a53ecc17f1 fix: make pre-commit hooks portable on Windows (#6881)
* fix: make pre-commit hooks portable on Windows

* test: validate each pre-commit hook command

* test: restore Bedrock module state after import check

* test: keep provider module references in sync

* fix: select virtualenv activation path by platform

* chore(ci): ignore unpatched accelerate advisory

* chore: keep Windows hook fix focused

---------

Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-09 08:50:41 +00:00
Liangshanbobo
929a173575 test(agents): cover native result as answer (#7334) (#7336)
* test(agents): cover native result as answer (#7334)

* test(agents): document result as answer coverage

---------

Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-09 13:32:27 +05:30
George Pickett
9feaf5ecab docs(tools): fix parallel search reference link (#7344)
Co-authored-by: George Pickett <297992784+georgeatparallel@users.noreply.github.com>
Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-09 13:21:59 +05:30
Vidit Ostwal
5c47c4a559 ci: ignore unpatched accelerate GHSA-4j2p-28q2-5m79 (#7347)
pip-audit fails on accelerate 1.13.0; no PyPI release past 1.14.0 ships the path-traversal fix yet.
2026-09-09 12:50:55 +05:30
Vidit Ostwal
a68b5e903c chore(ci): label FTC-closed PRs as needs-issue (#7249) 2026-09-09 00:32:53 +05:30
Vidit Ostwal
79befd0ce5 docs: clarify that tracing is managed separately from telemetry (#7311)
Users who disable telemetry still need the tracing docs to understand first-run trace viewing and how the two settings relate.
2026-09-08 23:08:10 +05:30
YOON KIWOONG
5d9b77ba10 GitContribute issue #7287 (#7288)
Signed-off-by: kiwoong <rldnddbs@naver.com>
Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-08 22:22:03 +05:30
oxy-giedrius
34199c21b7 chore(oxylabs): allow the 3.x oxylabs SDK (#7331)
`oxylabs` was pinned to exactly 2.0.0, so consumers could not take 3.0.0, out
since March. 3.x keeps the `RealtimeClient` surface these tools use, and all
four tools plus their failure paths were verified against the live API on both
2.0.0 and 3.0.0.

The lockfile keeps oxylabs at 2.0.0, so this permits the upgrade rather than
forcing it.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 07:22:23 +00:00
oxy-giedrius
fe62d04cdb fix(oxylabs): report scrape failures instead of raising IndexError (#7044)
* fix(oxylabs): report scrape failures instead of raising IndexError

The oxylabs SDK logs HTTP errors and returns an empty response rather than
raising, so the unchecked `response.results[0]` in every Oxylabs tool turned a
rejected request into `IndexError: list index out of range`. Invalid credentials
-- the most likely first-run mistake -- gave no indication of the cause. A
result carrying a non-2xx `status_code` had the same problem one level down: the
job ran, the page did not come back, and the tool returned its empty content as
though the scrape had succeeded, handing the agent "[]".

Both are now reported as a `ToolFailure` naming what went wrong, so the agent
gets something it can act on and the framework records the call as failed:

    401 Unauthorized
    400 Bad Request - Parameter `parsing_instructions` can be used just with
    `parse` parameter set to `true`.

Because the SDK keeps the cause only in its own log, the failing call is run
with a handler attached to the `oxylabs` logger and the status, the API's
explanation and timeouts are read back off it. `code` and `retryable` are set
from the status, so 429 and 5xx are marked worth retrying. Nothing about the
caller's logging configuration is changed; an application that has silenced the
SDK still gets the generic failure.

Content that is neither a string nor a dict is also serialized properly:
`parsing_instructions` commonly yields a list, and the previous `str()`
fallback produced a Python repr with single quotes instead of JSON.

The client construction and response handling these four tools duplicated
verbatim now live in a shared `OxylabsBaseTool`, following the existing
`SerpApiBaseTool` pattern, so the handling above exists in one place. The
generated tool specs change only by the new `locale` field, confirming the
tools' public surface is otherwise untouched.

Also add the `locale` option to the Google Search config, which the docs
already documented but the config model silently dropped, and correct two
copy-paste errors in the docs across all four locales.

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

* fix(oxylabs): keep concurrent scrape diagnoses apart

The error capture attached a fresh handler to the shared `oxylabs` logger for
each scrape, so two scrapes in flight at once each saw both errors. `_diagnose`
reads the first HTTP status it finds, so a timeout could be reported as the
other request's 400 -- `retryable=False` on a failure that was worth retrying.

One handler now serves every scrape and routes each record to the capture of
the call that caused it via a `ContextVar`, which isolates threads and asyncio
tasks alike. Serializing the captures would have fixed the cross-talk too, but
at the cost of running every scrape one at a time. The handler stays attached
once installed: it is inert outside a capture, and detaching it would race with
concurrent scrapes.

The regression test forces the interleaving -- one capture is held open while
the other call logs -- and fails against the previous implementation.

Also drive `config` through the public constructor in the tests instead of
assigning `__dict__["config"]`, so they would catch `__init__` dropping a
supplied config.

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

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 12:42:48 +05:30
αI
7e18abd108 fix(llm): route all DashScope models through native provider (#7234)
DashScope's OpenAI-compatible endpoint serves DeepSeek/Kimi/GLM/etc.,
not only Qwen. Stop restricting the native match to the qwen* prefix so
DASHSCOPE_BASE_URL applies consistently. Fixes #7233.

Co-authored-by: Alphaxiaoteng <230277249+Alphaxiaoteng@users.noreply.github.com>
Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-08 06:08:40 +00:00
Rolly Calma
09997bfd6f fix(state): persist json checkpoints as utf-8 (#7257)
* fix(state): persist json checkpoints as utf-8

* test: import pathlib Path in checkpoint tests

---------

Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-08 06:02:41 +00:00
陈志谦
98c067c22a fix(brightdata): drop stray $ in f-string search URLs (#7326)
get_search_url interpolated ${query} inside an f-string, producing
URLs like https://www.bing.com/search?q=$test. The URL is passed
straight to the SERP request, so every search carried the malformed
query string.

Fixes #7325
2026-09-08 04:55:52 +00:00
Bright Oparaji
1b855b4ff9 docs(events): remove stale params from handle_llm_stream_chunk docstring (#7313)
The Args block for ConsoleFormatter.handle_llm_stream_chunk listed
'chunk' and 'crew_tree' parameters that no longer exist on the method.
The signature was refactored to (accumulated_text, call_type) but the
docstring was not updated. Callers in event_listener.py pass only the
two real params.

Refs #7312.
2026-09-07 19:10:44 +05:30
Bright Oparaji
1f3e6113d7 docs(streaming): fix streaming output docstring examples (#7286)
* docs(streaming): fix streaming output docstring examples

CrewStreamingOutput's example called crew.kickoff() without setting
stream=True on the Crew, so the snippet returned a CrewOutput and did
not stream anything.

FlowStreamingOutput's example called flow.kickoff_streaming() and
flow.kickoff_streaming_async(); neither method exists. Flow-level
streaming is exposed through Flow.kickoff with stream=True and
returns a StreamSession, not a FlowStreamingOutput.

Refs #7285

* docs(streaming): clarify Flow.kickoff does not take stream param

Flow.kickoff() has no stream parameter; the runtime returns a
StreamSession when self.stream is True. Reword the FlowStreamingOutput
note so callers know to configure the Flow with stream=True before
calling kickoff().

Addresses CodeRabbit review on #7286.

* docs(streaming): restore FlowStreamingOutput example

Add back an Example block showing valid usage of FlowStreamingOutput.
The class is only ever constructed directly with a chunk-producing
iterator (see lib/crewai/tests/test_streaming.py), so the example
mirrors that pattern instead of the original snippet that referenced
non-existent Flow.kickoff_streaming methods.

Addresses review feedback on #7286.

* docs(streaming): swap FlowStreamingOutput example for public Flow streaming path

Replace the test-only FlowStreamingOutput(sync_iterator=...) example
with the actual public flow-streaming path: Flow.stream=True followed
by kickoff() / kickoff_async(), which return StreamSession /
AsyncStreamSession. The example is labeled explicitly to make clear
that Flow.kickoff() does not return a FlowStreamingOutput, and points
readers at the streaming-flow-execution guide.

Addresses review feedback on #7286.

---------

Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-07 16:27:15 +05:30
DrewWhittleNZ
193a166e61 fix(schema): support list-form type arrays in JSON schema conversion (#7281)
* fix(schema): support list-form "type" arrays in JSON schema conversion

_json_schema_to_pydantic_type already handles anyOf/oneOf for nullable
unions -- the form Pydantic's own schema generation produces for
Optional[T] fields -- but had no handling for the other, equally valid
JSON Schema way of expressing the same thing: a list-form type array,
e.g. {"type": ["string", "null"]}. This is what .NET/System.Text.Json
-based schema generators produce instead, so any MCP tool schema from
a non-Python server using this form crashed create_model_from_schema
outright with "Unsupported JSON schema type: ['string', 'null']" --
taking down the entire MCPServerAdapter connection, not just the one
affected tool.

Confirmed against a real self-hosted MCP server (Equibles,
github.com/daniel3303/Equibles): several of its tools (e.g.
ListCompanyDocuments's startDate/endDate filters) use exactly this
pattern, and MCPServerAdapter couldn't connect to it at all as a
result -- reproduced identically on both Windows and macOS.

Fix mirrors the existing anyOf/oneOf handling: treat each entry in a
list-form type the same way an anyOf member is handled, building a
Union of the corresponding Python types. A single-element list
collapses to that one type via typing.Union's own behavior, and
"null" entries resolve to None (matching how the type == "null"
branch already behaves), producing the same Optional[T] shape as the
anyOf case would.

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

* fix(schema): preserve union members when applying FORMAT_TYPE_MAP

CodeRabbit flagged this reviewing #7058: the format override in
_json_schema_to_pydantic_field replaced the whole resolved type with
FORMAT_TYPE_MAP[format_], even when that type was a Union built from a
list-form `type` (or anyOf/oneOf) rather than a plain `str`. For a
schema like {"type": ["string", "null"], "format": "date-time"}, this
collapsed Union[str, None] down to plain datetime, silently dropping
the null option -- masked for non-required fields by the
Optional-rewrap at the end of the same function, but not for a
required-but-nullable field (a valid, if unusual, JSON Schema shape).
The same override also drops any non-string members of a multi-type
array (e.g. ["string", "integer", "null"]) regardless of required
status, since nothing rewraps those.

Narrow the override to the `str` member specifically: replace `type_`
outright when it's already plain `str`, or substitute only the `str`
element inside a Union via get_origin/get_args, leaving null and
other type-array members untouched.

Added two tests covering the previously-broken cases: a required
nullable formatted field, and a multi-type array (string/integer/null)
with a format.

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

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-07 12:36:02 +05:30
Shxiao
7fe8317fc4 fix(llm): correct gpt-4o-mini context window 200000 -> 128000 (#7294)
gpt-4o-mini's official context window is 128,000 tokens (OpenAI
announcement and API docs; litellm's model database agrees), but the
shared LLM_CONTEXT_WINDOW_SIZES table and the OpenAI/Azure provider-local
tables listed 200000 - apparently copied from the neighboring o3-mini /
o4-mini entries. With CONTEXT_WINDOW_USAGE_RATIO = 0.85, crews resolved
the usable window to 170000 instead of 108800, letting history grow past
the model's real 128k limit and failing with API 400s on long runs.

Fixes #7293
2026-09-07 11:11:57 +05:30
Jesse Miller
143e902178 docs: use organization UUIDs in the skill install reference (#7273)
Organization names are not unique, so the documented `@org/name` form can
resolve to the wrong organization and fail to find the skill. Document the
`@org-uuid/name` form instead, and add a note pointing at `crewai org list`
for the UUID.

Applies to the agent-side registry refs too: they resolve through the same
`/skills/:org/:name` endpoint and the same `~/.crewai/skills/{org}/{name}/`
cache path, so leaving them as `@acme` would contradict the install command.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-04 13:26:07 -07:00
Lucas Kim
c00e3228fc fix(bedrock): preserve streaming tool call arguments at contentBlockStop (#6150)
* fix(bedrock): preserve streaming tool call arguments at contentBlockStop

Streaming Converse handlers accumulate tool input as JSON string deltas in
accumulated_tool_input but never fold it back into current_tool_use["input"],
so function_args reads an empty {} at contentBlockStop. Parse the accumulated
input into the tool-use block (with a {} fallback) in both the sync and async
streaming handlers. This is the streaming counterpart of the non-streaming fix
in #5415 (issue #4972).

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

* fix(bedrock): coerce non-dict streaming tool input to empty dict

json.loads on the accumulated tool input can return a valid-but-non-object
JSON value (e.g. a string or list), which would fail at fn(**function_args)
with a TypeError. Enforce a dict shape before use in both the sync and async
streaming handlers, and add a regression test for the non-dict case.

Addresses CodeRabbit review feedback on #6150.

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-04 20:19:47 +05:30
João Moura
a024115e4e [docs-freeze] docs: snapshot and changelog for v1.15.20 (#7271) 2026-09-04 09:42:07 -03:00
João Moura
1457740528 feat: bump versions to 1.15.20 (#7270) 2026-09-04 09:40:31 -03:00
Vinicius Brasil
a5f26f3598 Fix legacy platform tool alias discovery (#7269)
LegacyClient filtered the server response with exact app and action
names. The platform returns canonical app names and provider action
names, so valid aliases produced no tools.
2026-09-04 09:39:25 -03:00
João Moura
04e2efbdab [docs-freeze] docs: snapshot and changelog for v1.15.19 (#7266) 2026-09-04 08:28:16 -03:00
João Moura
227844ef86 feat: bump versions to 1.15.19 (#7265) 2026-09-04 08:26:06 -03:00
João Moura
1e8cbef1b8 fix(tools): read octet-stream and xlsx urls in urlreadtool (#7261)
* fix(tools): read octet-stream URLs by sniffing the body

URLReadTool resolved content type from the Content-Type header and then
the URL path extension. Presigned object-store links carry neither: they
pin every object to application/octet-stream and use a content hash for a
path, so a SharePoint download landing in R2 was refused outright.

Sniff the already-fetched body as a third source, consulted only after the
header and both URL extensions come back with nothing. The sniff can turn
a refusal into a read but never a read into a different read, so no URL
that works today changes behavior.

Fails closed: a zip is DOCX only when word/document.xml is in its central
directory, so an .xlsx keeps its honest refusal instead of surfacing a
misleading "failed to read DOCX"; text requires a strict, whole-body UTF-8
decode with no NUL byte; an empty body identifies nothing.

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

* feat(tools): extract text from XLSX URLs

The reported presigned SharePoint link is a spreadsheet, so sniffing the
body identified it as OOXML but still had nowhere to send it: URLReadTool
had no XLSX extractor, and the file would have been refused even with a
correct spreadsheetml Content-Type.

Read workbooks with openpyxl, already a core crewai dependency, so this
adds no new one. Sheets are emitted as CSV under a "Sheet <name>:" heading,
mirroring the PDF extractor's per-page shape. read_only streams the sheets
instead of building the whole object graph and data_only takes cached
values, both of which matter for a workbook arriving from an untrusted URL.

Cells are written through csv rather than joined, so a comma, quote or
newline inside a cell cannot corrupt the grid, and trailing phantom rows
are trimmed because Excel reports sheet dimensions generously.

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

* fix(tools): bound xlsx expansion and refuse ambiguous ooxml packages

Bot review found two real defects in the XLSX extractor, both reproduced.

openpyxl pads every row up to a sheet's declared dimension, so a single
stray cell far down the sheet turned a 4.8 KB upload into 100,000 rows and
200,000 cells. Trimming only trailing blanks did not help, because the
stray cell sits at the end and keeps the last row non-empty. Blank rows are
now skipped as they stream, and a cell budget caps what any one workbook
can hand an agent -- announced in the output rather than silently applied.

A zip carrying both word/document.xml and xl/workbook.xml was classified as
DOCX. Two identities is not a positive identification, so it is refused.

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

* fix(tools): keep whitespace-only xlsx cell values

Bot review, verified: openpyxl's row padding arrives as None, so testing
cells for exactly-empty drops it just as well as .strip() did while leaving
a row whose cells the author really did fill with spaces. And rstrip() on
the rendered grid removed a trailing space from the final cell along with
the line terminator; only the terminator should go.

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

* fix(tools): bound xlsx scan work, not just emitted cells

The cell budget only counted cells that reached the output, and blank rows
skip before that point. A sheet can declare Excel's maximum dimension while
holding two real cells; openpyxl then pads every row out to 16,384 columns
and yields one row per gap. Measured: a 4,848-byte workbook drove 1.64
billion cell normalizations in 15.2 seconds with the budget never touched.

Charge a separate scan budget per row, before the row is normalized and
before the blank check, so the work a hostile sheet can demand is bounded
whether or not any of it is emitted. The regression test asserts the read
completes in under 5 seconds and is mutation-verified: dropping the per-row
charge takes it back to 26 seconds.

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

* fix(deps): clear the six pip-audit advisories

gitpython 3.1.58 has PYSEC-2026-3785 through -3788, fixed in 3.1.59; the
lock now takes 3.1.61. Its exclude-newer-package cutoff is dropped rather
than bumped -- the global 3-day cutoff has long since passed 2026-08-05, so
that per-package pin was only holding the fix back.

snowflake-sqlalchemy 1.10.0 has GHSA-8g6f-qw9x-4q6q (SQL injection and
local file disclosure), fixed in 1.11.0.

unstructured 0.18.32 has GHSA-4mvj-m6j5-pmf7, a full-read SSRF via the url=
argument of partition(). The patched 0.24.0 requires Python >=3.11 while
crewai-tools supports 3.10, so the floor carries a marker and 3.10 stays on
the old line. 0.24+ also requires beautifulsoup4>=4.14.3, so the bs4 pin
widens from ~=4.13.4 to >=4.13.4,<5 -- a widening, so no existing install
breaks. uv resolves bs4 4.13.5 on 3.10 and 4.15.0 on 3.11+.

pip-audit locally: "No known vulnerabilities found, 5 ignored", with no new
--ignore-vuln entries. Only crewai-tools[xml] grows, gaining spacy and
openai-whisper transitively through unstructured's extras.

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

* fix(tools): narrow bs4 find_all results without a cast

Widening the beautifulsoup4 pin let uv resolve 4.15.0 on Python 3.11+ while
3.10 stays on 4.13.5, because the old unstructured line holds it back there.
4.15 types find_all precisely, so cast(Tag, link) became redundant and mypy
failed the 3.11-3.13 type-checker jobs while 3.10 passed.

isinstance narrowing is correct under both versions and is what AGENTS.md
asks for anyway. Verified by running mypy against 4.15.0 and again against
4.13.5: browser_toolkit is clean under both, leaving only the pre-existing
errors in crewai/rag/embeddings/providers/ibm.

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

* fix(deps): declare security floors in crewai-tools, not only as overrides

Bot review caught a regression I introduced. override-dependencies replace
the whole requirement including its marker, so gating the unstructured
override on python_version >= '3.11' dropped the dependency outright on
3.10: the lock held only 0.24.1, never the 0.18 line the comment claimed.
crewai-tools[xml] would have installed no unstructured at all there.

Move the floors into lib/crewai-tools/pyproject.toml, where a marker split
means what it says -- >=0.24.0 on 3.11+, >=0.17.2 below -- and drop the
root override for unstructured entirely. The lock now carries both 0.18.32
and 0.24.1 under complementary markers.

Same reasoning applies to the other two, per the nltk precedent already in
that file: a uv override only shapes this workspace's lock, so consumers
installing crewai-tools[snowflake] or [github] were still getting the
vulnerable floors. Declared there now as well.

Also documents the tool as a fit for presigned and share links from S3, R2,
Google Drive, OneDrive and SharePoint -- the case this PR fixes -- while
saying plainly that it reads a URL and does not authenticate.

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

* chore: update tool specifications

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-09-04 16:51:47 +05:30
Havel Cyrus
92eb5f9183 fix: append trailing user turn in native Gemini provider (#6973)
* fix: append trailing user turn in native Gemini provider

GeminiCompletion._format_messages_for_gemini maps assistant messages
to Gemini's 'model' role but never guards against the resulting
contents list ending on a model turn. CrewAI's own agent loop (max
iterations, guardrail retries) can produce exactly that history, and
Gemini's generateContent API rejects it with 400 'Requests ending
with a model turn are not supported'.

Mirrors the existing Mistral/Ollama guard in
LLM._format_messages_for_provider, which never applies to Gemini
since gemini/google model strings resolve to this native provider
instead of the LiteLLM fallback path.

Fixes #6972

* fix: append trailing user turn for Gemini on the LiteLLM fallback path

LLM._format_messages_for_provider already guards Mistral/Ollama
against a trailing assistant turn, but Gemini models routed through
the LiteLLM fallback (no google-genai installed, or a model name not
recognized as native) had no equivalent guard. litellm's own
Vertex/Gemini transformation doesn't handle this either, so the
request reaches Gemini's generateContent API unguarded and 400s.

Complements the native-provider fix in GeminiCompletion, covering
both dispatch paths.

* fix: don't append text turn after unresolved Gemini function call

Address CodeRabbit review on #6973: appending a plain 'Please
continue.' user turn after a trailing model turn that contains an
unresolved function_call violates Gemini's function-calling protocol
-- it requires a matching functionResponse, not free text. Raise a
targeted error instead so the caller notices rather than silently
sending a malformed follow-up.

Also strengthens the native-provider formatting tests to assert exact
role sequence and text content (not just the last role), per review,
and adds a regression test for the unresolved-function-call case.

* fix: guard None parts when checking Gemini history for unresolved function call

contents[-1].parts is typed list[Part] | None; iterating it directly
failed mypy (union-attr) on 3.10-3.13. Narrow to [] before the any()
check and document the ValueError in the docstring.

---------

Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-03 16:26:44 +05:30
Parthiban Sivakumar
c90337ba5a fix(llms): normalize scheme and port in Ollama base URL (#7206)
* fix(llms): normalize scheme and port in Ollama base URL

OLLAMA_HOST follows Ollama's own convention and may be a bare host
("0.0.0.0") or a host:port pair ("127.0.0.1:11434") rather than a full
URL. _normalize_ollama_base_url only appended "/v1", so those values
produced invalid base URLs such as "0.0.0.0/v1", and every request
failed with the misleading error "Failed to connect to OpenAI API:
Connection error." - confusing, since no OpenAI model was requested.

Fill in the missing parts the way Ollama's own client does: prepend
http:// when no scheme is present, append the default port 11434 when
none is present and the scheme is http (https implies 443), then append
the /v1 suffix the OpenAI-compatible endpoint requires.

Six of nine realistic OLLAMA_HOST forms were affected, including
127.0.0.1:11434, which is Ollama's documented default.

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

* fix(llms): strip only the parsed path when normalizing Ollama base URL

Stripping trailing slashes from the whole URL before parsing corrupted
inputs that carry a query or fragment. "http://ollama/?tenant=acme" kept
a "/" path and produced a doubled "//v1", and a query or fragment ending
in "/" silently lost that character.

Parse first, then rstrip only parts.path. Adds regression tests for a
root path alongside a query and for a query value ending in "/".

Reported by CodeRabbit on #7206.

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

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-03 16:05:56 +05:30
Vidit Ostwal
3d72c707d5 chore(ci): ignore unpatched nltk GHSA-8mgp-746c-j5xp (#7215)
* chore(ci): ignore unpatched nltk GHSA-8mgp-746c-j5xp

No patched PyPI release exists beyond 3.10.3. nltk is transitive via
crewai-tools[xml] -> unstructured; CrewAI does not call the vulnerable
model-artifact APIs.

Co-authored-by: Vidit Ostwal <Vidit-Ostwal@users.noreply.github.com>

* chore(ci): note dropping nltk GHSA ignore on the next bump

Leave an explicit TODO beside the ignore so GHSA-8mgp-746c-j5xp is
removed when nltk moves past the unpatched 3.10.3 floor.

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Vidit Ostwal <Vidit-Ostwal@users.noreply.github.com>
2026-09-02 10:04:20 -07:00
Zhewen Tan
98799a3b09 fix(memory): preserve reusable scope configs (#7068)
Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-02 19:35:30 +05:30
Vidit Ostwal
1cef70de52 fix: bump pypdf to 6.16.2 for GHSA-jp53-mhqp-8xcg (#7200)
* fix: bump pypdf to 6.16.2 for GHSA-jp53-mhqp-8xcg

pypdf 6.15.0 fails pip-audit on three moderate DoS advisories; 6.16.1+ patches them.

* chore: keep existing uv.lock environment markers

A full uv lock refresh rewrote unrelated dependency markers; restore them so the pypdf bump stays isolated.

* chore: drop unused pypdf exclude-newer-package in crewai-files

~=6.16.1 plus the global 3-day cutoff already admits 6.16.2.

* chore: drop pypdf from exclude-newer-package

6.16.2 is already older than the global 3-day cutoff; the version floor is enough.
2026-09-02 10:38:33 -03:00
Fang Kaiqi
b608a3595c docs: remove CodeInterpreterTool from AI/ML overview examples (#7100)
Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-02 10:31:18 +05:30
Fang Kaiqi
f5db5a1788 docs: point prompt-template link at its current path (#7101)
Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-02 10:21:40 +05:30
Vinicius Brasil
968c3065d3 Add Clipper integrations client (#7196)
* Add Clipper integrations client

Implement the internal Clipper discovery and execution contract with
deployment authentication and normalized results. Keep
CrewAIPlatformTools on LegacyClient until the new path is ready for
selection.

* Allow Clipper requests without deployment instances

Local and self-hosted CrewAI executions can have a valid integration
token without a deployment instance UUID. Send the deployment header
when it is available and allow Clipper to attribute other executions to
the organization.

* fixup! Allow Clipper requests without deployment instances

* fixup! Add Clipper integrations client
2026-09-01 14:11:43 -07:00
Vidit Ostwal
818f2624e8 [OSS-149] Accept 1/yes/on on telemetry disable flags (#7185)
* fix(telemetry): accept 1/yes/on on disable flags

CREWAI_DISABLE_TELEMETRY=1 was ignored because the gate only matched true, so telemetry stayed on with no warning.

* fix(telemetry): warn once on unrecognized disable values

Stop repeating the same invalid-flag warning on every telemetry check, and drop the undocumented CREWAI_DISABLE_TRACKING alias from docs.

---------

Co-authored-by: Lorenze Jay <63378463+lorenzejay@users.noreply.github.com>
2026-09-01 11:41:20 -07:00
Vidit Ostwal
8e46205619 [OSS-151] Fail closed when human-feedback emit cannot classify (#7188)
* fix(flow): resolve @human_feedback emit LLM from the project model

Omitting llm= no longer hardcodes OpenAI. Collapse and learn resolve through create_llm so MODEL / MODEL_NAME / OPENAI_MODEL_NAME win, then DEFAULT_LLM_MODEL.

* fix(flow): fail closed when human-feedback collapse cannot classify

Stop routing to emit[0] when the collapse LLM cannot be called or its response does not match an outcome. Empty skip still uses default_outcome.

* refactor(flow): extract human-feedback collapse matching helpers

Move match/require outcome helpers out of _collapse_to_outcome so the classify path stays flat.

* refactor(flow): catch only LLM call failures in collapse

Keep HumanFeedbackCollapseError from matching outside the call try so it is raised once and does not trigger a second prompt.

* fix(flow): treat non-object JSON as raw collapse text

Avoid AttributeError when the collapse LLM returns JSON that is not an object.
2026-09-01 17:25:07 +00:00
Thiago Moretto
1bc2e0722d feat(flows): add now() to the CEL expression environment (#7194)
* feat(flows): add now() to the CEL expression environment

CEL expressions in flow definitions had no way to produce the current
date: the environment was built bare, so date-dependent flows failed at
runtime. Register a now() function that returns the current UTC time as
a CEL timestamp. The value is frozen once per kickoff so every
expression in a run sees the same instant, even across midnight.

Standard CEL covers formatting from there: string(now()),
now().getFullYear(), now() - duration('24h').

* chore(flows): drop redundant comment on _cel_now

* refactor(flows): derive CEL env and functions from one registry

A function now lives in one _CelFunctionSpec entry: its annotation for
compile and its implementation factory for evaluate, so the two cannot
drift. Run-scoped values move into _CelRunContext; adding one is a
field, not a new parameter through every helper signature.

* chore(flows): drop _CelRunContext docstring

* fix(flows): freeze a fresh cel now() on human-feedback resume

resume_async never passes through kickoff_async, so a flow restored
with from_pending() had no frozen instant and now() fell back to live
wall-clock per expression. Freeze a fresh instant at resume instead of
persisting the kickoff one: a flow can pause on feedback for days, and
expressions after resume must see today.
2026-09-01 17:05:47 +00:00
Vinicius Brasil
48cc5d4e5e Decouple platform tools from the integrations API (#7180)
* Decouple platform tools from the integrations API

Define normalized selector and tool data so platform tool creation does
not depend on the legacy API response shape. This contract makes the
legacy client easier to replace later.

- Move action discovery and response normalization into LegacyClient.
- Pass ToolInfo from discovery through tool creation and execution.
- Replace the builder flow with direct factory orchestration.
- Preserve app, action, and connection data in immutable models.
- Build sanitized tool names from the full tool identity.
- Preserve legacy request, SSL, and failure behavior with contract tests.

* fixup! Decouple platform tools from the integrations API

* fixup! Decouple platform tools from the integrations API

* fixup! Decouple platform tools from the integrations API

* fixup! Decouple platform tools from the integrations API
2026-09-01 16:07:08 +00:00
Lorenze Jay
917b9df6d7 Validate JSON crews in project environments (#7171)
* Validate JSON crews in project environments

* fix(cli): address standalone deploy review feedback

---------

Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-09-01 16:00:59 +00:00
João Moura
ec53d6f534 fix(llms): native structured outputs for current claude models, and snowflake CVE floor (#7182)
* fix(llms): let current claude models use native structured outputs

NATIVE_STRUCTURED_OUTPUT_MODELS only listed 4.5-era prefixes, so Opus 5,
Sonnet 5, Fable 5 and Opus 4.8 fell through to the forced-tool-call
fallback. That path also overwrites params["tools"], so a call combining
tools with a response_model silently lost the caller's tools.

_infer_provider_from_model documented a pattern-matching fallback it never
performed, so a Claude release newer than the constants list resolved to
"openai". Bedrock ('.' in model) and Azure (every OpenAI prefix) are left
out of that fallback because they would capture gpt-* models.

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

* fix(llms): route bedrock-namespaced anthropic ids to bedrock

"anthropic.claude-*" is Bedrock's namespace, not the Anthropic API, and it
satisfies the anthropic prefix pattern. Settle it before the pattern loop so
an unlisted Bedrock id picks BedrockCompletion. The region-prefixed form
("us.anthropic.claude-*") was resolving to openai, so this repairs that too.

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

* fix(deps): raise snowflake-connector-python floor for CVE-2026-15925

GHSA-5cc2-282f-jjq2 (CRITICAL): the connector does not verify TLS hostnames,
so a network attacker can impersonate the Snowflake endpoint. Fixed in 4.7.1.

crewai-tools[snowflake] declares "snowflake-connector-python>=3.12.4", which
the lock had resolved to 4.6.0. Following the existing convention, the security
floor goes in [tool.uv] override-dependencies rather than the source
declaration, matching how cryptography is handled.

Relocking also refreshes numpy/humanfriendly/nvidia environment markers, which
re-resolution under the relative exclude-newer window produces regardless of
this change.

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

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 12:01:22 +05:30
Vinicius Brasil
381fef73be Add injectable client for CrewAI platform tools (#7177)
* Add injectable client for CrewAI platform tools

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

Allow callers to provide a custom client through CrewaiPlatformTools.

* Fix platform action tool failure tests

* Remove redundant protocol placeholders
2026-08-31 16:01:54 -07:00
Vidit Ostwal
bf56bb13bd ci: require an open issue for first-time contributor PRs (#7169)
* ci: require an open issue for first-time contributor PRs

Gate anyone who is not a returning contributor, and allow the PR only when a closing keyword points at an open issue in this repo.

* ci: accept any open issue mention for first-timer PRs

Drop the closing-keyword regex so #123, owner/repo#N, or an issue URL is enough when that issue is open.

* ci: ignore foreign owner/repo#N in first-timer issue gate

Bare #123 no longer matches the suffix of other/repo#123, so an open local issue cannot keep that PR open.
2026-08-31 22:48:14 +05:30
Vidit Ostwal
614efcdd30 ci: close first-time contributor PRs that lack a linked issue (#7164)
* ci: close first-time contributor PRs that lack a linked issue

* ci: indent FTC close comment so the workflow YAML parses
2026-08-31 21:29:59 +05:30
Vidit Ostwal
0e7625813b fix: bump nltk to 3.10.3 for PYSEC-2026-3726 (#7162)
Force the xml extra and workspace override onto the patched release so pip-audit stops failing on the 3.10.0 symlink file-read advisory.
2026-08-31 21:26:41 +05:30
Ran Shemtov
a35fbc864d docs: update channels guide to current copilotkit channels api (#7016)
* docs: update channels guide to current copilotkit channels api

* docs: translate channels and frontend overview guides to ar, ko, pt-BR

---------

Co-authored-by: Lorenze Jay <63378463+lorenzejay@users.noreply.github.com>
2026-08-31 15:47:58 +00:00
chenshiyang
265697b6f8 docs: refresh retired Gemini model ids (#7003)
Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-08-31 10:43:31 -03:00
Vinicius Brasil
da4daadba0 Parse platform application selectors (#7148)
Stores application, action, and connection values in an internal
selector. Validates the selector with clearer error messages. Keeps
existing application syntax and legacy API requests unchanged.
2026-08-28 15:36:29 -07:00
Lucas Gomide
e9d4c57b2a fix: run model call hooks on every path and propagate a deny (#7111)
* fix: let a hook deny reach the caller as a deny

A hook that raised `HookAborted` on `pre_model_call` never reached the code
making the call: the LLM layer caught it and returned `False`, which providers
translated into `ValueError("LLM call blocked by before_llm_call hook")`,
dropping the reason and the source and making a policy decision
indistinguishable from a provider outage. Every internal model call then
absorbed that error through the `except Exception` that keeps a provider hiccup
from failing a run, so memory analysis fell back to defaults and the converter
and reasoning handler retried the call that was just denied. The abort now
propagates out of the LLM layer while the boolean convention keeps its
documented `ValueError` via `LegacyHookBlocked`, and the fail-open handlers
around internal model calls re-raise it instead of degrading.

* fix: dispatch model call hooks on the paths that skipped them

A model call was only checked when the executor loop drove it: the
`from_agent is not None` short-circuit in `base_llm` silenced the hooks
for agent planning and step observation, no provider `acall` dispatched
them at all, and `InternalInstructor` bypassed `llm.call` entirely. This
replaces that short-circuit with an explicit
`model_call_hooks_already_dispatched` window so the enclosing caller
claims the dispatch, adds the pre-call dispatch to every provider's
`acall`, and runs the hooks around the Instructor client call. A denial
now emits a denied event instead of being logged and reported as a
provider failure.

* fix: report a boolean-convention deny as a deny, not an outage

A `before_llm_call` hook that blocks by returning `False` reached the five
native providers as a plain `ValueError`, which fell through to their generic
`except Exception` and was logged and emitted as `OpenAI API call failed: ...`
— the same deny raised as `HookAborted` was already labelled correctly, so the
two dialects disagreed on whether a policy decision was a provider outage. The
LLM layer now converts it into `LLMCallBlockedError`, still a `ValueError` so
the fail-open handlers around internal model calls keep absorbing it, but its
own type so a provider can report the decision it is. Since a block is raised
rather than returned, the thirteen callers that turned the return flag into a
raise by hand drop that line, and `_prepare_llm_call` raises the same type.

* fix: keep a denied plan from letting the agent run unplanned

`AgentExecutor.generate_plan` wraps `handle_agent_reasoning()` in a bare
`except Exception`, so guarding the reasoning handler alone still left the
deny absorbed one frame up: the executor logged "Error during planning" and
the agent proceeded with no plan. It now re-raises `HookAborted` like the
other planning boundaries, and the accompanying test also covers the
boolean convention still degrading at a fail-open site.

* fix: stop a denied knowledge query from running the task without knowledge

`handle_knowledge_retrieval` and its async twin wrap the query rewrite in
their own `except Exception`, so guarding `_get_knowledge_search_query`
alone still let `execute_task` continue on the unaugmented prompt after a
deny. Both now emit the terminal `KnowledgeSearchQueryFailedEvent` and
re-raise `HookAborted`, matching the second-frame guard already added to
`AgentExecutor.generate_plan`. Also documents the abort contract on
`PlannerObserver.observe`.

* fix: stop nine callers from re-swallowing a model call deny

CodeRabbit caught the replan path re-swallowing a deny, so an AST sweep of
every caller of a guarded function found the same defeat in nine places:
classic and replan planning, memory recall and memory save on both `Agent`
and `LiteAgent`, the base executor's save, and `LLMGuardrail.__call__`,
which turned a refused call into validation feedback. Each now re-raises
`HookAborted` after emitting whatever terminal event it owes, while every
other failure keeps degrading as before — the knowledge guards move to that
same idiom instead of duplicating their emit.

* fix: pair a denied guardrail with the event it started

Re-raising from `LLMGuardrail` left `process_guardrail` between its started
and completed events, so a denied validation read as one still in flight
rather than a policy decision. It now emits `LLMGuardrailCompletedEvent`
with the deny reason before the abort leaves, matching what every other
guarded site in this change already does.

* fix: stop retrying a task after a hook denied its model call

`Agent.execute_task` funnels every exception into `_handle_execution_error`,
which re-runs the whole task up to `max_retry_limit` times, so a policy deny
read as a transient blip: a crew whose first model call was denied retried and
returned a normal answer. `HookAborted` now joins `_passthrough_exceptions`,
the tuple already reserved for deliberate stops. The new boundary tests drive
the public entry points instead of the frame that makes the call, and count
model calls so a deny that gets retried fails the assertion — ten of the twelve
fail against `main`.

* fix: stop a denied plan step from being reported as a failed step

Making model call hooks reachable on agent-bearing calls put a deny inside
`StepExecutor.execute`, whose broad `except Exception` turned it into
`StepResult(success=False)` and let the plan carry on; `HookAborted` now
joins `ToolExecutionFailedError` in the passthrough handlers there, and
`execute_todos_parallel` re-raises a deny that `return_exceptions=True`
would otherwise record as one failed todo. `_emit_call_denied_event` also
renders the source through the now-public `source_name`, so a hook that
names itself with a callable reads as its name instead of a repr.

---------

Co-authored-by: Vidit Ostwal <110953813+Vidit-Ostwal@users.noreply.github.com>
2026-08-28 12:32:09 -04:00
João Moura
cba6c03646 feat(events): record how a crew run ended, for every user (#7118)
* feat(events): record how a crew run ended, for every user

Crew was the one level with no ungated terminal record. `Crew Execution` and
`end_crew` are both behind `share_crew`, which defaults False, so for
essentially every run there is no end-of-crew span at all - not one with fields
missing. Task outcomes ship ungated, flow outcomes ship ungated; crew being the
exception looks like an accident of history rather than a decision.

Adds `Crew Completed` carrying `outcome` and an explicit `duration_ms`, keyed by
crew_key/crew_id so it joins the existing ungated `Crew Created`. Modelled
directly on `flow_completed_span`, including its reasoning: a separate span
rather than holding `Crew Execution` open, because that span is emitted and
closed at start, so holding it would drop every run that is killed or crashes.

`on_crew_failed` called no telemetry at all before this, so a failed crew
produced nothing. It deliberately does not call `end_crew`, which writes onto
the gated execution span a failed run may never have opened.

Deliberately NOT included, each for a reason:

- Tokens. `crew.token_usage` sums per-agent LLM counters, and two agents sharing
  one LLM object share one counter, so the total double-counts today. Putting it
  on a span would propagate a known-wrong number into a metric. The dedup keys on
  `id(llm._token_usage)`, not `id(llm)` - `Agent.copy()` shallow-copies the LLM -
  and it changes the value of public `Crew.calculate_usage_metrics`, so it earns
  its own change.
- Models. Already on the ungated `Crew Created` span at 99.86% coverage; this
  joins to them by crew_id rather than duplicating.
- Tool counts. The ungated `Tool Usage` span covers only the ReAct path, the
  plan/step path double-emits, and nested crews share one RuntimeState - the
  count needs a design decision on cache hits before it is worth emitting.
- error_type. Needs 4.1's exception-class field factored out of task_events so
  both events share it, rather than duplicated hours after that merged.

Tests use the exporter pattern this suite already uses rather than mocking
`EventListener._telemetry`: EventListener is a singleton, so swapping that leaks
a MagicMock into every later test. The listener tests assert on the stamp
lifecycle instead. Verified order-independent over five randomized runs.

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

* test(telemetry): docstring the crew-completed helpers

Eight of the thirteen functions in this file carried a docstring and five
did not, which is an inconsistency inside the file this PR adds rather
than anything inherited. Documents the two fixtures, the span lookup, the
event-bus runner and the two test methods that were missing one.

No behaviour change: 9 passed, and re-run under random ordering on two
seeds to confirm order-independence.

Deliberately not addressed: the reviewer's 52.17% docstring-coverage
figure is dominated by event_listener.py, where 84 functions - nearly
every pre-existing on_* handler - carry no docstring. That is the file's
convention, and documenting them here would be an unrelated refactor.
The public API this PR adds, Telemetry.crew_completed_span, is documented.

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

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-28 13:06:51 -03:00
João Moura
1f6e327b3c feat(events): report machine size as a coarse band, not a core count (#7117)
* feat(events): report machine size as a coarse band, not a core count

`runtime_context` says where a process runs but carries no capacity axis, and
its largest bucket is a catch-all: a gunicorn worker on a VM and
`python main.py > out.log` on a MacBook both report `non_interactive`. Docker
Desktop on a laptop reports `container` via /.dockerenv, and a Remote-SSH shell
on a server reports `vscode_terminal`. So "server or laptop" is not answerable
from it today.

Adds `cpu_band` to the common span attributes, so it rides every span the way
`runtime_context` does rather than sitting on `Crew Created` alone - which would
answer nothing for Flow-only, CLI-only or standalone-agent runs.

Six bands, powers of two, top one open-ended: 1-2, 3-4, 5-8, 9-16, 17-32, 33+.
Open-ended because the exact count is the fingerprint - the observed fleet
maximum is 512, and a span reporting 512 identifies one machine. The vocabulary
is closed and asserted, like KNOWN_CODING_AGENTS and KNOWN_RUNTIME_CONTEXTS.

The share_crew-gated exact `cpus` attribute and the four platform* attributes
are untouched. That gating was a deliberate 2024 classification of machine
fingerprint as shareable content (44e38b1d5), and this does not reverse it: a
band is a range, the gated attribute remains the precise value.

Documents a trap in the docstring rather than leaving it to be rediscovered:
os.cpu_count() reports HOST cores, not the cgroup quota, so a 1-vCPU pod on a
96-core node lands in 33+. Right for "what kind of machine", wrong for "what did
this run get" - os.process_cpu_count() gives the latter but needs 3.13, above
this package's floor.

Docs updated in en/ar/ko/pt-BR, in the default-on Execution Environment row,
stating explicitly that the band is a range and the exact count stays opt-in.

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

* docs(telemetry): say where the cpu band comes from

The Execution Environment row ended "Detection reads only whether known
environment variables are set, never their values". True for the assistant
and runtime-context fields, and wrong for the band this PR adds:
detect_cpu_band() reads os.cpu_count() (runtime_env.py:306) and touches no
environment variable. In a privacy disclosure table that is the kind of
inaccuracy worth a line.

Names the source explicitly and scopes the env-var sentence to the two
fields it actually describes. All four locales at parity.

pt-BR also takes the reviewer's wording fix: "um de uma lista fixa" ->
"um valor de uma lista fixa", and the missing comma before o `project_id`.

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

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-28 08:50:10 -07:00
3424 changed files with 729788 additions and 3710 deletions

View File

@@ -29,7 +29,7 @@ uv run pre-commit install
## Repository Structure
This is a uv workspace with four packages under `lib/`:
This is a uv workspace with six packages under `lib/`:
| Package | Path | Description |
|---------|------|-------------|
@@ -37,6 +37,8 @@ This is a uv workspace with four packages under `lib/`:
| `crewai-tools` | `lib/crewai-tools/` | Tool integrations |
| `crewai-files` | `lib/crewai-files/` | File handling |
| `devtools` | `lib/devtools/` | Internal release tooling |
| `crewai-cli` | `lib/cli/` | Command-line interface |
| `crewai-core` | `lib/crewai-core/` | Shared core utilities |
Documentation lives in `docs/` with translations under `docs/{en,ar,ko,pt-BR}/`.
@@ -103,7 +105,8 @@ chore(deps): bump pydantic to 2.11
- Keep PRs focused — avoid bundling unrelated changes
- PRs over 500 lines are labeled `size/XL` automatically
- Title must follow the same conventional commit format
- Link related issues where applicable
- Link related issues where applicable (`#123`, `Fixes #123`, or the issue URL)
- First-time contributors must open or pick an existing **open** issue first, then mention it in the PR title or body (for example `#123`). PRs without a linked open issue are closed automatically and labeled `needs-issue`.
## Testing

24
.github/pull_request_template.md vendored Normal file
View File

@@ -0,0 +1,24 @@
## Related issue
Fixes #
<!--
First-time contributors must mention an existing open issue in this repo
(for example #123). PRs without a linked open issue are closed automatically
and labeled needs-issue.
-->
## Summary
<!-- Explain the solution and why. -->
## Verification
<!-- List the automated and manual checks used to verify the change. -->
- [ ] Tests added or updated for the changed behavior
- [ ] Relevant tests and quality checks pass locally
## Additional context
<!-- Include screenshots, compatibility notes, follow-up work, or "None". -->

View File

@@ -0,0 +1,92 @@
name: Welcome First-Time Contributors
on:
pull_request_target:
types: [closed]
permissions:
contents: read
issues: write
# GitHub accepts either Issues or Pull requests write access for PR comments.
# Request both scopes to match the first-time PR workflow and retain a
# supported permission path when GitHub issues the Actions token.
pull-requests: write
jobs:
welcome:
# Match the first-time contributor definition used by ftc-require-issue.
if: >
github.event.pull_request.merged == true &&
github.event.pull_request.user.type != 'Bot' &&
!contains(fromJSON('["MEMBER","OWNER","COLLABORATOR","CONTRIBUTOR"]'),
github.event.pull_request.author_association)
runs-on: ubuntu-latest
steps:
- name: Thank first-time contributors
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
const pullRequest = context.payload.pull_request;
const owner = context.repo.owner;
const repo = context.repo.repo;
const marker = "<!-- crewai-first-merged-pr-welcome -->";
const existingComments = await github.paginate(
github.rest.issues.listComments,
{
owner,
repo,
issue_number: pullRequest.number,
per_page: 100,
},
);
if (existingComments.some((comment) => comment.body?.includes(marker))) {
core.info("Welcome comment already exists; skipping duplicate.");
return;
}
const prUrl = pullRequest.html_url;
const shareText = [
"I just made my first contribution to @crewAIInc!",
"",
"Excited to help build the future of AI agents with CrewAI.",
"",
prUrl,
"",
"#OpenSource #AI #CrewAI",
].join("\n");
const xShareUrl = `https://x.com/intent/post?text=${encodeURIComponent(shareText)}`;
const linkedInShareUrl = `https://www.linkedin.com/sharing/share-offsite/?url=${encodeURIComponent(prUrl)}`;
const body = [
marker,
"",
`## Thanks for your first contribution to CrewAI, @${pullRequest.user.login}!`,
"",
"We really appreciate the time and care you put into this PR. Your work is now part of CrewAI — welcome to the contributor community.",
"",
"Want to share your contribution? Totally optional:",
"",
`[Share on X](${xShareUrl}) · [Share the PR on LinkedIn](${linkedInShareUrl})`,
"",
"If the links don't work, feel free to copy and personalize this:",
"",
"```text",
"I just made my first contribution to @crewAIInc!",
"",
"Excited to help build the future of AI agents with CrewAI.",
"",
prUrl,
"",
"#OpenSource #AI #CrewAI",
"```",
"",
"If you share, we'd love to see it — tag **@crewAIInc** on X and **CrewAI** on LinkedIn.",
].join("\n");
await github.rest.issues.createComment({
owner,
repo,
issue_number: pullRequest.number,
body,
});

134
.github/workflows/ftc-require-issue.yml vendored Normal file
View File

@@ -0,0 +1,134 @@
name: First-time contributor issue required
on:
pull_request_target:
types: [opened, edited, reopened]
permissions:
pull-requests: write
issues: write
concurrency:
group: ftc-require-issue-${{ github.event.pull_request.number }}
cancel-in-progress: true
jobs:
require-issue:
# Allow-list returning contributors. FIRST_TIMER / FIRST_TIME_CONTRIBUTOR
# are often NONE on pull_request_target at opened time, which skipped the
# previous deny-list and left first-timer PRs open.
if: >
github.event.pull_request.user.type != 'Bot' &&
!contains(fromJSON('["MEMBER","OWNER","COLLABORATOR","CONTRIBUTOR"]'),
github.event.pull_request.author_association)
runs-on: ubuntu-latest
steps:
- name: Require an open issue
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number }}
REPO: ${{ github.repository }}
AUTHOR_ASSOCIATION: ${{ github.event.pull_request.author_association }}
run: |
python3 << 'PY'
import json
import os
import re
import subprocess
import sys
repo = os.environ["REPO"]
pr_number = os.environ["PR_NUMBER"]
owner, name = repo.split("/", 1)
print(
"author_association=",
os.environ.get("AUTHOR_ASSOCIATION", ""),
sep="",
)
patterns = (
re.compile(r"(?<![\w./-])#(\d+)\b"),
re.compile(rf"{re.escape(owner)}/{re.escape(name)}#(\d+)\b"),
re.compile(
rf"https://github\.com/{re.escape(owner)}/{re.escape(name)}/issues/(\d+)\b"
),
)
def gh_json(*args: str) -> dict:
return json.loads(
subprocess.check_output(["gh", *args], text=True)
)
def is_open_repo_issue(number: int) -> bool:
result = subprocess.run(
["gh", "api", f"repos/{repo}/issues/{number}"],
capture_output=True,
text=True,
)
if result.returncode != 0:
stderr = result.stderr or ""
if "404" in stderr or "Not Found" in stderr:
return False
raise RuntimeError(
f"GitHub API error looking up #{number}: {stderr}"
)
payload = json.loads(result.stdout)
if "pull_request" in payload:
return False
return (payload.get("state") or "").lower() == "open"
pr = gh_json(
"pr", "view", pr_number, "--repo", repo, "--json", "title,body,state"
)
text = f"{pr.get('title') or ''}\n{pr.get('body') or ''}"
candidates = {
int(match)
for pattern in patterns
for match in pattern.findall(text)
}
if any(is_open_repo_issue(number) for number in sorted(candidates)):
sys.exit(0)
if (pr.get("state") or "").upper() == "CLOSED":
sys.exit(0)
comment = f"""Thanks for the pull request.
First-time contributors need an associated open issue before we can review a PR.
1. Open an issue with a [template](https://github.com/{repo}/issues/new/choose), or pick an existing open one.
2. Open a new PR (or reopen this one) whose title or body mentions that issue, for example `#123`.
See the [contributing guide](https://github.com/{repo}/blob/main/.github/CONTRIBUTING.md).
"""
subprocess.run(
[
"gh",
"pr",
"comment",
pr_number,
"--repo",
repo,
"--body",
comment,
],
check=True,
)
subprocess.run(
[
"gh",
"pr",
"edit",
pr_number,
"--repo",
repo,
"--add-label",
"needs-issue",
],
check=True,
)
subprocess.run(
["gh", "pr", "close", pr_number, "--repo", repo],
check=True,
)
PY

View File

@@ -100,6 +100,23 @@ jobs:
# GHSA-xph7-9rjv-w5fr (CVE-2026-45831): SimpleRBACAuthorizationProvider
# ignores tenant/database/collection scope.
--ignore-vuln GHSA-xph7-9rjv-w5fr
# nltk <=3.10.3: GHSA-8mgp-746c-j5xp (CVE-2026-81726): model-artifact
# APIs bypass pathsec and read/write outside allowed roots. No patched
# PyPI release yet (fixes are on nltk develop only). Transitive via
# crewai-tools[xml] -> unstructured; CrewAI does not call those APIs.
# TODO: drop this ignore when bumping nltk past 3.10.3 to a patched
# release; keep the ignore list in sync with .pre-commit-config.yaml.
--ignore-vuln GHSA-8mgp-746c-j5xp
# accelerate <=1.14.0: GHSA-4j2p-28q2-5m79 (CVE-2026-69112): path
# traversal / FIFO DoS via unsanitized sharded-checkpoint weight_map
# entries. No patched PyPI release yet (fix is huggingface/accelerate
# #4138, not shipped). Transitive via docling extras
# (docling-ibm-models / docling-slim[standard]); CrewAI does not load
# untrusted checkpoints through those APIs.
# TODO: drop this ignore when bumping accelerate past 1.14.0 to a
# patched release; keep the ignore list in sync with
# .pre-commit-config.yaml.
--ignore-vuln GHSA-4j2p-28q2-5m79
)
uv run pip-audit "${pip_audit_args[@]}"
continue-on-error: true

View File

@@ -3,19 +3,19 @@ repos:
hooks:
- id: ruff
name: ruff
entry: bash -c 'source .venv/bin/activate && uv run ruff check --config pyproject.toml "$@"' --
entry: bash -c 'case "$OSTYPE" in msys*|cygwin*|win32*) source .venv/Scripts/activate ;; *) source .venv/bin/activate ;; esac && uv run ruff check --config pyproject.toml "$@"' --
language: system
pass_filenames: true
types: [python]
- id: ruff-format
name: ruff-format
entry: bash -c 'source .venv/bin/activate && uv run ruff format --config pyproject.toml "$@"' --
entry: bash -c 'case "$OSTYPE" in msys*|cygwin*|win32*) source .venv/Scripts/activate ;; *) source .venv/bin/activate ;; esac && uv run ruff format --config pyproject.toml "$@"' --
language: system
pass_filenames: true
types: [python]
- id: mypy
name: mypy
entry: bash -c 'source .venv/bin/activate && uv run mypy --config-file pyproject.toml "$@"' --
entry: bash -c 'case "$OSTYPE" in msys*|cygwin*|win32*) source .venv/Scripts/activate ;; *) source .venv/bin/activate ;; esac && uv run mypy --config-file pyproject.toml "$@"' --
language: system
pass_filenames: true
types: [python]
@@ -29,8 +29,10 @@ repos:
- id: pip-audit
name: pip-audit
# Keep this ignore list in sync with .github/workflows/vulnerability-scan.yml.
# TODO: drop --ignore-vuln GHSA-8mgp-746c-j5xp when bumping nltk past 3.10.3.
# TODO: drop --ignore-vuln GHSA-4j2p-28q2-5m79 when bumping accelerate past 1.14.0.
entry: >-
bash -c 'source .venv/bin/activate && uv run pip-audit --skip-editable
bash -c 'case "$OSTYPE" in msys*|cygwin*|win32*) source .venv/Scripts/activate ;; *) source .venv/bin/activate ;; esac && uv run pip-audit --skip-editable
--ignore-vuln PYSEC-2024-277
--ignore-vuln PYSEC-2026-89
--ignore-vuln PYSEC-2026-97
@@ -59,7 +61,9 @@ repos:
--ignore-vuln GHSA-f4j7-r4q5-qw2c
--ignore-vuln GHSA-2wm9-hf6c-p5cr
--ignore-vuln GHSA-36p7-vc44-83pf
--ignore-vuln GHSA-xph7-9rjv-w5fr' --
--ignore-vuln GHSA-xph7-9rjv-w5fr
--ignore-vuln GHSA-8mgp-746c-j5xp
--ignore-vuln GHSA-4j2p-28q2-5m79' --
language: system
pass_filenames: false
stages: [pre-push, manual]

View File

@@ -202,6 +202,38 @@ def cleanup_event_handlers() -> Generator[None, Any, None]:
pass
@pytest.fixture(autouse=True, scope="function")
def reset_tracing_state() -> Generator[None, Any, None]:
"""Drop the tracing singleton and its context after each test.
`TraceCollectionListener` is a singleton, so without this three things leak
for the rest of the xdist worker:
- `TraceBatchManager.trace_batch_id`, which moves later trace POSTs from
`/tracing/ephemeral/batches` to `/tracing/batches/<id>/events` until some
unrelated cassette stops matching, naming neither the leak nor its source.
- `_listeners_setup`, which makes `setup_listeners` return early
(`trace_listener.py:208`) after `cleanup_event_handlers` has wiped the bus,
so tracing silently registers nothing and collects no events.
- the `_tracing_enabled` context var, which leaves tracing on for later tests
and re-registers `on_task_failed` alongside telemetry's — breaking
`test_task_failure_instrumentation`, which requires one handler per event.
All three go together: clearing the context vars is what makes dropping the
singleton safe, because the replacement listener then sees tracing disabled
and registers nothing. Dropping the singleton alone re-registers handlers and
breaks the telemetry test.
"""
yield
from crewai.events.listeners.tracing import utils as tracing_utils
from crewai.events.listeners.tracing.trace_listener import TraceCollectionListener
tracing_utils._tracing_enabled.set(None)
tracing_utils._tui_mode.set(False)
TraceCollectionListener._instance = None
@pytest.fixture(autouse=True, scope="function")
def reset_event_state() -> None:
"""Reset event system state before each test for isolation."""

File diff suppressed because it is too large Load Diff

View File

@@ -4,6 +4,145 @@ description: "تحديثات المنتج والتحسينات وإصلاحات
icon: "clock"
mode: "wide"
---
<Update label="16 سبتمبر 2026">
## v1.15.22
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.15.22)
## ما الذي تغير
### الميزات
- دعم الأسماء المستعارة كمعرفات اتصال
- تسجيل أسباب فشل إنشاء النشر
- جمع ملاحظات بشرية وإيقاف الأحداث في التتبع
- إضافة متغير السياق `llm_overlay` لتوجيه أدوار الوكلاء إلى النماذج
- نقل `task_prompt` والإخراج في حمولات تنفيذ الوكلاء
- التحقق من تكاملات المنصة أثناء إعداد الطاقم
- إضافة أدوات المنصة إلى معالج JSON للطاقم
- كشف كتالوج تطبيق CrewAI Platform
- إضافة OpenRouter كمزود تضمين مدعوم
### إصلاحات الأخطاء
- قبول CRLF في تعريفات المهارات المضمنة
- تحميل عناوين URL لملفات النصوص من خلال المستخرج الآمن
- إغلاق اتصالات SQLite في تخزين مخرجات مهمة البداية
- نقل `from_cache` في حدث `ToolUsageFinishedEvent` لمسار الأداة الأصلية
- رفع `ValueError` بدلاً من رفع عاري في المحمل
- دعم الأنواع غير الأولية في SQLiteFlowPersistence
- تحسين تعليمات وكلاء الترميز
- قراءة نقاط التحقق JSON كـ UTF-8
- الكتابة فوق النسخة الاحتياطية القديمة لـ `poetry.lock` على Windows
- مفتاح مكالمات الأداة المتدفقة بواسطة فهرس السلك في Azure
- الحفاظ على أجزاء محتوى بيانات الملف في Gemini
- احترام `read_only` في أوقات الوصول لـ `update()` و `recall()`
- إرسال `reasoning_effort` إلى كل نموذج استدلال OpenAI
- منع الأعطال في واجهة المستخدم عند تشغيلها عندما يحتوي الإخراج المتدفق على `[...]`
- رفض إعادة التشغيل عندما تختلف المهام المخزنة
- استخدام حراس `sys.platform` للتوافق مع mypy على Windows
- طلب الإجابة النهائية القسرية كدور مستخدم
- الاحتفاظ بالقيمة null في مخطط مخرجات المهمة المضمن في المطالبة
- محاذاة `DOCXSearchTool` مع نمط المخطط الثابت القياسي RAG
### الوثائق
- إضافة `xpu` إلى خيارات جهاز التضمين
- سرد جميع حزم مساحة العمل
## المساهمون
@ASTion24, @BlueX888, @HUAN2022A, @RaycarlLei, @Rohitkanithi, @SWAPI03, @SharoonSharif, @ShivangiRay, @Theater-ahyeon, @Vidit-Ostwal, @gamal1osama, @github-actions[bot], @joaomdmoura, @lorenzejay, @mhbuehler, @modusensus, @monkscode, @rohitkanithi, @roli-lpci, @vinibrsl, @wangtaotaotao95
</Update>
<Update label="9 سبتمبر 2026">
## v1.15.21
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.15.21)
## ما الذي تغير
### الميزات
- إضافة بيانات تتبع لتتبع وقت تشغيل نقاط التحقق واستخدام واجهة سطر الأوامر.
### إصلاحات الأخطاء
- إصلاح أخطاء البوابة المبلغ عنها داخل استجابة HTTP 200.
- الحفاظ على دفع النشر عند إنشاء مصدر AMP.
- الإبلاغ عن فشل السحب بدلاً من رفع IndexError في تكامل Oxylabs.
- توجيه جميع نماذج DashScope عبر المزود الأصلي.
- الاحتفاظ بنقاط تحقق JSON كـ UTF-8.
- إزالة $ الزائدة في عناوين URL الخاصة بالبحث في f-string لـ BrightData.
- دعم مصفوفات نوع القائمة في تحويل مخطط JSON.
- تصحيح نافذة السياق لـ gpt-4o-mini من 200000 إلى 128000.
- الحفاظ على وسائط استدعاء أداة البث عند contentBlockStop.
- جعل خطافات ما قبل الالتزام قابلة للنقل على Windows.
### الوثائق
- توضيح أن تتبع البيانات يتم إدارته بشكل منفصل عن بيانات التتبع.
- إصلاح رابط مرجع البحث المتوازي.
- إزالة المعلمات القديمة من سلسلة توثيق handle_llm_stream_chunk.
- إصلاح أمثلة سلسلة توثيق مخرجات البث.
- استخدام UUIDs الخاصة بالمنظمة في مرجع تثبيت المهارة.
## المساهمون
@Alphaxiaoteng, @DrewWhittleNZ, @Ghraven, @Shxiao101, @Vaishnavi220506, @Vidit-Ostwal, @danielfsbarreto, @georgeatparallel, @github-actions[bot], @jessemiller, @joaomdmoura, @kimnamu, @kiwoongyoon, @liang0417, @lorenzejay, @oxy-giedrius, @simpleqt, @uoparaji
</Update>
<Update label="4 سبتمبر 2026">
## v1.15.20
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.15.20)
## ما الذي تغير
### إصلاحات الأخطاء
- إصلاح اكتشاف اسم مستعار لأداة المنصة القديمة
### الوثائق
- تحديث اللقطة وسجل التغييرات للإصدار v1.15.19
## المساهمون
@joaomdmoura, @vinibrsl
</Update>
<Update label="4 سبتمبر 2026">
## v1.15.19
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.15.19)
## ما الذي تغير
### الميزات
- إضافة عميل تكامل Clipper
- إضافة `now()` إلى بيئة تعبير CEL
- تسجيل كيفية انتهاء تشغيل الطاقم لكل مستخدم
- الإبلاغ عن حجم الآلة كحزام خشن، وليس عدد النوى
- إضافة عميل قابل للحقن لأدوات منصة CrewAI
### إصلاحات الأخطاء
- إصلاح قراءة عناوين octet-stream و xlsx في `urlreadtool`
- إصلاح إضافة دوران المستخدم المتأخر في موفر Gemini الأصلي
- تطبيع المخطط والمنفذ في عنوان URL الأساسي لـ Ollama
- الحفاظ على تكوينات النطاق القابلة لإعادة الاستخدام في الذاكرة
- تحديث `pypdf` إلى 6.16.2 لمعالجة ثغرة أمنية
- تحديث `nltk` إلى 3.10.3 لمعالجة ثغرة أمنية
- إصلاح المخرجات الهيكلية الأصلية لنماذج Claude الحالية وسقف CVE لـ Snowflake
- تشغيل روابط استدعاء النموذج على كل مسار ونشر رفض
### الوثائق
- إزالة `CodeInterpreterTool` من أمثلة نظرة عامة على الذكاء الاصطناعي/التعلم الآلي
- توجيه رابط `prompt-template` إلى مساره الحالي
- تحديث دليل القنوات إلى واجهة برمجة التطبيقات الحالية لقنوات CopilotKit
- تحديث معرفات نماذج Gemini المتقاعدة
## المساهمون
@Vidit-Ostwal, @a-yeyang, @github-actions[bot], @hvlcrs, @joaomdmoura, @kikifrost, @lorenzejay, @lucasgomide, @parthiban-sivakumar, @ranst91, @tandede, @thiagomoretto, @vinibrsl
</Update>
<Update label="27 أغسطس 2026">
## v1.15.18

View File

@@ -201,6 +201,7 @@ def crew(self) -> Crew:
```shell Terminal
crewai deploy push
```
يحافظ الدفع على المصدر المستخدم عند الإنشاء. إضافة `origin` لاحقًا لا تحوّل نشر ZIP إلى git.
- **حالة النشر**:
```shell Terminal
@@ -286,6 +287,7 @@ crewai traces [COMMAND]
```shell Terminal
crewai traces enable
```
- يحدّث موجه التشغيل الأول (`Would you like to view your execution traces?`) هذا التفضيل أيضاً
<Note>
**لتفعيل التتبع**، استخدم أيًا من هذه الطرق:

View File

@@ -636,6 +636,21 @@ agent = Agent(
}
}
)
# Option 4: Use OpenRouter embeddings (supports models across providers)
# Set OPENROUTER_API_KEY environment variable if api_key is omitted in config
crew = Crew(
agents=[agent],
tasks=[...],
knowledge_sources=[knowledge_source],
embedder={
"provider": "openrouter",
"config": {
"model_name": "openai/text-embedding-3-small",
"api_key": "your-openrouter-api-key" # Optional if OPENROUTER_API_KEY is set
}
}
)
```
#### إعداد تضمينات Azure OpenAI

View File

@@ -1339,6 +1339,38 @@ llm = LLM(
llm = LLM(model="gpt-4")
```
</Tab>
<Tab title="أخطاء البوابة">
<Tip>
تُعيد البوابات مثل OpenRouter الرمز `200 OK` بمجرد قبول المزود الأساسي للطلب، لذلك يصل انتهاء مهلة المزود داخل جسم الاستجابة بدلًا من رمز الحالة.
</Tip>
تُطلق CrewAI الاستثناء نفسه الذي كان رمز الحالة الأصلي سيُنتجه، ومن ثم يلتقط منطق إعادة المحاولة الموجود لديك هذا الفشل المُقنَّع:
```python
import openai
from pydantic import BaseModel
from crewai import LLM
class Report(BaseModel):
summary: str
llm = LLM(model="openrouter/z-ai/glm-5.3", response_format=Report)
try:
result = llm.call("Summarize the incident", response_model=Report)
except openai.InternalServerError as e:
# "z-ai/glm-5.3 via openrouter.ai returned HTTP 200 with an upstream error
# and no choices: The operation was aborted (upstream code 504)"
print(f"Upstream provider failed, safe to retry: {e}")
```
<Warning>
إن استخدام `response_model` كبير أو متداخل بعمق يزيد احتمال انتهاء مهلة المزود. تعامل مع هذه الحالات كأعطال مؤقتة في المزود، وليس كإنتاج النموذج مخرجات منظمة تالفة.
</Warning>
</Tab>
<Tab title="طول السياق">
<Tip>
استخدم نماذج سياق أكبر للمهام الواسعة

View File

@@ -736,7 +736,7 @@ memory = Memory(llm="anthropic/claude-3-haiku-20240307")
memory = Memory(llm="ollama/llama3.2")
# Use Google Gemini
memory = Memory(llm="gemini/gemini-2.0-flash")
memory = Memory(llm="gemini/gemini-3.7-flash")
# Pass a pre-configured LLM instance with custom settings
llm = LLM(model="gpt-4o", temperature=0)

View File

@@ -202,13 +202,17 @@ crewai skill publish
### التثبيت
ثبّت مهارة منشورة عبر مرجعها `@org/name`:
ثبّت مهارة منشورة عبر مرجعها `@org-uuid/name`:
```shell Terminal
crewai skill install @acme/code-review
crewai skill install @your-org-uuid/code-review
```
داخل مشروع الطاقم تُثبَّت المهارة في `./skills/{name}/`؛ وخارج المشروع تذهب إلى ذاكرة التخزين المؤقتة المشتركة في `~/.crewai/skills/{org}/{name}/`.
<Note>
استخدم **UUID** الخاص بمؤسستك وليس اسمها — فأسماء المؤسسات ليست فريدة، وقد يشير الاسم إلى مؤسسة خاطئة فيفشل التثبيت برسالة "غير موجود". شغّل `crewai org list` لعرض الـ UUID (عمود `ID`) لكل مؤسسة تنتمي إليها.
</Note>
داخل مشروع الطاقم تُثبَّت المهارة في `./skills/{name}/`؛ وخارج المشروع تذهب إلى ذاكرة التخزين المؤقتة المشتركة في `~/.crewai/skills/{org-uuid}/{name}/`.
يمكن للوكلاء أيضًا الإشارة إلى مهارات السجل مباشرة — يتم حلّها من ذاكرة التخزين المؤقتة المحلية (أو من مجلد `skills/` في المشروع) وقت التشغيل:
@@ -217,7 +221,7 @@ agent = Agent(
role="Senior Code Reviewer",
goal="Review pull requests for quality and security issues",
backstory="Staff engineer with expertise in secure coding practices.",
skills=["@acme/code-review"], # registry ref, resolved locally
skills=["@your-org-uuid/code-review"], # registry ref, resolved locally
)
```

View File

@@ -26,7 +26,7 @@ mode: "wide"
- **معالجة الأخطاء** – توجيه كيفية استجابة الـ Agents للإخفاقات والاستثناءات وحالات انتهاء المهلة.
- **مطالبات خاصة بالأدوات** – تعريف تعليمات مفصلة لكيفية استدعاء الأدوات أو استخدامها.
اطلع على [قوالب المطالبات الأصلية في مستودع CrewAI](https://github.com/crewAIInc/crewAI/blob/main/src/crewai/translations/en.json) لمعرفة كيفية تنظيم هذه العناصر. من هناك، يمكنك تجاوزها أو تكييفها حسب الحاجة لفتح سلوكيات متقدمة.
اطلع على [قوالب المطالبات الأصلية في مستودع CrewAI](https://github.com/crewAIInc/crewAI/blob/main/lib/crewai/src/crewai/translations/en.json) لمعرفة كيفية تنظيم هذه العناصر. من هناك، يمكنك تجاوزها أو تكييفها حسب الحاجة لفتح سلوكيات متقدمة.
## فهم تعليمات النظام الافتراضية

View File

@@ -11,7 +11,7 @@ mode: "wide"
## إنشاء مشروع باستخدام CLI
استخدم CLI الخاص بـ CrewAI لإنشاء هيكل مشروع، وسيُضاف `AGENTS.md` تلقائيًا في الجذر.
استخدم CLI الخاص بـ CrewAI لإنشاء هيكل مشروع. يُضاف `AGENTS.md` في الجذر، ومعه ملفا `CLAUDE.md` و`GEMINI.md` اللذان يستوردانه، بحيث يقرأ Claude Code وGemini CLI نفس التوجيهات التي يقرأها كل مساعد آخر.
```bash
# Crew
@@ -32,24 +32,28 @@ crewai tool create my_tool
### Claude Code
يخزّن Claude Code ذاكرة المشروع في `CLAUDE.md`. يمكنك تهيئته بـ `/init` وتحريره باستخدام `/memory`. يدعم Claude Code أيضًا الاستيرادات داخل `CLAUDE.md`، فيمكنك إضافة سطر واحد مثل `@AGENTS.md` لسحب التعليمات المشتركة دون تكرارها.
يقرأ Claude Code ملف `CLAUDE.md` ويتجاهل `AGENTS.md`. تأتي المشاريع المُنشأة بملف `CLAUDE.md` تعليمته الوحيدة هي سطر الاستيراد `@AGENTS.md`، بحيث تُحمَّل التوجيهات المشتركة دون تكرارها. أضف الملاحظات الخاصة بـ Claude تحت هذا السطر واحتفظ بالاصطلاحات المشتركة في `AGENTS.md`.
يمكنك ببساطة استخدام:
لمشروع أُنشئ قبل أن يُضاف `CLAUDE.md` إلى الهيكل، أضف الاستيراد بنفسك:
```bash
mv AGENTS.md CLAUDE.md
printf '@AGENTS.md\n' > CLAUDE.md
```
لا تُعِد تسمية `AGENTS.md` إلى `CLAUDE.md`: يقرأ Codex وCursor ملف `AGENTS.md`، وإعادة التسمية تخفيه عنهما.
### Gemini CLI وGoogle Antigravity
يقوم Gemini CLI وAntigravity بتحميل ملف سياق المشروع (الافتراضي: `GEMINI.md`) من جذر المستودع والمجلدات الأصلية. يمكنك تهيئته لقراءة `AGENTS.md` بدلاً من ذلك (أو بالإضافة إليه) بتعيين `context.fileName` في إعدادات Gemini CLI. على سبيل المثال، عيّنه إلى `AGENTS.md` فقط، أو أدرج كلاً من `AGENTS.md` و`GEMINI.md` إذا أردت الاحتفاظ بتنسيق كل أداة.
يقوم Gemini CLI وAntigravity بتحميل ملف سياق المشروع (الافتراضي: `GEMINI.md`) من جذر المستودع والمجلدات الأصلية. تأتي المشاريع المُنشأة بملف `GEMINI.md` تعليمته الوحيدة هي سطر الاستيراد `@./AGENTS.md`، بحيث تُحمَّل التوجيهات المشتركة دون تكرارها. أضف الملاحظات الخاصة بـ Gemini تحت هذا السطر واحتفظ بالاصطلاحات المشتركة في `AGENTS.md`.
يمكنك ببساطة استخدام:
لمشروع أُنشئ قبل أن يُضاف `GEMINI.md` إلى الهيكل، أضف الاستيراد بنفسك:
```bash
mv AGENTS.md GEMINI.md
printf '@./AGENTS.md\n' > GEMINI.md
```
بدلاً من ذلك، عيّن `context.fileName` في إعدادات Gemini CLI ليشمل `AGENTS.md` فيقرأه Gemini مباشرة. لا تُعِد تسمية `AGENTS.md` إلى `GEMINI.md`: يقرأ Codex وCursor ملف `AGENTS.md`، وإعادة التسمية تخفيه عنهما.
### Cursor
يدعم Cursor ملف `AGENTS.md` كملف تعليمات مشروع. ضعه في جذر المشروع لتوفير توجيهات لمساعد البرمجة في Cursor.

View File

@@ -75,7 +75,7 @@ research_crew/
}
```
استبدل `provider/model-id` بالنموذج الذي تستخدمه، مثل `openai/gpt-4o` أو `anthropic/claude-sonnet-4-6` أو `gemini/gemini-2.0-flash-001`.
استبدل `provider/model-id` بالنموذج الذي تستخدمه، مثل `openai/gpt-4o` أو `anthropic/claude-sonnet-4-6` أو `gemini/gemini-3.7-flash`.
## الخطوة 3: تعريف المهام وإعدادات الـ Crew

View File

@@ -104,7 +104,7 @@ crewai flow add-crew content-crew
}
```
استبدل `provider/model-id` بالنموذج الذي تستخدمه، مثل `openai/gpt-4o` أو `gemini/gemini-2.0-flash-001` أو `anthropic/claude-sonnet-4-6`.
استبدل `provider/model-id` بالنموذج الذي تستخدمه، مثل `openai/gpt-4o` أو `gemini/gemini-3.7-flash` أو `anthropic/claude-sonnet-4-6`.
3. أنشئ `src/guide_creator_flow/crews/content_crew/crew.jsonc`:

View File

@@ -0,0 +1,156 @@
---
title: القنوات
description: شغّل نفس وكيل CrewAI كروبوت على Slack أو Teams باستخدام CopilotKit Channels SDK ومنصة Intelligence المُدارة.
icon: messages
mode: "wide"
---
## قابل مستخدميك حيث هم بالفعل
وكيل CrewAI الذي بنيته في [النظرة العامة](/edge/ar/guides/frontend/overview) لا يجب أن يعيش خلف تطبيق ويب فقط. يمكن لنفس الـ Crew أو الـ Flow أن يعمل كروبوت داخل منصة مراسلة. لا حاجة لإعادة البناء ولا لنسخة ثانية من منطق وكيلك: يبقى الوكيل مكشوفًا عبر [بروتوكول AG-UI](https://docs.ag-ui.com)، وتقوم **قناة** بتشغيله من Slack أو Microsoft Teams.
يوفّر [Channels SDK](https://docs.copilotkit.ai/slack) من CopilotKit تلك القناة. تُعرّف `createChannel` في وقت تشغيل صغير، وتوجّهه إلى وكيل CrewAI الخاص بك، وتتولى منصة **Intelligence** المُدارة من CopilotKit التوسّط في الاتصال مع مزوّد المراسلة.
<Note>
على خلاف بقية هذا القسم، فإن Channels **ليست ذاتية الاستضافة**. تعمل من خلال **CopilotKit Intelligence** — وهي سطح مطلوب لـ Channels، بحكم التصميم (تتوفر طبقة مجانية). تحتفظ Intelligence باتصال المنصة وبيانات الاعتماد، وتستقبل كل حدث من المنصة، وتسلّم الدور إلى عملية قناتك؛ تشغّل عمليتك الوكيل وتبثّ الرد مرة أخرى. تقوم بإعداد Slack مرة واحدة في لوحة تحكم Intelligence، ولا تدخل بيانات اعتماد المنصة عمليتك أبدًا. يبقى وكيلك وأدواتك وحالتك ملكًا لك.
</Note>
## كيف تتكامل الأجزاء معًا
لا يتغير أي شيء بخصوص خادم وكيل CrewAI الخاص بك. يستمر في تقديم الـ Crew أو الـ Flow عبر AG-UI تمامًا كما في النظرة العامة. ما تضيفه هو عملية Node منفصلة طويلة الأمد مبنية باستخدام `@copilotkit/channels`: تسجّل قناة على `CopilotRuntime`، وتتصل بـ Intelligence، وتشغّل وكيلك كلما وصلت رسالة.
```
Slack / Teams ──► CopilotKit Intelligence ──► channel process (Node) ──► CrewAI server (AG-UI) ──► Crew / Flow
```
تحتفظ عملية القناة باتصال دائم مع بوابة Intelligence، لذا فهي تحتاج إلى مضيف طويل الأمد — لا يمكن لمعالج طلبات بلا خادم (serverless) أن يملك ذلك الاتصال. يمكن لخادم CrewAI الخاص بك أن يستمر في تقديم واجهة الويب الأمامية من النظرة العامة في الوقت نفسه: تطبيق الويب والقناة ما هما إلا عميلان لنقطة نهاية AG-UI واحدة.
## دليل التكامل
<Steps>
<Step title="ثبّت حزم Channels">
يأتي Channels SDK مكتمل العناصر — كل منصة تُشحن في الحزمة الواحدة، بلا محوّل خاص بكل منصة لتثبيته. أضفه إلى جانب وقت التشغيل الذي يستضيف القناة وعميل CrewAI AG-UI:
```bash
npm install @copilotkit/channels @copilotkit/runtime @ag-ui/crewai
```
</Step>
<Step title="أنشئ قناة في Intelligence">
في [لوحة تحكم CopilotKit](https://docs.copilotkit.ai/slack)، أنشئ قناة واربط Slack — ترشدك Intelligence خلال إنشاء تطبيق Slack وتحتفظ ببيانات اعتماده. يترك ذلك متغيّري بيئة لعمليتك، كلاهما من لوحة التحكم:
```bash
export INTELLIGENCE_API_KEY=... # authenticates the runtime with Intelligence (free tier available)
export INTELLIGENCE_CHANNEL_ID=... # the Channel ID, matched by createChannel({ name })
```
</Step>
<Step title="عرّف القناة">
تُعرّف `createChannel` القناة وتربط وكيلك بها. ابنِ الوكيل كمصنع لكل خيط (thread) بحيث تحصل كل محادثة على جلستها الخاصة، مستخدمًا نفس `CrewAIAgent` الذي تستخدمه النظرة العامة في وقت تشغيل الويب، موجّهًا إلى نقطة نهاية AG-UI الخاصة بك. تتيح `identifyUser: "platform"` لـ Intelligence ربط كل مستخدم من المنصة بهوية ثابتة.
```ts
// channel.ts
import { createChannel } from "@copilotkit/channels";
import { CrewAIAgent } from "@ag-ui/crewai";
const channel = createChannel({
name: process.env.INTELLIGENCE_CHANNEL_ID!, // must match the Channel ID in Intelligence
identifyUser: "platform",
// A fresh agent per conversation, pointed at your CrewAI AG-UI endpoint.
agent: (threadId) => {
const agent = new CrewAIAgent({ url: "http://localhost:8000/recipe" });
agent.threadId = threadId;
return agent;
},
});
// A mention subscribes the thread and runs the agent; afterwards every message
// in a subscribed thread runs it without needing another mention.
channel.onMention(async ({ thread }) => {
await thread.subscribe();
await thread.runAgent();
});
channel.onMessage(async ({ thread }) => {
if (await thread.isSubscribed()) await thread.runAgent();
});
export { channel };
```
</Step>
<Step title="سجّل القناة على وقت التشغيل">
أنشئ `CopilotRuntime` مع بوابة Intelligence وقناتك، ثم قدّمه باستخدام `createCopilotNodeListener`. تبقى خريطة `agents` فارغة — القناة توفّر وكيلها الخاص. انتظر حتى تكون القناة جاهزة كي يفشل بدء التشغيل بصوت عالٍ عند وجود إعداد معطوب.
```ts
// server.ts
import { createServer } from "node:http";
import { CopilotRuntime, CopilotKitIntelligence } from "@copilotkit/runtime/v2";
import { createCopilotNodeListener } from "@copilotkit/runtime/v2/node";
import { channel } from "./channel";
const runtime = new CopilotRuntime({
agents: {}, // the channel supplies its own agent; no web-facing agents needed
intelligence: new CopilotKitIntelligence({
apiKey: process.env.INTELLIGENCE_API_KEY!, // free tier available
}),
channels: [channel],
});
const listener = createCopilotNodeListener({ runtime });
await listener.channels?.ready({ timeoutMs: 15_000 });
createServer(listener).listen(3123, () => {
console.log("Channels runtime listening on port 3123");
});
```
</Step>
<Step title="شغّل وقت تشغيل القناة">
ابدأه إلى جانب خادم وكيل CrewAI الخاص بك:
```bash
uvicorn server:app --port 8000 # terminal 1 — CrewAI agent server
npx tsx server.ts # terminal 2 — Channels runtime
```
اذكر الروبوت في Slack أو Teams فيشغّل الـ Crew أو الـ Flow الخاص بك، ويبثّ الرد مرة أخرى داخل الخيط. يبقى الخيط مشتركًا، لذا تعمل رسائل المتابعة دون الحاجة إلى ذكر آخر.
</Step>
</Steps>
## نموذج الأحداث
تتفاعل القناة مع أحداث المنصة عبر معالِجات، ويستقبل كل معالِج خيطًا (`thread`) تديره بعدد قليل من الدوال:
- **`channel.onMention`** يُطلَق عندما يذكر مستخدم الروبوت بـ @. استدعِ `thread.subscribe()` للانضمام إلى الخيط، ثم `thread.runAgent()` لتشغيل وكيل CrewAI الخاص بك عند الذكر.
- **`channel.onMessage`** يُطلَق عند كل رسالة في خيط يمكن للروبوت رؤيته. قيّده بـ `thread.isSubscribed()` كي لا يستجيب الوكيل إلا حيث انضمّ، ثم `thread.runAgent()`.
- **`thread.runAgent()`** يشغّل وكيل CrewAI المرفق للدور الحالي ويبثّ مخرجاته مرة أخرى داخل القناة. مرّر `{ prompt }` لتجاوز النص الذي يعمل عليه الوكيل.
يستقبل وكيلك `RunAgentInput` عاديًا من AG-UI ويصدر أحداث AG-UI عادية؛ تبقى آليات المنصة خلف القناة، لذا يعمل نفس الـ Crew أو الـ Flow دون تغيير عبر كل منصة. تكشف القناة أيضًا معالِجات للترحيبات والمقاطعات والأوامر والتفاعلات والنوافذ (modals) — راجع [مرجع `Channel`](https://docs.copilotkit.ai/reference/channels/classes/Channel) للاطلاع على السطح الكامل.
## دعم المنصات
يغطي مسار Intelligence المُدار **Slack** و**Microsoft Teams** اليوم — يعمل نفس كود القناة على أيٍّ منهما، وتفيد `message.platform` / `thread.platform` بالأصل الأصلي. تُبلَغ المنصات الأخرى (Discord وTelegram وWhatsApp) عبر **محوّلات مباشرة** يشغّلها المطوّر بدلًا من المسار المُدار — تملك عمليتك الخاصة بيانات اعتماد المنصة والنقل. راجع [توثيق CopilotKit Channels](https://docs.copilotkit.ai/slack) للاطلاع على قائمة المنصات الحالية والإعداد الخاص بكل منصة.
## ذات صلة
<CardGroup cols={2}>
<Card title="النظرة العامة على الواجهة الأمامية" icon="browser" href="/edge/ar/guides/frontend/overview">
قدّم الـ Crew أو الـ Flow الخاص بك عبر AG-UI — الأساس الذي تُبنى عليه كل قناة.
</Card>
<Card title="التدخل البشري (Human-in-the-Loop)" icon="user-check" href="/edge/en/guides/frontend/human-in-the-loop">
أوقف الوكيل مؤقتًا لجمع موافقة المستخدم أو مدخلاته في منتصف التشغيل.
</Card>
</CardGroup>

View File

@@ -0,0 +1,238 @@
---
title: النظرة العامة على الواجهة الأمامية
description: ابنِ واجهات مستخدم تفاعلية لوكلاء CrewAI الخاصين بك باستخدام CopilotKit وبروتوكول AG-UI.
icon: browser
mode: "wide"
---
## امنح وكلاءك واجهة مستخدم
يشغّل CrewAI وكلاءك. ويمنحهم [CopilotKit](https://copilotkit.ai) واجهة أمامية. معًا يتيحان لك بناء تطبيقات يحادث فيها المستخدمون Crew أو Flow، ويشاهدونه يعمل في الوقت الفعلي، ويوافقون على قراراته، ويرون مخرجاته معروضة كواجهة حيّة بدلًا من جدران من النص.
يتصل الاثنان عبر [بروتوكول AG-UI](https://docs.ag-ui.com). تكشف حزمة `ag-ui-crewai` أي Crew أو Flow كنقطة نهاية AG-UI. وتستهلك خطافات (hooks) ومكوّنات React من CopilotKit تلك النقطة. يفتح ذلك تجارب تتجاوز بكثير صندوق المحادثة:
<CardGroup cols={2}>
<Card title="واجهة المستخدم التوليدية (Generative UI)" icon="wand-magic-sparkles" href="/edge/en/guides/frontend/generative-ui">
اعرض استدعاءات أدوات الوكيل وحالته كمكوّنات React خاصة بك.
</Card>
<Card title="التدخل البشري (Human-in-the-Loop)" icon="user-check" href="/edge/en/guides/frontend/human-in-the-loop">
أوقف الوكيل مؤقتًا لجمع موافقة المستخدم أو مدخلاته في منتصف التشغيل.
</Card>
<Card title="الحالة المشتركة (Shared State)" icon="arrows-rotate" href="/edge/en/guides/frontend/shared-state">
أبقِ حالة الوكيل وواجهة تطبيقك متزامنتين في الاتجاهين.
</Card>
<Card title="القنوات (Channels)" icon="messages" href="/edge/ar/guides/frontend/channels">
شغّل نفس الوكيل كروبوت على Slack أو Discord أو Teams.
</Card>
</CardGroup>
يجعل هذا الدليل Crew أو Flow يتحدث مع واجهة أمامية بـ Next.js من البداية إلى النهاية. تبني بقية القسم على التطبيق الذي تعدّه هنا.
## البنية
هناك ثلاثة أجزاء:
1. **خادم وكيل CrewAI** — عملية Python تقدّم الـ Crew أو الـ Flow الخاص بك عبر AG-UI (FastAPI + `ag-ui-crewai`).
2. **وقت تشغيل CopilotKit** — مسار Next.js يسجّل وكيلك ويوكّل الطلبات إليه.
3. **الواجهة الأمامية بـ React** — مزوّد `<CopilotKit>` إلى جانب مكوّنات المحادثة والواجهة التوليدية.
```
React app ──► CopilotKit runtime (/api/copilotkit) ──► CrewAI server (AG-UI) ──► Crew / Flow
```
<Note>
يغطي هذا الدليل المسار **الذاتي الاستضافة**: تشغّل خادم وكيل CrewAI بنفسك باستخدام `ag-ui-crewai`، ويعمل محليًا دون أي خدمة مُدارة. يقدّم CopilotKit أيضًا مسارًا **مُدارًا** (CopilotKit Cloud / Enterprise Intelligence) بخيوط مستضافة وأداة فحص — راجع [دليل البدء السريع لـ CopilotKit مع CrewAI](https://docs.copilotkit.ai/crewai-crews/quickstart) إن أردت ذلك بدلًا منه. كود الواجهة الأمامية في هذا القسم هو نفسه في الحالتين؛ الاختلاف فقط في كيفية استضافة الوكيل وتسجيله.
</Note>
<Note>
يعمل CrewAI خلف AG-UI بثلاثة أشكال: الـ **Flows** العادية (المستخدمة في هذه الأدلة)، و**[الـ Flows المحادثية (Conversational Flows)](/edge/en/guides/frontend/conversational-flows)** (أصلية، مدركة للجلسة، قائمة على الأدوار، بتكافؤ كامل في الميزات)، والـ **Crews** (محادثة أساسية). الواجهة الأمامية في هذا القسم متطابقة عبرها جميعًا — الاختلاف فقط في تأليف الخلفية وتسجيلها.
</Note>
## دليل التكامل
<Steps>
<Step title="قدّم وكيلك عبر AG-UI">
ثبّت حزمة التكامل في مشروع CrewAI الخاص بك:
```bash
pip install ag-ui-crewai
```
اكشف وكيلك من تطبيق FastAPI. تستخدم الـ Flows دالة `add_crewai_flow_fastapi_endpoint`؛ وتستخدم الـ Crews دالة `add_crewai_crew_fastapi_endpoint`. يمكنك تسجيل ما تشاء منها، كلٌّ على مساره الخاص.
<CodeGroup>
```python Flow
# server.py
from fastapi import FastAPI
from ag_ui_crewai.endpoint import add_crewai_flow_fastapi_endpoint
from my_agents.recipe_flow import RecipeFlow
app = FastAPI(title="CrewAI Agent Server")
add_crewai_flow_fastapi_endpoint(
app=app,
flow=RecipeFlow(),
path="/recipe",
)
```
```python Crew
# server.py
from fastapi import FastAPI
from ag_ui_crewai.endpoint import add_crewai_crew_fastapi_endpoint
from my_agents.research_crew import ResearchCrew
app = FastAPI(title="CrewAI Agent Server")
add_crewai_crew_fastapi_endpoint(
app=app,
crew=ResearchCrew().crew(),
path="/research",
)
```
</CodeGroup>
شغّله:
```bash
uvicorn server:app --port 8000
```
<Note>
اضبط متغيّرات البيئة الخاصة بمزوّد الـ LLM الخاص بك (على سبيل المثال `OPENAI_API_KEY`) قبل بدء الخادم.
</Note>
</Step>
<Step title="أنشئ تطبيق Next.js">
إن لم تكن لديك واجهة أمامية بعد، أنشئ هيكلًا:
```bash
npx create-next-app@latest my-app
cd my-app
```
ثبّت CopilotKit وعميل CrewAI AG-UI:
```bash
npm install @copilotkit/react-core @copilotkit/react-ui @copilotkit/runtime @ag-ui/crewai
```
</Step>
<Step title="أضف وقت تشغيل CopilotKit">
أنشئ مسارًا يسجّل وكيل (أو وكلاء) CrewAI مع وقت تشغيل CopilotKit. يشير كل وكيل إلى مسار على خادم Python الخاص بك عبر `CrewAIAgent`.
```ts
// app/api/copilotkit/route.ts
import {
CopilotRuntime,
InMemoryAgentRunner,
createCopilotEndpoint,
} from "@copilotkit/runtime/v2";
import { CrewAIAgent } from "@ag-ui/crewai";
import { handle } from "hono/vercel";
const runtime = new CopilotRuntime({
agents: {
recipe: new CrewAIAgent({ url: "http://localhost:8000/recipe" }),
},
runner: new InMemoryAgentRunner(),
});
const app = createCopilotEndpoint({
runtime,
basePath: "/api/copilotkit",
});
const handler = handle(app);
export const GET = handler;
export const POST = handler;
```
</Step>
<Step title="غلّف تطبيقك بالمزوّد">
وجّه `<CopilotKit>` إلى مسار وقت التشغيل واذكر اسم الوكيل الذي سجّلته.
```tsx
// app/page.tsx
"use client";
import { CopilotKit } from "@copilotkit/react-core";
import { CopilotSidebar } from "@copilotkit/react-core/v2";
import "@copilotkit/react-core/v2/styles.css";
export default function Page() {
return (
<CopilotKit runtimeUrl="/api/copilotkit" agent="recipe">
<YourApp />
<CopilotSidebar agentId="recipe" labels={{ modalHeaderTitle: "Assistant" }} />
</CopilotKit>
);
}
```
</Step>
<Step title="شغّله">
ابدأ العمليتين وافتح التطبيق. تشغّل المحادثة في الشريط الجانبي الآن الـ Crew أو الـ Flow الخاص بك.
```bash
uvicorn server:app --port 8000 # terminal 1
npm run dev # terminal 2
```
</Step>
</Steps>
## خيارات واجهة المحادثة
يشحن CopilotKit ثلاثة أسطح محادثة قابلة للتبديل. بدّل المكوّن؛ يبقى التوصيل متطابقًا.
<CodeGroup>
```tsx Sidebar
import { CopilotSidebar } from "@copilotkit/react-core/v2";
<CopilotSidebar agentId="recipe" />
```
```tsx Popup
import { CopilotPopup } from "@copilotkit/react-core/v2";
<CopilotPopup agentId="recipe" />
```
```tsx Inline
import { CopilotChat } from "@copilotkit/react-core/v2";
<CopilotChat agentId="recipe" />
```
</CodeGroup>
## إلى أين تذهب بعد ذلك
<CardGroup cols={2}>
<Card title="واجهة المستخدم التوليدية (Generative UI)" icon="wand-magic-sparkles" href="/edge/en/guides/frontend/generative-ui">
اعرض استدعاءات الأدوات وحالة الوكيل كمكوّنات مخصّصة.
</Card>
<Card title="إجراءات الواجهة الأمامية (Frontend Actions)" icon="bolt" href="/edge/en/guides/frontend/frontend-actions">
دع الوكيل يستدعي دوالًا تعمل في المتصفح.
</Card>
<Card title="التدخل البشري (Human-in-the-Loop)" icon="user-check" href="/edge/en/guides/frontend/human-in-the-loop">
قيّد إجراءات الوكيل خلف موافقة المستخدم.
</Card>
<Card title="الحالة التنبؤية (Predictive State)" icon="gauge-high" href="/edge/en/guides/frontend/predictive-state-updates">
ابثّ الحالة قيد التنفيذ إلى الواجهة أثناء عمل الوكيل.
</Card>
</CardGroup>

View File

@@ -176,7 +176,7 @@ grep -r "llm:" --include="*.yaml" .
# llm = LLM(model="mistral/mistral-large-latest")
# After (Native):
llm = LLM(model="gemini/gemini-2.0-flash")
llm = LLM(model="gemini/gemini-3.7-flash")
```
```bash
@@ -312,7 +312,7 @@ llm = LLM(model="anthropic/claude-haiku-3-5") # Fast & affordable
# Together AI → OpenAI or Gemini
# llm = LLM(model="together_ai/meta-llama/Meta-Llama-3.1-70B")
llm = LLM(model="openai/gpt-4o") # High quality
llm = LLM(model="gemini/gemini-2.0-flash") # Fast & capable
llm = LLM(model="gemini/gemini-3.7-flash") # Fast & capable
# Mistral → Anthropic or OpenAI
# llm = LLM(model="mistral/mistral-large-latest")

View File

@@ -141,7 +141,7 @@ mode: "wide"
# Example using Gemini's OpenAI-compatible API.
os.environ["OPENAI_API_KEY"] = "your-gemini-key" # Should start with AIza...
os.environ["OPENAI_API_BASE"] = "https://generativelanguage.googleapis.com/v1beta/openai/"
os.environ["OPENAI_MODEL_NAME"] = "openai/gemini-2.0-flash" # Add your Gemini model here, under openai/
os.environ["OPENAI_MODEL_NAME"] = "openai/gemini-3.7-flash" # Add your Gemini model here, under openai/
```
</CodeGroup>
</Tab>
@@ -159,7 +159,7 @@ mode: "wide"
```python Google
# Example using Gemini's OpenAI-compatible API
llm = LLM(
model="openai/gemini-2.0-flash",
model="openai/gemini-3.7-flash",
base_url="https://generativelanguage.googleapis.com/v1beta/openai/",
api_key="your-gemini-key", # Should start with AIza...
)

View File

@@ -144,7 +144,7 @@ Planning agents benefit from reasoning models that can handle complex strategic
from crewai import Agent, Task, Crew, LLM
# High-capability reasoning model for strategic planning
manager_llm = LLM(model="gemini-2.5-flash-preview-05-20", temperature=0.1)
manager_llm = LLM(model="gemini/gemini-3.7-flash", temperature=0.1)
# Creative model for content generation
content_llm = LLM(model="claude-3-5-sonnet-20241022", temperature=0.7)
@@ -409,7 +409,7 @@ Rather than repeating the strategic framework, here's a tactical checklist for i
# Manager or coordination agents
manager_agent = Agent(
role="Project Manager",
llm=LLM(model="gemini-2.5-flash-preview-05-20"), # Premium for coordination
llm=LLM(model="gemini/gemini-3.7-flash"), # Premium for coordination
# ... rest of config
)

View File

@@ -9,7 +9,7 @@ mode: "wide"
يوفر CrewAI إمكانيات تتبع مدمجة تتيح لك مراقبة وتصحيح أخطاء الطواقم والتدفقات في الوقت الفعلي. يوضح هذا الدليل كيفية تفعيل التتبع لكل من **الطواقم** و**التدفقات** باستخدام منصة المراقبة المتكاملة في CrewAI.
> **ما هو تتبع CrewAI؟** يوفر التتبع المدمج في CrewAI مراقبة شاملة لوكلاء الذكاء الاصطناعي، بما في ذلك قرارات الوكلاء وجداول تنفيذ المهام واستخدام الأدوات واستدعاءات LLM - كل ذلك متاح عبر [منصة CrewAI AMP](https://app.crewai.com).
> **ما هو تتبع CrewAI؟** يوفر التتبع المدمج في CrewAI مراقبة شاملة لوكلاء الذكاء الاصطناعي، بما في ذلك قرارات الوكلاء وجداول تنفيذ المهام واستخدام الأدوات واستدعاءات LLM - كل ذلك متاح عبر [منصة CrewAI AMP](https://app.crewai.com). يتم إدارة التتبع بشكل مستقل عن [القياس عن بُعد](/ar/telemetry).
![واجهة تتبع CrewAI](/images/crewai-tracing.png)
@@ -150,8 +150,8 @@ result = flow.kickoff()
### الخطوة 5: عرض التتبعات في لوحة تحكم CrewAI AMP
بعد تشغيل الطاقم أو التدفق، يمكنك عرض التتبعات التي أنشأها تطبيق CrewAI في لوحة تحكم CrewAI AMP. يجب أن ترى خطوات تفصيلية لتفاعلات الوكلاء واستخدامات الأدوات واستدعاءات LLM.
ما عليك سوى النقر على الرابط أدناه لعرض التتبعات أو التوجه إلى علامة تبويب التتبعات في لوحة التحكم [هنا](https://app.crewai.com/crewai_plus/trace_batches)
لا تُرفع التتبعات إلا بعد نجاح التصدير باستخدام المصادقة أو الرفع المجهول الذي وافقت عليه صراحةً. لا يوجد تتبع مرفوع لأي تشغيل حُذف مخزنه المؤقت المحلي.
للتتبعات المرتبطة بحسابك، افتح [علامة تبويب التتبعات في لوحة تحكم CrewAI AMP](https://app.crewai.com/crewai_plus/trace_batches) لعرض تفاعلات الوكلاء واستخدام الأدوات واستدعاءات LLM.
![واجهة تتبع CrewAI](/images/view-traces.png)
### البديل: إعداد متغير البيئة
@@ -170,6 +170,49 @@ CREWAI_TRACING_ENABLED=true
عند تعيين متغير البيئة هذا، ستُفعّل جميع الطواقم والتدفقات التتبع تلقائياً، حتى بدون تعيين `tracing=True` صراحةً.
## عرض التتبعات بعد أول تشغيل
في المرة الأولى التي تشغّل فيها طاقماً أو تدفقاً، قد يسألك طرف تفاعلي:
```text
Share this execution trace with CrewAI? [y/N]
```
اختر **yes** لرفع التتبع المخزّن مؤقتاً إلى CrewAI. قد تحتوي التتبعات على
المطالبات والمدخلات والمخرجات. يُحذف المخزن المؤقت عند الرفض أو انتهاء المهلة
أو التشغيل دون مطالبة تفاعلية بالموافقة. يمكنك تغيير إعداد التتبع لاحقاً باستخدام
`crewai traces enable` أو `crewai traces disable`، أو بتعيين `tracing`
على الطاقم أو التدفق.
### التخزين المؤقت المحلي والتصدير بعد المصادقة
يبقى جمع التتبعات في أول تشغيل داخل ذاكرة العملية إلى أن توافق على المشاركة،
حتى إذا كانت لديك بيانات تسجيل دخول محفوظة. يستخدم التتبع دون مصادقة مسار
الموافقة نفسه. قبل الموافقة، لا يطلب CrewAI تصريح رفع ولا يرسل أي مقاطع تنفيذ.
يحتفظ المخزن المؤقت بحد أقصى **1,000 مقطع** و**8 MiB من بيانات OTLP المرمّزة**.
اضبط `CREWAI_EPHEMERAL_TRACE_MAX_SPANS` و
`CREWAI_EPHEMERAL_TRACE_MAX_BYTES` على أعداد صحيحة موجبة لتعديل هذين الحدّين.
عند تجاوز السعة، تُحذف أقدم المقاطع؛ ويُحذف أي مقطع يتجاوز وحده حد البايتات.
يُفرّغ المخزن المؤقت بعد مشاركته أو تجاهله.
عند تفعيل التتبع وتوفّر بيانات الاعتماد، يستبدل CrewAI بيانات تسجيل دخول CLI
أو `CREWAI_USER_PAT` أو بيانات اعتماد تكامل المنصة لدى AMP بتصريح خاص
بالتنفيذ. ثم يصدّر مقاطع OpenTelemetry مباشرةً إلى Wharf باستخدام ذلك التصريح.
لا تؤدي بيانات الاعتماد غير الصالحة إلى الرجوع إلى الرفع المجهول.
### جلسات التنفيذ المستضافة
يمكن للبيئات المضيفة إحاطة التنفيذ بـ `telemetry_session` من
`crewai.telemetry.tracing`. تستخدم الجلسة أحداث دورة حياة CrewAI لإنشاء
المقاطع وإنهائها، مع الحفاظ على طوابعها الزمنية وعلاقاتها بالمقاطع الأصل وروابط
الإيقاف والاستئناف في HITL. مرّر موفّراً موجوداً عبر `providers=` للاحتفاظ
بمتتبّع البيئة المضيفة وتكامل التسجيل لديها. مرّر معالجات المقاطع عبر
`processors=` ودالة تسجيل للمضيف عبر `log_emitter=`. يتولى المضيف أي تنقيح
للبيانات في هذه التكاملات.
تدير كل جلسة دورة حياة التتبع الخاصة بها وتترك موفّر OpenTelemetry العام
للتطبيق دون تغيير.
## عرض التتبعات
### الوصول إلى لوحة تحكم CrewAI AMP
@@ -210,5 +253,5 @@ CREWAI_TRACING_ENABLED=true
1. تأكد من تعيين `tracing=True` في الطاقم/التدفق
2. تحقق من `CREWAI_TRACING_ENABLED=true` إذا كنت تستخدم متغيرات البيئة
3. تأكد من المصادقة عبر `crewai login`
4. تحقق من أن الطاقم/التدفق قيد التنفيذ فعلاً
3. للتصدير باستخدام المصادقة، تحقّق من تسجيل دخول CLI أو `CREWAI_USER_PAT` أو بيانات اعتماد تكامل المنصة. للمشاركة المجهولة، وافق صراحةً على مطالبة الموافقة؛ لا يلزم تسجيل الدخول
4. تحقّق من تنفيذ الطاقم/التدفق ونجاح تصدير التتبع. يؤدي رفض الموافقة أو انتهاء المهلة أو التشغيل دون مطالبة تفاعلية بالموافقة إلى حذف المخزن المؤقت المحلي دون رفعه

View File

@@ -23,7 +23,8 @@ mode: "wide"
عند تفعيل ميزة `share_crew`، يتم جمع بيانات تفصيلية تشمل أوصاف المهام وخلفيات وأهداف الوكلاء وسمات محددة أخرى
لتوفير رؤى أعمق. قد يتضمن جمع البيانات الموسع هذا معلومات شخصية إذا دمجها المستخدمون في طواقمهم أو مهامهم.
يجب على المستخدمين النظر بعناية في محتوى طواقمهم ومهامهم قبل تفعيل `share_crew`.
يمكن للمستخدمين تعطيل القياس عن بُعد عبر تعيين متغير البيئة `CREWAI_DISABLE_TELEMETRY` إلى `true` أو تعيين `OTEL_SDK_DISABLED` إلى `true` (لاحظ أن الأخير يعطل جميع أدوات OpenTelemetry عالمياً).
يمكن للمستخدمين تعطيل القياس عن بُعد في CrewAI عبر تعيين `CREWAI_DISABLE_TELEMETRY` إلى `true` أو `1` أو `yes` أو `on` (بغض النظر عن حالة الأحرف). `OTEL_SDK_DISABLED` بنفس القيم يعطّل أيضاً مُصدِّر CrewAI. مجموعة أدوات OpenTelemetry نفسها ما تزال تقبل `true` فقط لتعطيل بقية أدوات القياس في العملية.
تتبع AMP مشمول بشكل منفصل في [التتبع](/ar/observability/tracing).
### أمثلة:
```python
@@ -34,6 +35,8 @@ os.environ['CREWAI_DISABLE_TELEMETRY'] = 'true'
os.environ['OTEL_SDK_DISABLED'] = 'true'
```
`CREWAI_DISABLE_TELEMETRY=1` (أو `yes` / `on`) يعمل بنفس طريقة `true`. تُتجاهل القيم غير المعروفة ويبقى القياس عن بُعد مفعّلاً.
### العزل عن إعداد OpenTelemetry الخاص بك
يعمل القياس عن بُعد الخاص بـ CrewAI على `TracerProvider` خاص به ولا يسجل نفسه
@@ -60,8 +63,8 @@ os.environ['OTEL_SDK_DISABLED'] = 'true'
| نعم | بيانات دورة حياة المهمة | تشمل: أوقات الإنشاء وبدء/انتهاء التنفيذ، معرّفات الطاقم والمهمة، وما إذا نجحت المهمة أو فشلت. وعند فشل المهمة، يُسجَّل **اسم صنف** الاستثناء (مثل `TimeoutError`) بحيث يمكن عدّ حالات الفشل وتشخيصها — وليس رسالة الخطأ أبدًا، فهي قد تحتوي على مطالبات أو مخرجات نموذج أو مسارات ملفات أو بيانات اعتماد. مخزنة كنطاقات مع طوابع زمنية. لا بيانات شخصية. |
| نعم | سمات LLM | تشمل: الاسم، model_name، model، top_k، temperature، واسم فئة LLM. كلها بيانات تقنية غير شخصية. |
| نعم | إنشاء مشروع باستخدام CLI الخاص بـ CrewAI | تشمل: أن مشروعًا جديدًا أُنشئ عبر `crewai create`، ونوعه (`crew` أو `json_crew` أو `flow`)، ومعرّف المشروع الذي تم توليده لهذا المشروع الجديد وكُتب في ملف `pyproject.toml` الخاص به. وهو معرّف المشروع الجديد نفسه، ويُسجَّل بشكل منفصل عن `project_id` الخاص بالمجلد الذي شُغّل منه الأمر — وقد يختلفان. لا اسم مشروع، ولا محتويات ملفات، ولا شيفرة. لا بيانات شخصية. |
| نعم | محاولة نشر الطاقم باستخدام CLI الخاص بـ CrewAI | تشمل: حقيقة إجراء النشر ومعرّف الطاقم، وما إذا كان يحاول سحب السجلات، وما إذا بدأ النشر من أمر CLI أو من واجهة التشغيل TUI. لا تُسجَّل محتويات المشروع أو الطاقم. لا توجد بيانات شخصية. |
| نعم | بيئة التنفيذ | تشمل: مساعد البرمجة بالذكاء الاصطناعي الذي يشغّل العملية إن وُجد (واحد من قائمة ثابتة مثل `claude_code` أو `codex` أو `cursor` أو `unknown`)، ومكان تشغيل العملية (واحد من قائمة ثابتة مثل `ci` أو `container` أو `serverless` أو `interactive`)، و`project_id` من ملف `pyproject.toml` عند ضبطه. يتحقق الاكتشاف فقط مما إذا كانت متغيرات البيئة المعروفة مضبوطة، ولا يقرأ قيمها أبدًا. لا بيانات شخصية. |
| نعم | محاولة نشر الطاقم باستخدام CLI الخاص بـ CrewAI | تشمل: حقيقة إجراء النشر ومعرّف الطاقم، وما إذا كان يحاول سحب السجلات، وما إذا بدأ النشر من أمر CLI أو من واجهة التشغيل TUI. إذا فشل إنشاء النشر، تُسجَّل فئة الفشل (واحدة من قائمة ثابتة مثل `api_4xx` أو `network_error` أو `user_declined`) ورمز حالة HTTP لاستجابة API إن وُجدت — ولا تُسجَّل رسالة الخطأ أبدًا. لا تُسجَّل محتويات المشروع أو الطاقم. لا توجد بيانات شخصية. |
| نعم | بيئة التنفيذ | تشمل: مساعد البرمجة بالذكاء الاصطناعي الذي يشغّل العملية إن وُجد (واحد من قائمة ثابتة مثل `claude_code` أو `codex` أو `cursor` أو `unknown`)، ومكان تشغيل العملية (واحد من قائمة ثابتة مثل `ci` أو `container` أو `serverless` أو `interactive`)، و`project_id` من ملف `pyproject.toml` عند ضبطه، ونطاقًا تقريبيًا لحجم الجهاز (واحد من `1-2` أو `3-4` أو `5-8` أو `9-16` أو `17-32` أو `33+` أو `unknown`). النطاق مجال وليس العدد الدقيق للأنوية أبدًا — العدد الدقيق اختياري فقط، ضمن «معلومات البيئة» أدناه. تأتي فئة الحجم من عدد أنوية المضيف؛ ويتحقق اكتشاف المساعد وموقع التشغيل فقط مما إذا كانت متغيرات البيئة المعروفة مضبوطة، ولا يقرأ قيمها أبدًا. لا بيانات شخصية. |
| نعم | إشارات دورة حياة التدفق | تشمل: بدء التدفق، وما إذا اكتمل أو فشل، وما إذا فشلت إحدى طرقه، وما إذا توقف مؤقتًا لانتظار إدخال أو ملاحظات بشرية، وما إذا كان البدء تشغيلًا مستأنفًا، وما إذا فشل دور محادثة، ومدة تشغيل التدفق، وما إذا كان التدفق مما تشغّله CrewAI داخليًا أو مما كتبته أنت. ويُسجَّل اسم التدفق، كما هو الحال بالفعل لإنشاء التدفق وتنفيذه. وعند فشل تدفق أو إحدى طرقه، يُسجَّل **اسم فئة** الاستثناء (مثل `TimeoutError`) لتشخيص الأعطال — ولا تُسجَّل أبدًا رسالة الخطأ، التي قد تحتوي على مطالبات أو مخرجات النموذج أو مسارات ملفات أو بيانات اعتماد. ولا تُسجَّل أبدًا أسماء الطرق أو حالة التدفق. لا توجد بيانات شخصية. |
| نعم | إشارة مشاركة التتبع | تشمل: نجاح مشاركة دفعة من عمليات التتبع مع CrewAI AMP، وما إذا تمت المشاركة بشكل مجهول (قبل إنشاء حساب) أو مرتبطة بحسابك. ومثل كل span، تحمل أيضًا سمات بيئة التنفيذ الموضحة أعلاه (`project_id` عند تكوينه، ومساعد البرمجة، وبيئة التشغيل). يصف هذا الصف بيانات القياس عن بُعد الخاصة بالمشاركة فقط — وليس محتويات التتبع أو الوصول الذي تمنحه روابط التتبع المشتركة. لا تُسجَّل محتويات التتبع أو المدخلات أو المخرجات في هذه الإشارة. قبل مشاركة التتبعات، راجع الأسرار والبيانات الشخصية وإعدادات التنقيح والاحتفاظ في AMP. |
| لا | بيانات الوكيل الموسّعة | تشمل: وصف الهدف، نص الخلفية، معرّف ملف موجهات i18n. يجب على المستخدمين التأكد من عدم تضمين معلومات شخصية في حقول النص. |

View File

@@ -50,16 +50,15 @@ mode: "wide"
- **سلامة الذكاء الاصطناعي**: تنفيذ فحوصات الإشراف على المحتوى والسلامة
```python
from crewai_tools import DallETool, VisionTool, CodeInterpreterTool
from crewai_tools import DallETool, VisionTool
# Create AI tools
image_generator = DallETool()
vision_processor = VisionTool()
code_executor = CodeInterpreterTool()
# Add to your agent
agent = Agent(
role="AI Specialist",
tools=[image_generator, vision_processor, code_executor],
tools=[image_generator, vision_processor],
goal="Create and analyze content using AI capabilities"
)

View File

@@ -460,7 +460,7 @@ rag_tool = RagTool(config=config, summarize=True)
**خيارات الإعداد:**
- `model_name` (str): معرّف نموذج HuggingFace. القيمة الافتراضية: `hkunlp/instructor-base`. الخيارات: `hkunlp/instructor-xl`، `hkunlp/instructor-large`، `hkunlp/instructor-base`
- `device` (str): الجهاز للتشغيل. القيمة الافتراضية: `cpu`. الخيارات: `cpu`، `cuda`، `mps`
- `device` (str): الجهاز للتشغيل. القيمة الافتراضية: `cpu`. الخيارات: `cpu`، `cuda`، `mps`، `xpu`
- `instruction` (str): بادئة التعليمات للتضمينات
**متغيرات البيئة:**
@@ -485,7 +485,7 @@ rag_tool = RagTool(config=config, summarize=True)
**خيارات الإعداد:**
- `model_name` (str): اسم نموذج Sentence Transformers. القيمة الافتراضية: `all-MiniLM-L6-v2`. الخيارات: `all-mpnet-base-v2`، `all-MiniLM-L6-v2`، `paraphrase-multilingual-MiniLM-L12-v2`
- `device` (str): الجهاز للتشغيل. القيمة الافتراضية: `cpu`. الخيارات: `cpu`، `cuda`، `mps`
- `device` (str): الجهاز للتشغيل. القيمة الافتراضية: `cpu`. الخيارات: `cpu`، `cuda`، `mps`، `xpu`
- `normalize_embeddings` (bool): ما إذا كان يتم تطبيع التضمينات. القيمة الافتراضية: `False`
**متغيرات البيئة:**

View File

@@ -12,6 +12,16 @@ mode: "wide"
تُستخدم هذه الأداة لاستخراج النص من الصور. عند تمريرها إلى الوكيل، ستستخرج النص من الصورة ثم تستخدمه لتوليد استجابة أو تقرير أو أي مخرج آخر.
يجب تمرير عنوان URL أو مسار الصورة إلى الوكيل.
يمكنك أيضًا طرح استعلام `query` مخصص حول الصورة واختيار مستوى تعقيد `complexity_level` يقوم تلقائيًا باختيار النموذج الأنسب للطلب:
| مستوى التعقيد | النموذج |
| :--------------- | :------------ |
| `easy` | `gpt-5.6-luna` |
| `medium` (افتراضي) | `gpt-5.6-terra` |
| `hard` | `gpt-5.6-sol` |
عند تمرير `llm` أو `model` بشكل صريح إلى الأداة، فإنه يأخذ الأولوية على اختيار النموذج المستند إلى مستوى التعقيد.
## التثبيت
ثبّت حزمة crewai_tools
@@ -43,8 +53,10 @@ def researcher(self) -> Agent:
## المعاملات
تتطلب VisionTool المعاملات التالية:
تقبل VisionTool المعاملات التالية:
| المعامل | النوع | الوصف |
| :----------------- | :------- | :------------------------------------------------------------------------------- |
| **image_path_url** | `string` | **إلزامي**. مسار ملف الصورة المراد استخراج النص منها. |
| **image_path_url** | `string` | **إلزامي**. مسار ملف الصورة (أو عنوان URL) المراد استخراج النص منها. |
| **query** | `string` | **اختياري**. السؤال أو التعليمات المراد طرحها على النموذج حول الصورة. القيمة الافتراضية هي `"What's in this image?"`. |
| **complexity_level** | `string` | **اختياري**. مستوى تعقيد الطلب، والذي يحدد النموذج: `easy` أو `medium` أو `hard`. القيمة الافتراضية هي `medium`. |

View File

@@ -4,7 +4,7 @@ description: >
تتيح أدوات استخراج Oxylabs الوصول بسهولة إلى المعلومات من المصادر المعنية. يرجى الاطلاع على قائمة المصادر المتاحة أدناه:
- `Amazon Product`
- `Amazon Search`
- `Google Seach`
- `Google Search`
- `Universal`
icon: globe
mode: "wide"
@@ -87,7 +87,7 @@ print(result)
### المعاملات
- `query` - مصطلح بحث Amazon.
- `domain` - توطين النطاق لـ Bestbuy.
- `domain` - توطين النطاق لـ Amazon.
- `start_page` - رقم صفحة البداية.
- `pages` - عدد الصفحات المراد استرجاعها.
- `geo_location` - موقع _التوصيل إلى_.

View File

@@ -4,6 +4,145 @@ description: "Product updates, improvements, and bug fixes for CrewAI"
icon: "clock"
mode: "wide"
---
<Update label="Sep 16, 2026">
## v1.15.22
[View release on GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.15.22)
## What's Changed
### Features
- Support aliases as connection identifiers
- Record reasons for deployment creation failures
- Collect human feedback and pause events in tracing
- Add `llm_overlay` context variable to route agent roles to models
- Carry `task_prompt` and output in agent execution payloads
- Validate platform integrations during crew setup
- Add platform tools to JSON crew wizard
- Expose CrewAI Platform application catalog
- Add OpenRouter as a supported embedding provider
### Bug Fixes
- Accept CRLF in inline skill definitions
- Load text file URLs through the safe fetcher
- Close SQLite connections in kickoff task outputs storage
- Carry `from_cache` on the native tool path's `ToolUsageFinishedEvent`
- Raise `ValueError` instead of bare raise in uploader
- Support non-primitive types in SQLiteFlowPersistence
- Improve coding agents instructions
- Read JSON checkpoints as UTF-8
- Overwrite stale `poetry.lock` backup on Windows
- Key streamed tool calls by wire index in Azure
- Preserve file data content parts in Gemini
- Honor `read_only` on `update()` and `recall()` access times
- Send `reasoning_effort` to every OpenAI reasoning model
- Prevent crashes in the run TUI when streamed output contains a literal `[...]`
- Reject replay when stored tasks differ
- Use `sys.platform` guards for mypy compatibility on Windows
- Request the forced final answer as a user turn
- Keep null in the task output schema embedded in the prompt
- Align `DOCXSearchTool` with standard RAG fixed schema pattern
### Documentation
- Add `xpu` to embedding device options
- List all workspace packages
## Contributors
@ASTion24, @BlueX888, @HUAN2022A, @RaycarlLei, @Rohitkanithi, @SWAPI03, @SharoonSharif, @ShivangiRay, @Theater-ahyeon, @Vidit-Ostwal, @gamal1osama, @github-actions[bot], @joaomdmoura, @lorenzejay, @mhbuehler, @modusensus, @monkscode, @rohitkanithi, @roli-lpci, @vinibrsl, @wangtaotaotao95
</Update>
<Update label="Sep 09, 2026">
## v1.15.21
[View release on GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.15.21)
## What's Changed
### Features
- Add telemetry to track checkpoint runtime and CLI usage.
### Bug Fixes
- Fix gateway errors reported inside an HTTP 200 response.
- Keep deploy push on the AMP create source.
- Report scrape failures instead of raising IndexError in the Oxylabs integration.
- Route all DashScope models through the native provider.
- Persist JSON checkpoints as UTF-8.
- Drop stray $ in f-string search URLs for BrightData.
- Support list-form type arrays in JSON schema conversion.
- Correct gpt-4o-mini context window from 200000 to 128000.
- Preserve streaming tool call arguments at contentBlockStop.
- Make pre-commit hooks portable on Windows.
### Documentation
- Clarify that tracing is managed separately from telemetry.
- Fix parallel search reference link.
- Remove stale parameters from handle_llm_stream_chunk docstring.
- Fix streaming output docstring examples.
- Use organization UUIDs in the skill install reference.
## Contributors
@Alphaxiaoteng, @DrewWhittleNZ, @Ghraven, @Shxiao101, @Vaishnavi220506, @Vidit-Ostwal, @danielfsbarreto, @georgeatparallel, @github-actions[bot], @jessemiller, @joaomdmoura, @kimnamu, @kiwoongyoon, @liang0417, @lorenzejay, @oxy-giedrius, @simpleqt, @uoparaji
</Update>
<Update label="Sep 04, 2026">
## v1.15.20
[View release on GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.15.20)
## What's Changed
### Bug Fixes
- Fix legacy platform tool alias discovery
### Documentation
- Update snapshot and changelog for v1.15.19
## Contributors
@joaomdmoura, @vinibrsl
</Update>
<Update label="Sep 04, 2026">
## v1.15.19
[View release on GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.15.19)
## What's Changed
### Features
- Add Clipper integrations client
- Add `now()` to the CEL expression environment
- Record how a crew run ended for every user
- Report machine size as a coarse band, not a core count
- Add injectable client for CrewAI platform tools
### Bug Fixes
- Fix reading of octet-stream and xlsx URLs in `urlreadtool`
- Fix appending trailing user turn in native Gemini provider
- Normalize scheme and port in Ollama base URL
- Preserve reusable scope configs in memory
- Bump `pypdf` to 6.16.2 for security vulnerability
- Bump `nltk` to 3.10.3 for security vulnerability
- Fix native structured outputs for current Claude models and Snowflake CVE floor
- Run model call hooks on every path and propagate a deny
### Documentation
- Remove `CodeInterpreterTool` from AI/ML overview examples
- Point `prompt-template` link at its current path
- Update channels guide to current CopilotKit channels API
- Refresh retired Gemini model IDs
## Contributors
@Vidit-Ostwal, @a-yeyang, @github-actions[bot], @hvlcrs, @joaomdmoura, @kikifrost, @lorenzejay, @lucasgomide, @parthiban-sivakumar, @ranst91, @tandede, @thiagomoretto, @vinibrsl
</Update>
<Update label="Aug 27, 2026">
## v1.15.18

View File

@@ -338,6 +338,7 @@ crewai org switch <organization_id>
- Initiates the deployment process on the CrewAI AMP platform.
- Upon successful initiation, it will output the Deployment created successfully! message along with the Deployment Name and a unique Deployment ID (UUID).
- Push keeps the source used at create. Adding a git `origin` later does not switch a ZIP deployment to git.
- **Deployment Status**: You can check the status of your deployment with:
@@ -578,6 +579,7 @@ Trace collection is controlled by checking three settings in priority order:
```
- Checked only if `tracing` is not set in code and `CREWAI_TRACING_ENABLED` is not set to `true`
- Running `crewai traces enable` is sufficient to enable tracing by itself
- The first-run prompt (`Would you like to view your execution traces?`) also updates this preference
<Note>
**To enable tracing**, use any one of these methods:

View File

@@ -37,7 +37,7 @@ A crew in crewAI represents a collaborative group of agents working together to
| **Chat LLM** _(optional)_ | `chat_llm` | The language model used to orchestrate `crewai chat` CLI interactions with the crew. Accepts a model name string or `LLM` instance. Defaults to `None`. |
| **Before Kickoff Callbacks** _(optional)_ | `before_kickoff_callbacks` | A list of callable functions executed **before** the crew starts. Each callback receives and can modify the inputs dict. Distinct from the `@before_kickoff` decorator. Defaults to `[]`. |
| **After Kickoff Callbacks** _(optional)_ | `after_kickoff_callbacks` | A list of callable functions executed **after** the crew finishes. Each callback receives and can modify the `CrewOutput`. Distinct from the `@after_kickoff` decorator. Defaults to `[]`. |
| **Tracing** _(optional)_ | `tracing` | Controls OpenTelemetry tracing for the crew. `True` = always enable, `False` = always disable, `None` = inherit from environment / user settings. Defaults to `None`. |
| **Tracing** _(optional)_ | `tracing` | Controls tracing for the crew. `True` = always enable, `False` = always disable, `None` = inherit from environment / user settings. Defaults to `None`. |
| **Skills** _(optional)_ | `skills` | A list of `Path` objects (skill search directories) or pre-loaded `Skill` objects applied to all agents in the crew. Defaults to `None`. |
| **Security Config** _(optional)_ | `security_config` | A `SecurityConfig` instance managing crew fingerprinting and identity. Defaults to `SecurityConfig()`. |
| **Checkpoint** _(optional)_ | `checkpoint` | Enables automatic checkpointing. Pass `True` for sensible defaults, a `CheckpointConfig` for full control, `False` to opt out, or `None` to inherit. See the [Checkpointing](#checkpointing) section below. Defaults to `None`. |

View File

@@ -636,6 +636,21 @@ agent = Agent(
}
}
)
# Option 4: Use OpenRouter embeddings (supports models across providers)
# Set OPENROUTER_API_KEY environment variable if api_key is omitted in config
crew = Crew(
agents=[agent],
tasks=[...],
knowledge_sources=[knowledge_source],
embedder={
"provider": "openrouter",
"config": {
"model_name": "openai/text-embedding-3-small",
"api_key": "your-openrouter-api-key" # Optional if OPENROUTER_API_KEY is set
}
}
)
```
#### Configuring Azure OpenAI Embeddings

View File

@@ -1487,6 +1487,38 @@ llm = LLM(
llm = LLM(model="gpt-4")
```
</Tab>
<Tab title="Gateway Errors">
<Tip>
Gateways such as OpenRouter return `200 OK` as soon as the upstream provider accepts the request, so a provider timeout arrives in the response body instead of the status code.
</Tip>
CrewAI raises the same exception the upstream code would have produced as a real HTTP status, so a masked failure is caught by the retry handling you already have:
```python
import openai
from pydantic import BaseModel
from crewai import LLM
class Report(BaseModel):
summary: str
llm = LLM(model="openrouter/z-ai/glm-5.3", response_format=Report)
try:
result = llm.call("Summarize the incident", response_model=Report)
except openai.InternalServerError as e:
# "z-ai/glm-5.3 via openrouter.ai returned HTTP 200 with an upstream error
# and no choices: The operation was aborted (upstream code 504)"
print(f"Upstream provider failed, safe to retry: {e}")
```
<Warning>
A large or deeply nested `response_model` makes upstream timeouts more likely. Treat these as transient provider failures, not as the model producing malformed structured output.
</Warning>
</Tab>
<Tab title="Context Length">
<Tip>
Use larger context models for extensive tasks

View File

@@ -740,7 +740,7 @@ memory = Memory(llm="anthropic/claude-3-haiku-20240307")
memory = Memory(llm="ollama/llama3.2")
# Use Google Gemini
memory = Memory(llm="gemini/gemini-2.0-flash")
memory = Memory(llm="gemini/gemini-3.7-flash")
# Pass a pre-configured LLM instance with custom settings
llm = LLM(model="gpt-4o", temperature=0)

View File

@@ -210,13 +210,17 @@ Publishing reads `name`, `description`, and `metadata.version` from the `SKILL.m
### Install
Install a published skill by its `@org/name` reference:
Install a published skill by its `@org-uuid/name` reference:
```shell Terminal
crewai skill install @acme/code-review
crewai skill install @your-org-uuid/code-review
```
Inside a crew project the skill lands in `./skills/{name}/`; outside a project it goes to the shared cache at `~/.crewai/skills/{org}/{name}/`.
<Note>
Use your organization's **UUID**, not its name — organization names are not unique, so a name can resolve to the wrong organization and the install fails with a "not found" error. Run `crewai org list` to see the UUID (the `ID` column) of every organization you belong to.
</Note>
Inside a crew project the skill lands in `./skills/{name}/`; outside a project it goes to the shared cache at `~/.crewai/skills/{org-uuid}/{name}/`.
Agents can also reference registry skills directly — they resolve from the local cache (or project `skills/` directory) at runtime:
@@ -225,7 +229,7 @@ agent = Agent(
role="Senior Code Reviewer",
goal="Review pull requests for quality and security issues",
backstory="Staff engineer with expertise in secure coding practices.",
skills=["@acme/code-review"], # registry ref, resolved locally
skills=["@your-org-uuid/code-review"], # registry ref, resolved locally
)
```
@@ -240,7 +244,7 @@ agent = Agent(
role="Senior Code Reviewer",
goal="Review pull requests for quality and security issues",
backstory="Staff engineer with expertise in secure coding practices.",
skills=["@acme/code-review@1.2.0"], # pinned; a leading "v" also works
skills=["@your-org-uuid/code-review@1.2.0"], # pinned; a leading "v" also works
)
```

View File

@@ -26,7 +26,7 @@ Under the hood, CrewAI employs a modular prompt system that you can customize ex
- **Error handling** – Direct how agents respond to failures, exceptions, or timeouts.
- **Tool-specific prompts** – Define detailed instructions for how tools are invoked or utilized.
Check out the [original prompt templates in CrewAI's repository](https://github.com/crewAIInc/crewAI/blob/main/src/crewai/translations/en.json) to see how these elements are organized. From there, you can override or adapt them as needed to unlock advanced behaviors.
Check out the [original prompt templates in CrewAI's repository](https://github.com/crewAIInc/crewAI/blob/main/lib/crewai/src/crewai/translations/en.json) to see how these elements are organized. From there, you can override or adapt them as needed to unlock advanced behaviors.
## Understanding Default System Instructions

View File

@@ -11,7 +11,7 @@ mode: "wide"
## Create a Project with the CLI
Use the CrewAI CLI to scaffold a project, then `AGENTS.md` will be automatically added at the root.
Use the CrewAI CLI to scaffold a project. `AGENTS.md` is added at the root, together with a `CLAUDE.md` and a `GEMINI.md` that import it, so Claude Code and Gemini CLI read the same guidance as every other assistant.
```bash
# Crew
@@ -36,24 +36,28 @@ Codex can be guided by `AGENTS.md` files placed in your repository. Use them to
### Claude Code
Claude Code stores project memory in `CLAUDE.md`. You can bootstrap it with `/init` and edit it using `/memory`. Claude Code also supports imports inside `CLAUDE.md`, so you can add a single line like `@AGENTS.md` to pull in the shared instructions without duplicating them.
Claude Code reads `CLAUDE.md` and ignores `AGENTS.md`. Scaffolded projects ship a `CLAUDE.md` whose only instruction is the import line `@AGENTS.md`, so the shared guidance is loaded without duplicating it. Add Claude-specific notes under that line and keep shared conventions in `AGENTS.md`.
You can simply use:
For a project created before `CLAUDE.md` was scaffolded, add the import yourself:
```bash
mv AGENTS.md CLAUDE.md
printf '@AGENTS.md\n' > CLAUDE.md
```
Do not rename `AGENTS.md` to `CLAUDE.md`: Codex and Cursor read `AGENTS.md`, and the rename hides it from them.
### Gemini CLI and Google Antigravity
Gemini CLI and Antigravity load a project context file (default: `GEMINI.md`) from the repo root and parent directories. You can configure it to read `AGENTS.md` instead (or in addition) by setting `context.fileName` in your Gemini CLI settings. For example, set it to `AGENTS.md` only, or include both `AGENTS.md` and `GEMINI.md` if you want to keep each tool’s format.
Gemini CLI and Antigravity load a project context file (default: `GEMINI.md`) from the repo root and parent directories. Scaffolded projects ship a `GEMINI.md` whose only instruction is the import line `@./AGENTS.md`, so the shared guidance is loaded without duplicating it. Add Gemini-specific notes under that line and keep shared conventions in `AGENTS.md`.
You can simply use:
For a project created before `GEMINI.md` was scaffolded, add the import yourself:
```bash
mv AGENTS.md GEMINI.md
printf '@./AGENTS.md\n' > GEMINI.md
```
Alternatively, set `context.fileName` in your Gemini CLI settings to include `AGENTS.md` and Gemini reads it directly. Do not rename `AGENTS.md` to `GEMINI.md`: Codex and Cursor read `AGENTS.md`, and the rename hides it from them.
### Cursor
Cursor supports `AGENTS.md` as a project instruction file. Place it at the project root to provide guidance for Cursor’s coding assistant.

View File

@@ -77,7 +77,7 @@ Replace the generated `agents/researcher.jsonc` file and add `agents/analyst.jso
}
```
Replace `provider/model-id` with the model you use, for example `openai/gpt-4o`, `anthropic/claude-sonnet-4-6`, or `gemini/gemini-2.0-flash-001`.
Replace `provider/model-id` with the model you use, for example `openai/gpt-4o`, `anthropic/claude-sonnet-4-6`, or `gemini/gemini-3.7-flash`.
## Step 3: Define Tasks and Crew Settings

View File

@@ -136,7 +136,7 @@ Now, let's configure the content writer crew with JSONC. We'll set up two specia
}
```
Replace `provider/model-id` with the model you use, for example `openai/gpt-4o`, `gemini/gemini-2.0-flash-001`, or `anthropic/claude-sonnet-4-6`.
Replace `provider/model-id` with the model you use, for example `openai/gpt-4o`, `gemini/gemini-3.7-flash`, or `anthropic/claude-sonnet-4-6`.
3. Create `src/guide_creator_flow/crews/content_crew/crew.jsonc`:
@@ -483,7 +483,7 @@ Flows allow you to make direct calls to language models when you need simple, st
```python
llm = LLM(
model="model-id-here", # gpt-4o, gemini-2.0-flash, anthropic/claude...
model="model-id-here", # gpt-4o, gemini/gemini-3.7-flash, anthropic/claude...
response_format=GuideOutline
)
response = llm.call(messages=messages)

View File

@@ -1,117 +1,148 @@
---
title: Channels
description: Run the same CrewAI agent as a chat bot on Slack and Discord with the CopilotKit Channels SDK.
icon: slack
description: Run the same CrewAI agent as a Slack or Teams bot with the CopilotKit Channels SDK and managed Intelligence platform.
icon: messages
mode: "wide"
---
## Meet your users where they already are
The CrewAI agent you built in the [Overview](/edge/en/guides/frontend/overview) does not have to live behind a web app. The same Crew or Flow can run as a bot inside a messaging platform. No rebuild, no second copy of your agent logic: the agent stays exposed over the [AG-UI protocol](https://docs.ag-ui.com), and a bot process drives it.
The CrewAI agent you built in the [Overview](/edge/en/guides/frontend/overview) does not have to live behind a web app. The same Crew or Flow can run as a bot inside a messaging platform. No rebuild, no second copy of your agent logic: the agent stays exposed over the [AG-UI protocol](https://docs.ag-ui.com), and a **channel** drives it from Slack or Microsoft Teams.
CopilotKit's [Channels SDK](https://docs.copilotkit.ai/reference/channels) provides that bot process. It ships a platform-agnostic engine plus per-platform adapters.
CopilotKit's [Channels SDK](https://docs.copilotkit.ai/slack) provides that channel. You declare a `createChannel` in a small runtime, point it at your CrewAI agent, and CopilotKit's managed **Intelligence** platform brokers the connection to the messaging provider.
<Note>
Unlike the rest of this section, Channels is **not self-hosted**. It runs through **CopilotKit Intelligence** — a required surface for Channels, by design (a free tier is available). Intelligence holds the platform connection and credentials, receives each platform event, and delivers the turn to your channel process; your process runs the agent and streams the reply back. You configure Slack once in the Intelligence dashboard, and platform credentials never enter your process. Your agent, tools, and state stay yours.
</Note>
## How it fits together
Nothing about your agent server changes. It keeps serving your Crew or Flow over AG-UI exactly as in the Overview. What you add is a separate **bot process**: it connects to a platform adapter, listens for messages, and runs your agent when it is messaged. The reply streams back into the channel.
Nothing about your CrewAI agent server changes. It keeps serving your Crew or Flow over AG-UI exactly as in the Overview. What you add is a separate long-running Node process built with `@copilotkit/channels`: it registers a channel on the `CopilotRuntime`, connects to Intelligence, and runs your agent whenever a message arrives.
```
Slack / Discord ──► Channels bot process ──► CrewAI server (AG-UI) ──► Crew / Flow
Slack / Teams ──► CopilotKit Intelligence ──► channel process (Node) ──► CrewAI server (AG-UI) ──► Crew / Flow
```
Your agent server can keep serving the web frontend from the Overview at the same time. The web app and the bot are just two clients of one AG-UI endpoint.
The channel process holds a persistent connection to the Intelligence gateway, so it needs a long-running host — a serverless request handler cannot own that connection. Your CrewAI server can keep serving the web frontend from the Overview at the same time: the web app and the channel are just two clients of one AG-UI endpoint.
## Slack
## Integration guide
<Steps>
<Step title="Install the Channels packages">
The Channels SDK is batteries-included — every platform ships in the one package, with no per-platform adapter to install. Add it alongside the runtime that hosts the channel and the CrewAI AG-UI client:
```bash
npm install @copilotkit/channels @copilotkit/channels-slack @ag-ui/crewai
npm install @copilotkit/channels @copilotkit/runtime @ag-ui/crewai
```
</Step>
<Step title="Create a Slack app and get tokens">
<Step title="Create a Channel in Intelligence">
Create an app in the Slack API dashboard for your workspace, enable Socket Mode, and grant it the message and event scopes it needs to read and post in channels. Then expose its tokens to the bot process:
In the [CopilotKit dashboard](https://docs.copilotkit.ai/slack), create a Channel and connect Slack — Intelligence walks you through creating the Slack app and holds its credentials. That leaves two environment variables for your process, both from the dashboard:
```bash
export SLACK_BOT_TOKEN=xoxb-... # bot user token
export SLACK_APP_TOKEN=xapp-... # app-level token (Socket Mode)
export INTELLIGENCE_API_KEY=... # authenticates the runtime with Intelligence (free tier available)
export INTELLIGENCE_CHANNEL_ID=... # the Channel ID, matched by createChannel({ name })
```
</Step>
<Step title="Point the bot at your CrewAI agent">
<Step title="Define the channel">
`createBot` wires a Slack adapter to your agent. The `agent` factory returns a `CrewAIAgent` pointed at the AG-UI path your server exposes (the same URL you registered in the runtime in the Overview).
`createChannel` declares the channel and attaches your agent. Build the agent as a per-thread factory so each conversation gets its own session, using the same `CrewAIAgent` the Overview uses in the web runtime, pointed at your AG-UI endpoint. `identifyUser: "platform"` lets Intelligence map each platform user to a stable identity.
```ts
// bot.ts
import { createBot } from "@copilotkit/channels";
import { slack, defaultSlackTools, defaultSlackContext } from "@copilotkit/channels-slack";
// channel.ts
import { createChannel } from "@copilotkit/channels";
import { CrewAIAgent } from "@ag-ui/crewai";
const bot = createBot({
adapters: [
slack({
botToken: process.env.SLACK_BOT_TOKEN!, // xoxb-…
appToken: process.env.SLACK_APP_TOKEN!, // xapp-… (Socket Mode)
}),
],
agent: (threadId) => new CrewAIAgent({ url: "http://localhost:8000/recipe" }),
tools: [...defaultSlackTools],
context: [...defaultSlackContext],
const channel = createChannel({
name: process.env.INTELLIGENCE_CHANNEL_ID!, // must match the Channel ID in Intelligence
identifyUser: "platform",
// A fresh agent per conversation, pointed at your CrewAI AG-UI endpoint.
agent: (threadId) => {
const agent = new CrewAIAgent({ url: "http://localhost:8000/recipe" });
agent.threadId = threadId;
return agent;
},
});
bot.start();
// A mention subscribes the thread and runs the agent; afterwards every message
// in a subscribed thread runs it without needing another mention.
channel.onMention(async ({ thread }) => {
await thread.subscribe();
await thread.runAgent();
});
channel.onMessage(async ({ thread }) => {
if (await thread.isSubscribed()) await thread.runAgent();
});
export { channel };
```
</Step>
<Step title="Run the bot">
<Step title="Register the channel on the runtime">
Start the bot process alongside your agent server:
Create a `CopilotRuntime` with the Intelligence gateway and your channel, then serve it with `createCopilotNodeListener`. The `agents` map stays empty — the channel supplies its own agent. Wait for the channel to be ready so a broken config fails startup loudly.
```ts
// server.ts
import { createServer } from "node:http";
import { CopilotRuntime, CopilotKitIntelligence } from "@copilotkit/runtime/v2";
import { createCopilotNodeListener } from "@copilotkit/runtime/v2/node";
import { channel } from "./channel";
const runtime = new CopilotRuntime({
agents: {}, // the channel supplies its own agent; no web-facing agents needed
intelligence: new CopilotKitIntelligence({
apiKey: process.env.INTELLIGENCE_API_KEY!, // free tier available
}),
channels: [channel],
});
const listener = createCopilotNodeListener({ runtime });
await listener.channels?.ready({ timeoutMs: 15_000 });
createServer(listener).listen(3123, () => {
console.log("Channels runtime listening on port 3123");
});
```
</Step>
<Step title="Run the channel runtime">
Start it alongside your CrewAI agent server:
```bash
uvicorn server:app --port 8000 # terminal 1 — CrewAI agent server
node bot.ts # terminal 2 — Slack bot
npx tsx server.ts # terminal 2 — Channels runtime
```
Message the bot in Slack and it runs your Crew or Flow, streaming the reply back into the thread.
Mention the bot in Slack or Teams and it runs your Crew or Flow, streaming the reply back into the thread. The thread stays subscribed, so follow-up messages run without another mention.
</Step>
</Steps>
<Note>
Slack app scopes, Socket Mode setup, and the full adapter options are maintained by CopilotKit. Follow the [Slack channel reference](https://docs.copilotkit.ai/reference/channels/slack) together with Slack's own app setup guide for the authoritative steps.
</Note>
## The event model
## Discord
A channel reacts to platform events with handlers, and each handler receives a `thread` you drive with a few methods:
Discord uses the same `createBot` engine with the Discord adapter from `@copilotkit/channels-discord`:
- **`channel.onMention`** fires when a user @-mentions the bot. Call `thread.subscribe()` to join the thread, then `thread.runAgent()` to run your CrewAI agent on the mention.
- **`channel.onMessage`** fires on every message in a thread the bot can see. Gate it with `thread.isSubscribed()` so the agent only responds where it has joined, then `thread.runAgent()`.
- **`thread.runAgent()`** runs the attached CrewAI agent for the current turn and streams its output back into the channel. Pass `{ prompt }` to override the text the agent runs on.
```ts
import { createBot } from "@copilotkit/channels";
import { discord } from "@copilotkit/channels-discord";
import { CrewAIAgent } from "@ag-ui/crewai";
const bot = createBot({
adapters: [discord({ token: process.env.DISCORD_BOT_TOKEN! })],
agent: (threadId) => new CrewAIAgent({ url: "http://localhost:8000/recipe" }),
});
bot.start();
```
See the [Discord channel reference](https://docs.copilotkit.ai/reference/channels/discord) for the exact adapter options and bot setup.
Your agent receives an ordinary AG-UI `RunAgentInput` and emits ordinary AG-UI events; the platform mechanics stay behind the channel, so the same Crew or Flow runs unchanged across every platform. The channel also exposes handlers for welcomes, interrupts, commands, reactions, and modals — see the [`Channel` reference](https://docs.copilotkit.ai/reference/channels/classes/Channel) for the full surface.
## Platform support
Slack and Discord have official Channels adapters (`@copilotkit/channels-slack`, `@copilotkit/channels-discord`). Microsoft Teams is available through CopilotKit's managed offering (currently waitlisted). Check the [Channels reference](https://docs.copilotkit.ai/reference/channels) for the current list before promising a platform.
The managed Intelligence path covers **Slack** and **Microsoft Teams** today — the same channel code runs on either, and `message.platform` / `thread.platform` report the native origin. Other platforms (Discord, Telegram, WhatsApp) are reached through developer-operated **direct adapters** rather than the managed path — your own process holds the platform credentials and transport. Check the [CopilotKit Channels documentation](https://docs.copilotkit.ai/slack) for the current platform list and per-platform setup.
## Related

View File

@@ -21,7 +21,7 @@ The two connect through the [AG-UI protocol](https://docs.ag-ui.com). The `ag-ui
<Card title="Shared State" icon="arrows-rotate" href="/edge/en/guides/frontend/shared-state">
Keep agent state and your app UI in two-way sync.
</Card>
<Card title="Channels" icon="slack" href="/edge/en/guides/frontend/channels">
<Card title="Channels" icon="messages" href="/edge/en/guides/frontend/channels">
Run the same agent as a Slack, Discord, or Teams bot.
</Card>
</CardGroup>

View File

@@ -176,7 +176,7 @@ grep -r "llm:" --include="*.yaml" .
# llm = LLM(model="mistral/mistral-large-latest")
# After (Native):
llm = LLM(model="gemini/gemini-2.0-flash")
llm = LLM(model="gemini/gemini-3.7-flash")
```
```bash
@@ -399,7 +399,7 @@ llm = LLM(model="anthropic/claude-haiku-3-5") # Fast & affordable
# Together AI → OpenAI or Gemini
# llm = LLM(model="together_ai/meta-llama/Meta-Llama-3.1-70B")
llm = LLM(model="openai/gpt-4o") # High quality
llm = LLM(model="gemini/gemini-2.0-flash") # Fast & capable
llm = LLM(model="gemini/gemini-3.7-flash") # Fast & capable
# Mistral → Anthropic or OpenAI
# llm = LLM(model="mistral/mistral-large-latest")

View File

@@ -141,7 +141,7 @@ You can connect to OpenAI-compatible LLMs using either environment variables or
# Example using Gemini's OpenAI-compatible API.
os.environ["OPENAI_API_KEY"] = "your-gemini-key" # Should start with AIza...
os.environ["OPENAI_API_BASE"] = "https://generativelanguage.googleapis.com/v1beta/openai/"
os.environ["OPENAI_MODEL_NAME"] = "openai/gemini-2.0-flash" # Add your Gemini model here, under openai/
os.environ["OPENAI_MODEL_NAME"] = "openai/gemini-3.7-flash" # Add your Gemini model here, under openai/
```
</CodeGroup>
</Tab>
@@ -159,7 +159,7 @@ You can connect to OpenAI-compatible LLMs using either environment variables or
```python Google
# Example using Gemini's OpenAI-compatible API
llm = LLM(
model="openai/gemini-2.0-flash",
model="openai/gemini-3.7-flash",
base_url="https://generativelanguage.googleapis.com/v1beta/openai/",
api_key="your-gemini-key", # Should start with AIza...
)

View File

@@ -147,7 +147,7 @@ Planning agents benefit from reasoning models that can handle complex strategic
from crewai import Agent, Task, Crew, LLM
# High-capability reasoning model for strategic planning
manager_llm = LLM(model="gemini-2.5-flash-preview-05-20", temperature=0.1)
manager_llm = LLM(model="gemini/gemini-3.7-flash", temperature=0.1)
# Creative model for content generation
content_llm = LLM(model="claude-3-5-sonnet-20241022", temperature=0.7)
@@ -412,7 +412,7 @@ Rather than repeating the strategic framework, here's a tactical checklist for i
# Manager or coordination agents
manager_agent = Agent(
role="Project Manager",
llm=LLM(model="gemini-2.5-flash-preview-05-20"), # Premium for coordination
llm=LLM(model="gemini/gemini-3.7-flash"), # Premium for coordination
# ... rest of config
)

View File

@@ -9,7 +9,7 @@ mode: "wide"
CrewAI provides built-in tracing capabilities that allow you to monitor and debug your Crews and Flows in real-time. This guide demonstrates how to enable tracing for both **Crews** and **Flows** using CrewAI's integrated observability platform.
> **What is CrewAI Tracing?** CrewAI's built-in tracing provides comprehensive observability for your AI agents, including agent decisions, task execution timelines, tool usage, and LLM calls - all accessible through the [CrewAI AMP platform](https://app.crewai.com).
> **What is CrewAI Tracing?** CrewAI's built-in tracing provides comprehensive observability for your AI agents, including agent decisions, task execution timelines, tool usage, and LLM calls - all accessible through the [CrewAI AMP platform](https://app.crewai.com). Tracing is managed independently from [telemetry](/en/telemetry).
![CrewAI Tracing Interface](/images/crewai-tracing.png)
@@ -150,8 +150,8 @@ result = flow.kickoff()
### Step 5: View Traces in the CrewAI AMP Dashboard
After running the crew or flow, you can view the traces generated by your CrewAI application in the CrewAI AMP dashboard. You should see detailed steps of the agent interactions, tool usages, and LLM calls.
Just click on the link below to view the traces or head over to the traces tab in the dashboard [here](https://app.crewai.com/crewai_plus/trace_batches)
Traces are uploaded only after a successful authenticated export or an explicitly approved anonymous upload. A run whose local buffer is discarded has no uploaded trace.
For traces associated with your account, open the [Traces tab in the CrewAI AMP dashboard](https://app.crewai.com/crewai_plus/trace_batches) to view agent interactions, tool usage, and LLM calls.
![CrewAI Tracing Interface](/images/view-traces.png)
### Alternative: Environment Variable Configuration
@@ -170,6 +170,50 @@ CREWAI_TRACING_ENABLED=true
When this environment variable is set, all Crews and Flows will automatically have tracing enabled, even without explicitly setting `tracing=True`.
## Viewing traces after your first run
The first time you run a Crew or Flow, an interactive terminal may ask:
```text
Share this execution trace with CrewAI? [y/N]
```
Choose **yes** to upload the buffered trace to CrewAI. Traces may contain
prompts, inputs, and outputs. Declining, timing out, or running without an
interactive consent prompt discards the buffer. You can change tracing later
with `crewai traces enable` or `crewai traces disable`, or by setting `tracing`
on the Crew or Flow.
### Local buffering and authenticated export
First-run trace collection stays in process memory until you agree to share,
even if you have saved login credentials. Unauthenticated tracing uses the same
consent flow. Before consent, CrewAI requests no upload grant and sends no
execution spans.
The buffer retains up to **1,000 spans** and **8 MiB of encoded OTLP data**.
Set `CREWAI_EPHEMERAL_TRACE_MAX_SPANS` and
`CREWAI_EPHEMERAL_TRACE_MAX_BYTES` to positive integers to adjust these limits.
Overflow drops the oldest spans; a span larger than the byte limit is dropped.
The buffer is cleared after sharing or discarding it.
When tracing is enabled and credentials are available, CrewAI exchanges your
CLI login, `CREWAI_USER_PAT`, or platform integration credential with AMP for
an execution-specific grant. It then exports OpenTelemetry spans directly to
Wharf using that grant. Invalid credentials do not fall back to anonymous upload.
### Hosted execution sessions
Hosts can wrap execution with `telemetry_session` from
`crewai.telemetry.tracing`. The session uses CrewAI lifecycle events to create
and finish spans, preserving their timestamps, parent relationships, and HITL
pause/resume links. Pass an existing provider with `providers=` to retain the
host's tracer and logging integration. Pass span processors with `processors=`
and a host logging callback with `log_emitter=`. The host owns any redaction
in these integrations.
Each session owns its tracing lifecycle and leaves the application's global
OpenTelemetry provider unchanged.
## Viewing Your Traces
### Access the CrewAI AMP Dashboard
@@ -210,5 +254,5 @@ If traces aren't showing up in the dashboard:
1. Confirm `tracing=True` is set in your Crew/Flow
2. Check that `CREWAI_TRACING_ENABLED=true` if using environment variables
3. Ensure you're authenticated with `crewai login`
4. Verify your crew/flow is actually executing
3. For authenticated export, verify your CLI login, `CREWAI_USER_PAT`, or platform integration credential. For anonymous sharing, explicitly approve the consent prompt; login is not required
4. Verify your crew/flow executed and the trace export succeeded. Declining consent, timing out, or running without an interactive consent prompt discards the local buffer without uploading it

View File

@@ -23,7 +23,8 @@ usage of tools, API calls, responses, any data processed by the agents, or secre
When the `share_crew` feature is enabled, detailed data including task descriptions, agents' backstories or goals, and other specific attributes are collected
to provide deeper insights. This expanded data collection may include personal information if users have incorporated it into their crews or tasks.
Users should carefully consider the content of their crews and tasks before enabling `share_crew`.
Users can disable telemetry by setting the environment variable `CREWAI_DISABLE_TELEMETRY` to `true` or by setting `OTEL_SDK_DISABLED` to `true` (note that the latter disables all OpenTelemetry instrumentation globally).
Users can disable CrewAI telemetry by setting `CREWAI_DISABLE_TELEMETRY` to `true`, `1`, `yes`, or `on` (any case). `OTEL_SDK_DISABLED` with the same values also disables CrewAI's exporter. The OpenTelemetry SDK itself still only honors `true` for disabling other instrumentation in the process.
AMP tracing is covered separately in [Tracing](/en/observability/tracing).
### Examples:
```python
@@ -34,6 +35,8 @@ os.environ['CREWAI_DISABLE_TELEMETRY'] = 'true'
os.environ['OTEL_SDK_DISABLED'] = 'true'
```
`CREWAI_DISABLE_TELEMETRY=1` (or `yes` / `on`) works the same as `true`. Unrecognized values are ignored and leave telemetry on.
### Isolation from your own OpenTelemetry setup
CrewAI's telemetry runs on its own private `TracerProvider` and never registers
@@ -60,8 +63,8 @@ own tracer provider, which is independent of the one described here.
| Yes | Task Lifecycle Data | Includes: creation and execution start/end times, crew and task identifiers, and whether the task succeeded or failed. When a task fails, the **class name** of the exception is recorded (for example `TimeoutError`) so failures can be counted and diagnosed — never the error message, which can contain prompts, model output, file paths or credentials. Stored as spans with timestamps. No personal data. |
| Yes | LLM Attributes | Includes: name, model_name, model, top_k, temperature, and class name of the LLM. All technical, non-personal data. |
| Yes | Project Creation using crewAI CLI | Includes: that a new project was scaffolded by `crewai create`, which kind it was (`crew`, `json_crew` or `flow`), and the project ID minted for that new project and written into its own `pyproject.toml`. That is the new project's own ID, recorded separately from the `project_id` of the directory the command was run from — the two can differ. No project name, no file contents, no code. No personal data. |
| Yes | Crew Deployment attempt using crewAI CLI | Includes: The fact a deploy is being made and crew id, whether it's trying to pull logs, and whether the deploy was started from a CLI command or from the run TUI. No project or crew contents. No personal data. |
| Yes | Execution Environment | Includes: which AI coding assistant is running the process, if any (one of a fixed list such as `claude_code`, `codex`, `cursor`, or `unknown`), where the process runs (one of a fixed list such as `ci`, `container`, `serverless`, `interactive`), and the `project_id` from your `pyproject.toml` when one is configured. Detection reads only whether known environment variables are set, never their values. No personal data. |
| Yes | Crew Deployment attempt using crewAI CLI | Includes: The fact a deploy is being made and crew id, whether it's trying to pull logs, and whether the deploy was started from a CLI command or from the run TUI. If creating a deployment fails, the failure category (one of a fixed list such as `api_4xx`, `network_error` or `user_declined`) and the HTTP status code of the API response, when there was one, are recorded — never the error message. No project or crew contents. No personal data. |
| Yes | Execution Environment | Includes: which AI coding assistant is running the process, if any (one of a fixed list such as `claude_code`, `codex`, `cursor`, or `unknown`), where the process runs (one of a fixed list such as `ci`, `container`, `serverless`, `interactive`), the `project_id` from your `pyproject.toml` when one is configured, and a coarse size band for the machine (one of `1-2`, `3-4`, `5-8`, `9-16`, `17-32`, `33+`, or `unknown`). The band is a range, never the exact core count — the exact count is opt-in only, under Environment Information below. The size band comes from the host CPU count; assistant and location detection reads only whether known environment variables are set, never their values. No personal data. |
| Yes | Flow Lifecycle Signals | Includes: that a flow started, whether it completed or failed, whether one of its methods failed, whether it paused for human input or feedback, whether the start was a resumed run, whether a conversation turn failed, how long the flow ran, and whether the flow is one CrewAI runs internally or one you wrote. The flow name is recorded, as it already is for flow creation and execution. When a flow or one of its methods fails, the **class name** of the exception is recorded (for example `TimeoutError`) so that failures can be diagnosed — never the error message, which can contain prompts, model output, file paths or credentials. Method names and flow state are never recorded. No personal data. |
| Yes | Trace Sharing Signal | Includes: that a batch of traces was successfully shared with CrewAI AMP, and whether it was shared anonymously (before you have an account) or linked to your account. Like every span, it also carries the Execution Environment attributes described above (`project_id` when configured, the coding assistant, and the runtime). This row describes sharing telemetry only — not the trace contents or access granted by shared trace links. Trace contents, inputs, and outputs are never recorded on this signal. Before sharing traces, review secrets, personal data, and AMP redaction and retention settings. |
| No | Agent's Expanded Data | Includes: goal description, backstory text, i18n prompt file identifier. Users should ensure no personal info is included in text fields. |

View File

@@ -50,16 +50,15 @@ These tools integrate with AI and machine learning services to enhance your agen
- **AI Safety**: Implement content moderation and safety checks
```python
from crewai_tools import DallETool, VisionTool, CodeInterpreterTool
from crewai_tools import DallETool, VisionTool
# Create AI tools
image_generator = DallETool()
vision_processor = VisionTool()
code_executor = CodeInterpreterTool()
# Add to your agent
agent = Agent(
role="AI Specialist",
tools=[image_generator, vision_processor, code_executor],
tools=[image_generator, vision_processor],
goal="Create and analyze content using AI capabilities"
)

View File

@@ -460,7 +460,7 @@ The `embedding_model` parameter accepts a `crewai.rag.embeddings.types.ProviderS
**Config Options:**
- `model_name` (str): HuggingFace model ID. Default: `hkunlp/instructor-base`. Options: `hkunlp/instructor-xl`, `hkunlp/instructor-large`, `hkunlp/instructor-base`
- `device` (str): Device to run on. Default: `cpu`. Options: `cpu`, `cuda`, `mps`
- `device` (str): Device to run on. Default: `cpu`. Options: `cpu`, `cuda`, `mps`, `xpu`
- `instruction` (str): Instruction prefix for embeddings
**Environment Variables:**
@@ -485,7 +485,7 @@ The `embedding_model` parameter accepts a `crewai.rag.embeddings.types.ProviderS
**Config Options:**
- `model_name` (str): Sentence Transformers model name. Default: `all-MiniLM-L6-v2`. Options: `all-mpnet-base-v2`, `all-MiniLM-L6-v2`, `paraphrase-multilingual-MiniLM-L12-v2`
- `device` (str): Device to run on. Default: `cpu`. Options: `cpu`, `cuda`, `mps`
- `device` (str): Device to run on. Default: `cpu`. Options: `cpu`, `cuda`, `mps`, `xpu`
- `normalize_embeddings` (bool): Whether to normalize embeddings. Default: `False`
**Environment Variables:**

View File

@@ -12,6 +12,16 @@ mode: "wide"
This tool is used to extract text from images. When passed to the agent it will extract the text from the image and then use it to generate a response, report or any other output.
The URL or the PATH of the image should be passed to the Agent.
You can also ask a custom `query` about the image and pick a `complexity_level` that automatically selects the model best suited for the request:
| Complexity level | Model |
| :--------------- | :------------ |
| `easy` | `gpt-5.6-luna` |
| `medium` (default) | `gpt-5.6-terra` |
| `hard` | `gpt-5.6-sol` |
When an explicit `llm` or `model` is provided to the tool, it takes precedence over the complexity-based model selection.
## Installation
Install the crewai_tools package
@@ -43,8 +53,10 @@ def researcher(self) -> Agent:
## Arguments
The VisionTool requires the following arguments:
The VisionTool accepts the following arguments:
| Argument | Type | Description |
| :----------------- | :------- | :------------------------------------------------------------------------------- |
| **image_path_url** | `string` | **Mandatory**. The path to the image file from which text needs to be extracted. |
| Argument | Type | Description |
| :------------------- | :------- | :----------------------------------------------------------------------------------------------------------- |
| **image_path_url** | `string` | **Mandatory**. The path to the image file (or URL) from which text needs to be extracted. |
| **query** | `string` | **Optional**. The question or instruction to ask the model about the image. Defaults to `"What's in this image?"`. |
| **complexity_level** | `string` | **Optional**. The complexity of the request, which selects the model: `easy`, `medium`, or `hard`. Defaults to `medium`. |

View File

@@ -4,7 +4,7 @@ description: >
Oxylabs Scrapers allow to easily access the information from the respective sources. Please see the list of available sources below:
- `Amazon Product`
- `Amazon Search`
- `Google Seach`
- `Google Search`
- `Universal`
icon: globe
mode: "wide"
@@ -87,7 +87,7 @@ print(result)
### Parameters
- `query` - Amazon search term.
- `domain` - Domain localization for Bestbuy.
- `domain` - domain localization for Amazon.
- `start_page` - starting page number.
- `pages` - number of pages to retrieve.
- `geo_location` - the _Deliver to_ location.

View File

@@ -4,6 +4,145 @@ description: "CrewAI의 제품 업데이트, 개선 사항 및 버그 수정"
icon: "clock"
mode: "wide"
---
<Update label="2026년 9월 16일">
## v1.15.22
[GitHub 릴리스 보기](https://github.com/crewAIInc/crewAI/releases/tag/1.15.22)
## 변경 사항
### 기능
- 연결 식별자로서 별칭 지원
- 배포 생성 실패 사유 기록
- 추적에서 인간 피드백 및 일시 중지 이벤트 수집
- 에이전트 역할을 모델로 라우팅하기 위해 `llm_overlay` 컨텍스트 변수 추가
- 에이전트 실행 페이로드에 `task_prompt` 및 출력 포함
- 승무원 설정 중 플랫폼 통합 검증
- JSON 승무원 마법사에 플랫폼 도구 추가
- CrewAI 플랫폼 애플리케이션 카탈로그 노출
- OpenRouter를 지원되는 임베딩 제공자로 추가
### 버그 수정
- 인라인 기술 정의에서 CRLF 수용
- 안전한 가져오기를 통해 텍스트 파일 URL 로드
- 시작 작업 출력 저장소에서 SQLite 연결 닫기
- 네이티브 도구 경로의 `ToolUsageFinishedEvent`에서 `from_cache` 전달
- 업로더에서 단순한 raise 대신 `ValueError` 발생
- SQLiteFlowPersistence에서 비원시 유형 지원
- 코딩 에이전트 지침 개선
- JSON 체크포인트를 UTF-8로 읽기
- Windows에서 오래된 `poetry.lock` 백업 덮어쓰기
- Azure에서 와이어 인덱스로 스트리밍된 도구 호출 키 지정
- Gemini에서 파일 데이터 콘텐츠 부분 보존
- `update()` 및 `recall()` 접근 시간에 대해 `read_only` 준수
- 모든 OpenAI 추론 모델에 `reasoning_effort` 전송
- 스트리밍된 출력에 리터럴 `[...]`가 포함될 때 실행 TUI에서 충돌 방지
- 저장된 작업이 다를 경우 재생 거부
- Windows에서 mypy 호환성을 위한 `sys.platform` 보호 사용
- 사용자 턴으로 강제 최종 답변 요청
- 프롬프트에 포함된 작업 출력 스키마에서 null 유지
- `DOCXSearchTool`을 표준 RAG 고정 스키마 패턴에 맞추기
### 문서
- 임베딩 장치 옵션에 `xpu` 추가
- 모든 작업 공간 패키지 나열
## 기여자
@ASTion24, @BlueX888, @HUAN2022A, @RaycarlLei, @Rohitkanithi, @SWAPI03, @SharoonSharif, @ShivangiRay, @Theater-ahyeon, @Vidit-Ostwal, @gamal1osama, @github-actions[bot], @joaomdmoura, @lorenzejay, @mhbuehler, @modusensus, @monkscode, @rohitkanithi, @roli-lpci, @vinibrsl, @wangtaotaotao95
</Update>
<Update label="2026년 9월 9일">
## v1.15.21
[GitHub 릴리스 보기](https://github.com/crewAIInc/crewAI/releases/tag/1.15.21)
## 변경 사항
### 기능
- 체크포인트 실행 시간 및 CLI 사용을 추적하기 위한 텔레메트리 추가.
### 버그 수정
- HTTP 200 응답 내에서 보고된 게이트웨이 오류 수정.
- AMP 소스 생성 시 배포 푸시 유지.
- Oxylabs 통합에서 IndexError를 발생시키는 대신 스크랩 실패 보고.
- 모든 DashScope 모델을 네이티브 제공자를 통해 라우팅.
- JSON 체크포인트를 UTF-8로 유지.
- BrightData의 f-string 검색 URL에서 이탈한 $ 제거.
- JSON 스키마 변환에서 리스트 형태의 배열 지원.
- gpt-4o-mini 컨텍스트 창 크기를 200000에서 128000으로 수정.
- contentBlockStop에서 스트리밍 도구 호출 인수 유지.
- Windows에서 pre-commit 훅을 휴대 가능하게 만듦.
### 문서
- 추적이 텔레메트리와 별도로 관리됨을 명확히 함.
- 병렬 검색 참조 링크 수정.
- handle_llm_stream_chunk 문서 문자열에서 오래된 매개변수 제거.
- 스트리밍 출력 문서 문자열 예제 수정.
- 기술 설치 참조에서 조직 UUID 사용.
## 기여자
@Alphaxiaoteng, @DrewWhittleNZ, @Ghraven, @Shxiao101, @Vaishnavi220506, @Vidit-Ostwal, @danielfsbarreto, @georgeatparallel, @github-actions[bot], @jessemiller, @joaomdmoura, @kimnamu, @kiwoongyoon, @liang0417, @lorenzejay, @oxy-giedrius, @simpleqt, @uoparaji
</Update>
<Update label="2026년 9월 4일">
## v1.15.20
[GitHub 릴리스 보기](https://github.com/crewAIInc/crewAI/releases/tag/1.15.20)
## 변경 사항
### 버그 수정
- 레거시 플랫폼 도구 별칭 검색 수정
### 문서
- v1.15.19에 대한 스냅샷 및 변경 로그 업데이트
## 기여자
@joaomdmoura, @vinibrsl
</Update>
<Update label="2026년 9월 4일">
## v1.15.19
[GitHub 릴리스 보기](https://github.com/crewAIInc/crewAI/releases/tag/1.15.19)
## 변경 사항
### 기능
- Clipper 통합 클라이언트 추가
- CEL 표현식 환경에 `now()` 추가
- 모든 사용자에 대해 크루 실행이 어떻게 종료되었는지 기록
- 기계 크기를 코어 수가 아닌 대략적인 범위로 보고
- CrewAI 플랫폼 도구를 위한 주입 가능한 클라이언트 추가
### 버그 수정
- `urlreadtool`에서 octet-stream 및 xlsx URL 읽기 수정
- 네이티브 Gemini 제공자에서 후행 사용자 전환 추가 수정
- Ollama 기본 URL에서 스킴 및 포트 정규화
- 메모리에서 재사용 가능한 범위 구성 유지
- 보안 취약성을 위해 `pypdf`를 6.16.2로 업데이트
- 보안 취약성을 위해 `nltk`를 3.10.3으로 업데이트
- 현재 Claude 모델 및 Snowflake CVE 바닥을 위한 네이티브 구조화된 출력 수정
- 모든 경로에서 모델 호출 후크 실행 및 거부 전파
### 문서
- AI/ML 개요 예제에서 `CodeInterpreterTool` 제거
- `prompt-template` 링크를 현재 경로로 지정
- 현재 CopilotKit 채널 API에 맞게 채널 가이드 업데이트
- 퇴역한 Gemini 모델 ID 새로 고침
## 기여자
@Vidit-Ostwal, @a-yeyang, @github-actions[bot], @hvlcrs, @joaomdmoura, @kikifrost, @lorenzejay, @lucasgomide, @parthiban-sivakumar, @ranst91, @tandede, @thiagomoretto, @vinibrsl
</Update>
<Update label="2026년 8월 27일">
## v1.15.18

View File

@@ -286,6 +286,7 @@ crewai org switch <organization_id>
- CrewAI AMP 플랫폼에서 배포 프로세스를 시작합니다.
- 성공적으로 시작되면, Deployment created successfully! 메시지와 함께 Deployment Name 및 고유한 Deployment ID(UUID)가 출력됩니다.
- Push는 생성 시 사용한 소스를 유지합니다. 나중에 git `origin`을 추가해도 ZIP 배포가 git으로 바뀌지 않습니다.
- **배포 상태**: 배포 상태를 확인하려면 다음을 사용합니다:

View File

@@ -603,6 +603,21 @@ agent = Agent(
}
}
)
# Option 4: Use OpenRouter embeddings (supports models across providers)
# Set OPENROUTER_API_KEY environment variable if api_key is omitted in config
crew = Crew(
agents=[agent],
tasks=[...],
knowledge_sources=[knowledge_source],
embedder={
"provider": "openrouter",
"config": {
"model_name": "openai/text-embedding-3-small",
"api_key": "your-openrouter-api-key" # Optional if OPENROUTER_API_KEY is set
}
}
)
```
#### Azure OpenAI 임베딩 구성

View File

@@ -995,6 +995,38 @@ LLM 설정을 최대한 활용하는 방법을 알아보세요:
llm = LLM(model="gpt-4")
```
</Tab>
<Tab title="게이트웨이 오류">
<Tip>
OpenRouter와 같은 게이트웨이는 업스트림 공급자가 요청을 수락하는 즉시 `200 OK`를 반환하므로, 공급자 타임아웃은 상태 코드가 아니라 응답 본문에 담겨 도착합니다.
</Tip>
CrewAI는 해당 업스트림 코드가 실제 HTTP 상태로 왔을 때 발생시킬 예외와 동일한 예외를 발생시키므로, 이미 구성해 둔 재시도 처리로 가려진 실패를 잡을 수 있습니다:
```python
import openai
from pydantic import BaseModel
from crewai import LLM
class Report(BaseModel):
summary: str
llm = LLM(model="openrouter/z-ai/glm-5.3", response_format=Report)
try:
result = llm.call("Summarize the incident", response_model=Report)
except openai.InternalServerError as e:
# "z-ai/glm-5.3 via openrouter.ai returned HTTP 200 with an upstream error
# and no choices: The operation was aborted (upstream code 504)"
print(f"Upstream provider failed, safe to retry: {e}")
```
<Warning>
크거나 깊게 중첩된 `response_model`은 업스트림 타임아웃 가능성을 높입니다. 이를 모델이 잘못된 구조화 출력을 생성한 것으로 보지 말고, 일시적인 공급자 장애로 처리하세요.
</Warning>
</Tab>
<Tab title="컨텍스트 길이">
<Tip>
대규모 작업에는 더 큰 컨텍스트 모델을 사용하세요.

View File

@@ -736,7 +736,7 @@ memory = Memory(llm="anthropic/claude-3-haiku-20240307")
memory = Memory(llm="ollama/llama3.2")
# Google Gemini 사용
memory = Memory(llm="gemini/gemini-2.0-flash")
memory = Memory(llm="gemini/gemini-3.7-flash")
# 사용자 정의 설정이 있는 사전 구성된 LLM 인스턴스 전달
llm = LLM(model="gpt-4o", temperature=0)

View File

@@ -202,13 +202,17 @@ crewai skill publish
### 설치
게시된 스킬을 `@org/name` 참조로 설치합니다:
게시된 스킬을 `@org-uuid/name` 참조로 설치합니다:
```shell Terminal
crewai skill install @acme/code-review
crewai skill install @your-org-uuid/code-review
```
크루 프로젝트 내부에서는 스킬이 `./skills/{name}/`에 설치되고, 프로젝트 외부에서는 공유 캐시인 `~/.crewai/skills/{org}/{name}/`에 저장됩니다.
<Note>
조직 이름이 아니라 조직 **UUID**를 사용하세요 — 조직 이름은 고유하지 않아서 잘못된 조직으로 해석될 수 있고, 그러면 설치가 "찾을 수 없음" 오류로 실패합니다. `crewai org list`를 실행하면 소속된 각 조직의 UUID(`ID` 열)를 확인할 수 있습니다.
</Note>
크루 프로젝트 내부에서는 스킬이 `./skills/{name}/`에 설치되고, 프로젝트 외부에서는 공유 캐시인 `~/.crewai/skills/{org-uuid}/{name}/`에 저장됩니다.
에이전트는 레지스트리 스킬을 직접 참조할 수도 있습니다 — 런타임에 로컬 캐시(또는 프로젝트 `skills/` 디렉터리)에서 해석됩니다:
@@ -217,7 +221,7 @@ agent = Agent(
role="Senior Code Reviewer",
goal="Review pull requests for quality and security issues",
backstory="Staff engineer with expertise in secure coding practices.",
skills=["@acme/code-review"], # registry ref, resolved locally
skills=["@your-org-uuid/code-review"], # registry ref, resolved locally
)
```

View File

@@ -26,7 +26,7 @@ CrewAI의 기본 프롬프트는 많은 시나리오에서 잘 작동하지만,
- **오류 처리** – agent가 실패, 예외, 또는 타임아웃에 어떻게 반응할지 지정합니다.
- **도구별 prompt** – 도구가 호출되거나 사용되는 방법에 대한 상세 지침을 정의합니다.
이 요소들이 어떻게 구성되어 있는지 보려면 [CrewAI 저장소의 원본 prompt 템플릿](https://github.com/crewAIInc/crewAI/blob/main/src/crewai/translations/en.json)을 확인하세요. 여기서 필요에 따라 오버라이드하거나 수정하여 고급 동작을 구현할 수 있습니다.
이 요소들이 어떻게 구성되어 있는지 보려면 [CrewAI 저장소의 원본 prompt 템플릿](https://github.com/crewAIInc/crewAI/blob/main/lib/crewai/src/crewai/translations/en.json)을 확인하세요. 여기서 필요에 따라 오버라이드하거나 수정하여 고급 동작을 구현할 수 있습니다.
## 기본 시스템 지침 이해하기

View File

@@ -11,7 +11,7 @@ mode: "wide"
## CLI로 프로젝트 생성
CrewAI CLI를 사용하여 프로젝트를 스캐폴딩하면, `AGENTS.md`가 루트에 자동으로 추가됩니다.
CrewAI CLI를 사용하여 프로젝트를 스캐폴딩하세요. `AGENTS.md`가 루트에 추가되며, 이를 임포트하는 `CLAUDE.md`와 `GEMINI.md`도 함께 추가되므로 Claude Code와 Gemini CLI가 다른 모든 어시스턴트와 동일한 안내를 읽습니다.
```bash
# Crew
@@ -32,24 +32,28 @@ Codex는 저장소에 배치된 `AGENTS.md` 파일로 안내할 수 있습니다
### Claude Code
Claude Code는 프로젝트 메모리를 `CLAUDE.md`에 저장합니다. `/init`으로 부트스트랩하고 `/memory`로 편집할 수 있습니다. Claude Code는 `CLAUDE.md` 내에서 임포트도 지원하므로, `@AGENTS.md`와 같은 한 줄을 추가하여 공유 지침을 중복 없이 가져올 수 있습니다.
Claude Code는 `CLAUDE.md`를 읽고 `AGENTS.md`는 무시합니다. 스캐폴딩된 프로젝트에는 임포트 줄 `@AGENTS.md` 하나만 담긴 `CLAUDE.md`가 포함되어 있어, 공유 안내가 중복 없이 로드됩니다. Claude 전용 메모는 그 줄 아래에 추가하고, 공유 컨벤션은 `AGENTS.md`에 유지하세요.
간단하게 다음과 같이 사용할 수 있습니다:
`CLAUDE.md`가 스캐폴딩되기 전에 생성된 프로젝트라면 임포트를 직접 추가하세요:
```bash
mv AGENTS.md CLAUDE.md
printf '@AGENTS.md\n' > CLAUDE.md
```
`AGENTS.md`를 `CLAUDE.md`로 이름을 바꾸지 마세요. Codex와 Cursor는 `AGENTS.md`를 읽으며, 이름을 바꾸면 이들에게 보이지 않게 됩니다.
### Gemini CLI와 Google Antigravity
Gemini CLI와 Antigravity는 저장소 루트 및 상위 디렉토리에서 프로젝트 컨텍스트 파일(기본값: `GEMINI.md`)을 로드합니다. Gemini CLI 설정에서 `context.fileName`을 설정하여 `AGENTS.md`를 대신(또는 추가로) 읽도록 구성할 수 있습니다. 예를 들어, `AGENTS.md`만 설정하거나 각 도구의 형식을 유지하고 싶다면 `AGENTS.md`와 `GEMINI.md`를 모두 포함할 수 있습니다.
Gemini CLI와 Antigravity는 저장소 루트 및 상위 디렉토리에서 프로젝트 컨텍스트 파일(기본값: `GEMINI.md`)을 로드합니다. 스캐폴딩된 프로젝트에는 임포트 줄 `@./AGENTS.md` 하나만 담긴 `GEMINI.md`가 포함되어 있어, 공유 안내가 중복 없이 로드됩니다. Gemini 전용 메모는 그 줄 아래에 추가하고, 공유 컨벤션은 `AGENTS.md`에 유지하세요.
간단하게 다음과 같이 사용할 수 있습니다:
`GEMINI.md`가 스캐폴딩되기 전에 생성된 프로젝트라면 임포트를 직접 추가하세요:
```bash
mv AGENTS.md GEMINI.md
printf '@./AGENTS.md\n' > GEMINI.md
```
또는 Gemini CLI 설정의 `context.fileName`에 `AGENTS.md`를 포함시키면 Gemini가 이를 직접 읽습니다. `AGENTS.md`를 `GEMINI.md`로 이름을 바꾸지 마세요. Codex와 Cursor는 `AGENTS.md`를 읽으며, 이름을 바꾸면 이들에게 보이지 않게 됩니다.
### Cursor
Cursor는 `AGENTS.md`를 프로젝트 지침 파일로 지원합니다. 프로젝트 루트에 배치하여 Cursor의 코딩 어시스턴트에 안내를 제공하세요.

View File

@@ -75,7 +75,7 @@ research_crew/
}
```
`provider/model-id`를 `openai/gpt-4o`, `anthropic/claude-sonnet-4-6`, `gemini/gemini-2.0-flash-001` 같은 모델로 바꾸세요.
`provider/model-id`를 `openai/gpt-4o`, `anthropic/claude-sonnet-4-6`, `gemini/gemini-3.7-flash` 같은 모델로 바꾸세요.
## 3단계: 태스크와 Crew 설정

View File

@@ -135,7 +135,7 @@ crewai flow add-crew content-crew
}
```
`provider/model-id`를 사용하는 모델로 바꾸세요. 예: `openai/gpt-4o`, `gemini/gemini-2.0-flash-001`, `anthropic/claude-sonnet-4-6`.
`provider/model-id`를 사용하는 모델로 바꾸세요. 예: `openai/gpt-4o`, `gemini/gemini-3.7-flash`, `anthropic/claude-sonnet-4-6`.
3. `src/guide_creator_flow/crews/content_crew/crew.jsonc`를 만듭니다:
@@ -481,7 +481,7 @@ Flow를 사용하면 간단하고 구조화된 응답이 필요할 때 언어
```python
llm = LLM(
model="model-id-here", # gpt-4o, gemini-2.0-flash, anthropic/claude...
model="model-id-here", # gpt-4o, gemini/gemini-3.7-flash, anthropic/claude...
response_format=GuideOutline
)
response = llm.call(messages=messages)

View File

@@ -0,0 +1,156 @@
---
title: Channels
description: CopilotKit Channels SDK와 관리형 Intelligence 플랫폼으로 동일한 CrewAI 에이전트를 Slack 또는 Teams 봇으로 실행하세요.
icon: messages
mode: "wide"
---
## 사용자가 이미 있는 곳에서 만나세요
[Overview](/edge/ko/guides/frontend/overview)에서 만든 CrewAI 에이전트는 반드시 웹 앱 뒤에서만 동작할 필요가 없습니다. 동일한 Crew 또는 Flow를 메시징 플랫폼 안에서 봇으로 실행할 수 있습니다. 다시 빌드할 필요도, 에이전트 로직을 두 번 복사할 필요도 없습니다. 에이전트는 [AG-UI 프로토콜](https://docs.ag-ui.com)을 통해 그대로 노출되고, **channel**이 Slack 또는 Microsoft Teams에서 이를 구동합니다.
CopilotKit의 [Channels SDK](https://docs.copilotkit.ai/slack)가 그 channel을 제공합니다. 작은 런타임에 `createChannel`을 선언하고 이를 CrewAI 에이전트에 연결하면, CopilotKit의 관리형 **Intelligence** 플랫폼이 메시징 제공자와의 연결을 중개합니다.
<Note>
이 섹션의 나머지 내용과 달리 Channels는 **셀프 호스팅되지 않습니다**. Channels는 **CopilotKit Intelligence**를 통해 실행되며, 이는 설계상 Channels에 필수적인 서비스입니다(무료 티어 제공). Intelligence는 플랫폼 연결과 자격 증명을 보관하고, 각 플랫폼 이벤트를 수신하며, 해당 턴을 여러분의 channel 프로세스로 전달합니다. 여러분의 프로세스는 에이전트를 실행하고 응답을 다시 스트리밍합니다. Slack은 Intelligence 대시보드에서 한 번만 구성하면 되며, 플랫폼 자격 증명은 결코 여러분의 프로세스로 들어오지 않습니다. 에이전트, 도구, 상태는 온전히 여러분의 것으로 유지됩니다.
</Note>
## 어떻게 맞물리는가
CrewAI 에이전트 서버에 관한 것은 아무것도 바뀌지 않습니다. Overview에서와 똑같이 AG-UI를 통해 Crew 또는 Flow를 계속 제공합니다. 여러분이 추가하는 것은 `@copilotkit/channels`로 빌드된 별도의 장시간 실행 Node 프로세스입니다. 이 프로세스는 `CopilotRuntime`에 channel을 등록하고, Intelligence에 연결하며, 메시지가 도착할 때마다 에이전트를 실행합니다.
```
Slack / Teams ──► CopilotKit Intelligence ──► channel process (Node) ──► CrewAI server (AG-UI) ──► Crew / Flow
```
channel 프로세스는 Intelligence 게이트웨이에 대한 지속적인 연결을 유지하므로, 장시간 실행되는 호스트가 필요합니다. 서버리스 요청 핸들러는 그 연결을 소유할 수 없습니다. CrewAI 서버는 동시에 Overview의 웹 프론트엔드를 계속 제공할 수 있습니다. 웹 앱과 channel은 하나의 AG-UI 엔드포인트에 연결된 두 개의 클라이언트일 뿐입니다.
## 통합 가이드
<Steps>
<Step title="Channels 패키지 설치">
Channels SDK는 모든 것이 포함되어 있습니다. 모든 플랫폼이 하나의 패키지로 제공되며, 플랫폼별로 설치할 어댑터가 없습니다. channel을 호스팅하는 런타임 및 CrewAI AG-UI 클라이언트와 함께 다음을 추가하세요:
```bash
npm install @copilotkit/channels @copilotkit/runtime @ag-ui/crewai
```
</Step>
<Step title="Intelligence에서 Channel 생성">
[CopilotKit 대시보드](https://docs.copilotkit.ai/slack)에서 Channel을 생성하고 Slack을 연결하세요. Intelligence가 Slack 앱 생성 과정을 안내하고 그 자격 증명을 보관합니다. 그러면 여러분의 프로세스를 위한 두 개의 환경 변수가 남으며, 둘 다 대시보드에서 얻습니다:
```bash
export INTELLIGENCE_API_KEY=... # authenticates the runtime with Intelligence (free tier available)
export INTELLIGENCE_CHANNEL_ID=... # the Channel ID, matched by createChannel({ name })
```
</Step>
<Step title="channel 정의">
`createChannel`은 channel을 선언하고 에이전트를 연결합니다. 각 대화가 자신만의 세션을 갖도록 에이전트를 스레드별 팩토리로 빌드하되, Overview가 웹 런타임에서 사용하는 것과 동일한 `CrewAIAgent`를 여러분의 AG-UI 엔드포인트를 가리키도록 설정하세요. `identifyUser: "platform"`은 Intelligence가 각 플랫폼 사용자를 안정적인 신원에 매핑하도록 합니다.
```ts
// channel.ts
import { createChannel } from "@copilotkit/channels";
import { CrewAIAgent } from "@ag-ui/crewai";
const channel = createChannel({
name: process.env.INTELLIGENCE_CHANNEL_ID!, // must match the Channel ID in Intelligence
identifyUser: "platform",
// A fresh agent per conversation, pointed at your CrewAI AG-UI endpoint.
agent: (threadId) => {
const agent = new CrewAIAgent({ url: "http://localhost:8000/recipe" });
agent.threadId = threadId;
return agent;
},
});
// A mention subscribes the thread and runs the agent; afterwards every message
// in a subscribed thread runs it without needing another mention.
channel.onMention(async ({ thread }) => {
await thread.subscribe();
await thread.runAgent();
});
channel.onMessage(async ({ thread }) => {
if (await thread.isSubscribed()) await thread.runAgent();
});
export { channel };
```
</Step>
<Step title="런타임에 channel 등록">
Intelligence 게이트웨이와 여러분의 channel로 `CopilotRuntime`을 생성한 다음, `createCopilotNodeListener`로 이를 제공하세요. `agents` 맵은 비어 있는 상태로 둡니다. channel이 자신의 에이전트를 제공하기 때문입니다. 잘못된 구성이 시작 시 명확하게 실패하도록 channel이 준비될 때까지 기다리세요.
```ts
// server.ts
import { createServer } from "node:http";
import { CopilotRuntime, CopilotKitIntelligence } from "@copilotkit/runtime/v2";
import { createCopilotNodeListener } from "@copilotkit/runtime/v2/node";
import { channel } from "./channel";
const runtime = new CopilotRuntime({
agents: {}, // the channel supplies its own agent; no web-facing agents needed
intelligence: new CopilotKitIntelligence({
apiKey: process.env.INTELLIGENCE_API_KEY!, // free tier available
}),
channels: [channel],
});
const listener = createCopilotNodeListener({ runtime });
await listener.channels?.ready({ timeoutMs: 15_000 });
createServer(listener).listen(3123, () => {
console.log("Channels runtime listening on port 3123");
});
```
</Step>
<Step title="channel 런타임 실행">
CrewAI 에이전트 서버와 함께 시작하세요:
```bash
uvicorn server:app --port 8000 # terminal 1 — CrewAI agent server
npx tsx server.ts # terminal 2 — Channels runtime
```
Slack 또는 Teams에서 봇을 멘션하면 Crew 또는 Flow를 실행하고 응답을 스레드로 다시 스트리밍합니다. 스레드는 구독된 상태로 유지되므로 후속 메시지는 또다시 멘션할 필요 없이 실행됩니다.
</Step>
</Steps>
## 이벤트 모델
channel은 핸들러로 플랫폼 이벤트에 반응하며, 각 핸들러는 몇 가지 메서드로 구동하는 `thread`를 받습니다:
- **`channel.onMention`**은 사용자가 봇을 @-멘션할 때 발생합니다. `thread.subscribe()`를 호출해 스레드에 참여한 다음, `thread.runAgent()`로 멘션에 대해 CrewAI 에이전트를 실행하세요.
- **`channel.onMessage`**는 봇이 볼 수 있는 스레드의 모든 메시지에서 발생합니다. `thread.isSubscribed()`로 게이트를 걸어 에이전트가 참여한 곳에서만 응답하도록 한 다음, `thread.runAgent()`를 호출하세요.
- **`thread.runAgent()`**는 현재 턴에 대해 연결된 CrewAI 에이전트를 실행하고 그 출력을 channel로 다시 스트리밍합니다. 에이전트가 실행할 텍스트를 재정의하려면 `{ prompt }`를 전달하세요.
여러분의 에이전트는 일반적인 AG-UI `RunAgentInput`을 받고 일반적인 AG-UI 이벤트를 방출합니다. 플랫폼 메커니즘은 channel 뒤에 머무르므로, 동일한 Crew 또는 Flow가 모든 플랫폼에서 변경 없이 실행됩니다. channel은 환영 인사, 인터럽트, 명령, 반응, 모달을 위한 핸들러도 노출합니다. 전체 표면은 [`Channel` 레퍼런스](https://docs.copilotkit.ai/reference/channels/classes/Channel)를 참조하세요.
## 플랫폼 지원
관리형 Intelligence 경로는 현재 **Slack**과 **Microsoft Teams**를 지원합니다. 동일한 channel 코드가 양쪽에서 실행되며, `message.platform` / `thread.platform`이 원래의 출처를 보고합니다. 다른 플랫폼(Discord, Telegram, WhatsApp)은 관리형 경로가 아니라 개발자가 운영하는 **direct adapters**를 통해 연결됩니다. 여러분 자신의 프로세스가 플랫폼 자격 증명과 전송을 보유합니다. 현재 지원 플랫폼 목록과 플랫폼별 설정은 [CopilotKit Channels 문서](https://docs.copilotkit.ai/slack)를 확인하세요.
## 관련 항목
<CardGroup cols={2}>
<Card title="Frontend Overview" icon="browser" href="/edge/ko/guides/frontend/overview">
Crew 또는 Flow를 AG-UI를 통해 제공하세요. 모든 channel이 그 위에 세워지는 토대입니다.
</Card>
<Card title="Human-in-the-Loop" icon="user-check" href="/edge/en/guides/frontend/human-in-the-loop">
실행 도중 사용자 승인이나 입력을 수집하기 위해 에이전트를 일시 중지하세요.
</Card>
</CardGroup>

View File

@@ -0,0 +1,238 @@
---
title: Frontend Overview
description: CopilotKit과 AG-UI 프로토콜로 CrewAI 에이전트를 위한 인터랙티브 사용자 인터페이스를 구축하세요.
icon: browser
mode: "wide"
---
## 에이전트에 사용자 인터페이스를 부여하세요
CrewAI는 여러분의 에이전트를 실행합니다. [CopilotKit](https://copilotkit.ai)은 그 에이전트에 프론트엔드를 제공합니다. 이 둘을 함께 사용하면 사용자가 Crew 또는 Flow와 대화하고, 실시간으로 작동하는 모습을 지켜보고, 그 결정을 승인하며, 출력을 장황한 텍스트 대신 살아 있는 UI로 렌더링하여 볼 수 있는 애플리케이션을 구축할 수 있습니다.
이 둘은 [AG-UI 프로토콜](https://docs.ag-ui.com)을 통해 연결됩니다. `ag-ui-crewai` 패키지는 어떤 Crew나 Flow든 AG-UI 엔드포인트로 노출합니다. CopilotKit의 React 훅과 컴포넌트가 그 엔드포인트를 소비합니다. 이를 통해 채팅 상자를 훨씬 뛰어넘는 경험이 열립니다:
<CardGroup cols={2}>
<Card title="Generative UI" icon="wand-magic-sparkles" href="/edge/en/guides/frontend/generative-ui">
에이전트 도구 호출과 상태를 여러분만의 React 컴포넌트로 렌더링하세요.
</Card>
<Card title="Human-in-the-Loop" icon="user-check" href="/edge/en/guides/frontend/human-in-the-loop">
실행 도중 사용자 승인이나 입력을 수집하기 위해 에이전트를 일시 중지하세요.
</Card>
<Card title="Shared State" icon="arrows-rotate" href="/edge/en/guides/frontend/shared-state">
에이전트 상태와 앱 UI를 양방향으로 동기화하세요.
</Card>
<Card title="Channels" icon="messages" href="/edge/ko/guides/frontend/channels">
동일한 에이전트를 Slack, Discord 또는 Teams 봇으로 실행하세요.
</Card>
</CardGroup>
이 가이드는 Crew 또는 Flow를 Next.js 프론트엔드와 처음부터 끝까지 연동시킵니다. 이 섹션의 나머지 내용은 여기서 설정한 앱을 기반으로 합니다.
## 아키텍처
세 가지 구성 요소가 있습니다:
1. **CrewAI 에이전트 서버** — AG-UI를 통해 Crew 또는 Flow를 제공하는 Python 프로세스(FastAPI + `ag-ui-crewai`).
2. **CopilotKit 런타임** — 에이전트를 등록하고 요청을 프록시하는 Next.js 라우트.
3. **React 프론트엔드** — `<CopilotKit>` 프로바이더와 채팅 및 generative-UI 컴포넌트.
```
React app ──► CopilotKit runtime (/api/copilotkit) ──► CrewAI server (AG-UI) ──► Crew / Flow
```
<Note>
이 가이드는 **셀프 호스팅** 경로를 다룹니다. `ag-ui-crewai`로 CrewAI 에이전트 서버를 직접 실행하며, 관리형 서비스 없이 로컬에서 동작합니다. CopilotKit은 호스팅된 스레드와 인스펙터를 갖춘 **관리형** 경로(CopilotKit Cloud / Enterprise Intelligence)도 제공합니다. 그 방식을 원한다면 [CopilotKit CrewAI 퀵스타트](https://docs.copilotkit.ai/crewai-crews/quickstart)를 참조하세요. 이 섹션의 프론트엔드 코드는 어느 쪽이든 동일합니다. 에이전트를 호스팅하고 등록하는 방식만 다릅니다.
</Note>
<Note>
CrewAI는 AG-UI 뒤에서 세 가지 형태로 실행됩니다: 일반 **Flows**(이 가이드 전반에서 사용), **[Conversational Flows](/edge/en/guides/frontend/conversational-flows)**(네이티브, 세션 인식, 턴 기반, 완전한 기능 동등성), 그리고 **Crews**(기본 채팅). 이 섹션의 프론트엔드는 이들 전반에서 동일합니다. 백엔드 작성과 등록만 다릅니다.
</Note>
## 통합 가이드
<Steps>
<Step title="AG-UI를 통해 에이전트 제공">
통합 패키지를 CrewAI 프로젝트에 설치하세요:
```bash
pip install ag-ui-crewai
```
FastAPI 앱에서 에이전트를 노출하세요. Flows는 `add_crewai_flow_fastapi_endpoint`를, Crews는 `add_crewai_crew_fastapi_endpoint`를 사용합니다. 원하는 만큼 등록할 수 있으며, 각각 자신의 경로에 배치됩니다.
<CodeGroup>
```python Flow
# server.py
from fastapi import FastAPI
from ag_ui_crewai.endpoint import add_crewai_flow_fastapi_endpoint
from my_agents.recipe_flow import RecipeFlow
app = FastAPI(title="CrewAI Agent Server")
add_crewai_flow_fastapi_endpoint(
app=app,
flow=RecipeFlow(),
path="/recipe",
)
```
```python Crew
# server.py
from fastapi import FastAPI
from ag_ui_crewai.endpoint import add_crewai_crew_fastapi_endpoint
from my_agents.research_crew import ResearchCrew
app = FastAPI(title="CrewAI Agent Server")
add_crewai_crew_fastapi_endpoint(
app=app,
crew=ResearchCrew().crew(),
path="/research",
)
```
</CodeGroup>
실행하세요:
```bash
uvicorn server:app --port 8000
```
<Note>
서버를 시작하기 전에 LLM 제공자를 위한 환경 변수(예: `OPENAI_API_KEY`)를 설정하세요.
</Note>
</Step>
<Step title="Next.js 앱 생성">
아직 프론트엔드가 없다면 하나를 스캐폴딩하세요:
```bash
npx create-next-app@latest my-app
cd my-app
```
CopilotKit과 CrewAI AG-UI 클라이언트를 설치하세요:
```bash
npm install @copilotkit/react-core @copilotkit/react-ui @copilotkit/runtime @ag-ui/crewai
```
</Step>
<Step title="CopilotKit 런타임 추가">
CrewAI 에이전트를 CopilotKit 런타임에 등록하는 라우트를 생성하세요. 각 에이전트는 `CrewAIAgent`를 통해 Python 서버의 경로를 가리킵니다.
```ts
// app/api/copilotkit/route.ts
import {
CopilotRuntime,
InMemoryAgentRunner,
createCopilotEndpoint,
} from "@copilotkit/runtime/v2";
import { CrewAIAgent } from "@ag-ui/crewai";
import { handle } from "hono/vercel";
const runtime = new CopilotRuntime({
agents: {
recipe: new CrewAIAgent({ url: "http://localhost:8000/recipe" }),
},
runner: new InMemoryAgentRunner(),
});
const app = createCopilotEndpoint({
runtime,
basePath: "/api/copilotkit",
});
const handler = handle(app);
export const GET = handler;
export const POST = handler;
```
</Step>
<Step title="프로바이더로 앱 감싸기">
`<CopilotKit>`을 런타임 라우트로 가리키고 등록한 에이전트의 이름을 지정하세요.
```tsx
// app/page.tsx
"use client";
import { CopilotKit } from "@copilotkit/react-core";
import { CopilotSidebar } from "@copilotkit/react-core/v2";
import "@copilotkit/react-core/v2/styles.css";
export default function Page() {
return (
<CopilotKit runtimeUrl="/api/copilotkit" agent="recipe">
<YourApp />
<CopilotSidebar agentId="recipe" labels={{ modalHeaderTitle: "Assistant" }} />
</CopilotKit>
);
}
```
</Step>
<Step title="실행">
두 프로세스를 모두 시작하고 앱을 여세요. 이제 사이드바에서 채팅하면 Crew 또는 Flow가 실행됩니다.
```bash
uvicorn server:app --port 8000 # terminal 1
npm run dev # terminal 2
```
</Step>
</Steps>
## 채팅 UI 옵션
CopilotKit은 서로 교체 가능한 세 가지 채팅 표면을 제공합니다. 컴포넌트만 바꾸면 되며, 연결 방식은 동일합니다.
<CodeGroup>
```tsx Sidebar
import { CopilotSidebar } from "@copilotkit/react-core/v2";
<CopilotSidebar agentId="recipe" />
```
```tsx Popup
import { CopilotPopup } from "@copilotkit/react-core/v2";
<CopilotPopup agentId="recipe" />
```
```tsx Inline
import { CopilotChat } from "@copilotkit/react-core/v2";
<CopilotChat agentId="recipe" />
```
</CodeGroup>
## 다음으로 갈 곳
<CardGroup cols={2}>
<Card title="Generative UI" icon="wand-magic-sparkles" href="/edge/en/guides/frontend/generative-ui">
도구 호출과 에이전트 상태를 커스텀 컴포넌트로 렌더링하세요.
</Card>
<Card title="Frontend Actions" icon="bolt" href="/edge/en/guides/frontend/frontend-actions">
에이전트가 브라우저에서 실행되는 함수를 호출하도록 하세요.
</Card>
<Card title="Human-in-the-Loop" icon="user-check" href="/edge/en/guides/frontend/human-in-the-loop">
에이전트 동작을 사용자 승인 뒤에 두세요.
</Card>
<Card title="Predictive State" icon="gauge-high" href="/edge/en/guides/frontend/predictive-state-updates">
에이전트가 작동하는 동안 진행 중인 상태를 UI로 스트리밍하세요.
</Card>
</CardGroup>

View File

@@ -141,7 +141,7 @@ OpenAI 호환 LLM에 연결하려면 환경 변수를 사용하거나 LLM 클래
# Gemini의 OpenAI 호환 API 예시입니다.
os.environ["OPENAI_API_KEY"] = "your-gemini-key" # AIza...로 시작해야 합니다.
os.environ["OPENAI_API_BASE"] = "https://generativelanguage.googleapis.com/v1beta/openai/"
os.environ["OPENAI_MODEL_NAME"] = "openai/gemini-2.0-flash" # Gemini 모델을 여기에 추가하세요. openai/ 하위에 위치.
os.environ["OPENAI_MODEL_NAME"] = "openai/gemini-3.7-flash" # Gemini 모델을 여기에 추가하세요. openai/ 하위에 위치.
```
</CodeGroup>
</Tab>
@@ -159,7 +159,7 @@ OpenAI 호환 LLM에 연결하려면 환경 변수를 사용하거나 LLM 클래
```python Google
# Gemini의 OpenAI 호환 API 예시
llm = LLM(
model="openai/gemini-2.0-flash",
model="openai/gemini-3.7-flash",
base_url="https://generativelanguage.googleapis.com/v1beta/openai/",
api_key="your-gemini-key", # AIza...로 시작해야 합니다.
)

View File

@@ -145,7 +145,7 @@ planning agent는 복잡한 전략적 사고와 다단계 분석을 처리할
from crewai import Agent, Task, Crew, LLM
# High-capability reasoning model for strategic planning
manager_llm = LLM(model="gemini-2.5-flash-preview-05-20", temperature=0.1)
manager_llm = LLM(model="gemini/gemini-3.7-flash", temperature=0.1)
# Creative model for content generation
content_llm = LLM(model="claude-3-5-sonnet-20241022", temperature=0.7)
@@ -411,7 +411,7 @@ tech_writer = Agent(
# Manager 또는 coordination agent
manager_agent = Agent(
role="Project Manager",
llm=LLM(model="gemini-2.5-flash-preview-05-20"), # 조율을 위한 프리미엄
llm=LLM(model="gemini/gemini-3.7-flash"), # 조율을 위한 프리미엄
# ... 나머지 설정
)

View File

@@ -9,7 +9,7 @@ mode: "wide"
CrewAI는 Crews와 Flows를 실시간으로 모니터링하고 디버깅할 수 있는 내장 추적 기능을 제공합니다. 이 가이드는 CrewAI의 통합 관측 가능성 플랫폼을 사용하여 **Crews**와 **Flows** 모두에 대한 추적을 활성화하는 방법을 보여줍니다.
> **CrewAI Tracing이란?** CrewAI의 내장 추적은 agent 결정, 작업 실행 타임라인, 도구 사용, LLM 호출을 포함한 AI agent에 대한 포괄적인 관측 가능성을 제공하며, 모두 [CrewAI AMP 플랫폼](https://app.crewai.com)을 통해 액세스할 수 있습니다.
> **CrewAI Tracing이란?** CrewAI의 내장 추적은 agent 결정, 작업 실행 타임라인, 도구 사용, LLM 호출을 포함한 AI agent에 대한 포괄적인 관측 가능성을 제공하며, 모두 [CrewAI AMP 플랫폼](https://app.crewai.com)을 통해 액세스할 수 있습니다. 추적은 [텔레메트리](/ko/telemetry)와 별도로 관리됩니다.
![CrewAI Tracing Interface](/images/crewai-tracing.png)
@@ -150,8 +150,8 @@ result = flow.kickoff()
### 5단계: CrewAI AMP 대시보드에서 추적 보기
crew 또는 flow를 실행한 후 CrewAI AMP 대시보드에서 CrewAI 애플리케이션이 생성한 추적을 볼 수 있습니다. agent 상호 작용, 도구 사용 및 LLM 호출의 세부 단계를 볼 수 있습니다.
아래 링크를 클릭하여 추적을 보거나 대시보드의 추적 탭으로 이동하세요 [여기](https://app.crewai.com/crewai_plus/trace_batches)
추적은 인증된 내보내기 또는 명시적으로 동의한 익명 업로드가 성공한 경우에만 업로드됩니다. 로컬 버퍼가 삭제된 실행에는 업로드된 추적이 없습니다.
계정에 연결된 추적은 [CrewAI AMP 대시보드의 Traces 탭](https://app.crewai.com/crewai_plus/trace_batches)에서 agent 상호 작용, 도구 사용 및 LLM 호출을 확인하세요.
![CrewAI Tracing Interface](/images/view-traces.png)
### 대안: 환경 변수 구성
@@ -170,6 +170,51 @@ CREWAI_TRACING_ENABLED=true
이 환경 변수가 설정되면 `tracing=True`를 명시적으로 설정하지 않아도 모든 Crews와 Flows에 자동으로 추적이 활성화됩니다.
## 첫 실행 후 추적 보기
Crew 또는 Flow를 처음 실행하면 대화형 터미널에서 다음을 물을 수 있습니다:
```text
Share this execution trace with CrewAI? [y/N]
```
버퍼에 저장된 추적을 CrewAI에 업로드하려면 **yes**를 선택하세요. 추적에는
프롬프트, 입력, 출력이 포함될 수 있습니다. 거절하거나 시간이 초과되거나
대화형 동의 프롬프트 없이 실행하면 버퍼가 삭제됩니다. 나중에
`crewai traces enable` 또는 `crewai traces disable`을 사용하거나 Crew 또는
Flow에서 `tracing`을 설정하여 추적 설정을 변경할 수 있습니다.
### 로컬 버퍼링 및 인증된 내보내기
첫 실행에서 수집한 추적은 저장된 로그인 자격 증명이 있어도 공유에 동의할
때까지 프로세스 메모리에 보관됩니다. 인증되지 않은 추적도 같은 동의 절차를
사용합니다. 동의하기 전에는 CrewAI가 업로드 권한을 요청하거나 실행 span을
전송하지 않습니다.
버퍼는 최대 **1,000개의 span**과 **8 MiB의 인코딩된 OTLP 데이터**를
보관합니다. `CREWAI_EPHEMERAL_TRACE_MAX_SPANS`와
`CREWAI_EPHEMERAL_TRACE_MAX_BYTES`를 양의 정수로 설정하여 한도를 조정할
수 있습니다. 한도를 초과하면 가장 오래된 span부터 삭제하며, 개별 span이
바이트 한도보다 크면 해당 span을 삭제합니다. 공유하거나 폐기한 후에는
버퍼를 비웁니다.
추적이 활성화되고 자격 증명을 사용할 수 있으면 CrewAI는 CLI 로그인,
`CREWAI_USER_PAT` 또는 플랫폼 통합 자격 증명을 AMP에서 실행별 권한으로
교환합니다. 그런 다음 해당 권한을 사용하여 OpenTelemetry span을 Wharf로
직접 내보냅니다. 유효하지 않은 자격 증명으로는 익명 업로드로 전환하지 않습니다.
### 호스팅된 실행 세션
호스트는 `crewai.telemetry.tracing`의 `telemetry_session`으로 실행을 감쌀
수 있습니다. 세션은 CrewAI 수명 주기 이벤트를 사용하여 span을 생성하고
종료하며 타임스탬프, 부모 관계, HITL 일시 중지/재개 링크를 유지합니다.
`providers=`에 기존 공급자를 전달하면 호스트의 tracer와 로깅 통합을
유지할 수 있습니다. `processors=`로 span 프로세서를 전달하고
`log_emitter=`로 호스트 로깅 콜백을 전달할 수 있습니다. 이러한 통합에서
데이터 마스킹은 호스트가 담당합니다.
각 세션은 자체 추적 수명 주기를 관리하며 애플리케이션의 전역
OpenTelemetry 공급자를 변경하지 않습니다.
## 추적 보기
### CrewAI AMP 대시보드 액세스
@@ -210,5 +255,5 @@ CrewAI 추적은 다음에 대한 포괄적인 가시성을 제공합니다:
1. Crew/Flow에서 `tracing=True`가 설정되어 있는지 확인하세요
2. 환경 변수를 사용하는 경우 `CREWAI_TRACING_ENABLED=true`인지 확인하세요
3. `crewai login`으로 인증되었는지 확인하세요
4. crew/flow가 실제로 실행되고 있는지 확인하세요
3. 인증된 내보내기의 경우 CLI 로그인, `CREWAI_USER_PAT` 또는 플랫폼 통합 자격 증명을 확인하세요. 익명으로 공유하려면 동의 프롬프트에서 명시적으로 동의하세요. 로그인은 필요하지 않습니다
4. crew/flow가 실행되었고 추적 내보내기가 성공했는지 확인하세요. 동의를 거절하거나 시간이 초과되거나 대화형 동의 프롬프트 없이 실행하면 로컬 버퍼가 업로드되지 않고 삭제됩니다

View File

@@ -22,7 +22,8 @@ CrewAI는 익명 텔레메트리를 활용하여 사용 통계를 수집하며,
`share_crew` 기능이 활성화되면, 보다 심층적인 통찰을 제공하기 위해 작업 설명, 에이전트의 배경 이야기나 목표, 기타 특정 속성 등 상세한 데이터가 수집됩니다.
이 확대된 데이터 수집에는 사용자가 crew나 작업에 개인정보를 포함한 경우, 개인정보가 포함될 수 있습니다.
사용자는 `share_crew`를 활성화하기 전에 crew와 작업의 내용을 신중하게 검토해야 합니다.
사용자는 환경 변수 `CREWAI_DISABLE_TELEMETRY`를 `true`로 설정하거나, `OTEL_SDK_DISABLED`를 `true`로 설정하여 텔레메트리를 비활성화할 수 있습니다(후자의 경우 전체 OpenTelemetry 계측이 전역에서 비활성화된다는 점에 유의하십시오).
사용자는 `CREWAI_DISABLE_TELEMETRY`를 `true`, `1`, `yes`, `on` 중 하나로 설정하여 CrewAI 텔레메트리를 비활성화할 수 있습니다(대소문자 무관). 같은 값의 `OTEL_SDK_DISABLED`도 CrewAI exporter를 끕니다. 프로세스 내 다른 OpenTelemetry 계측을 끄려면 OpenTelemetry SDK는 여전히 `true`만 인식합니다.
AMP 추적은 [Tracing](/ko/observability/tracing)에서 별도로 다룹니다.
### 예시:
```python
@@ -33,6 +34,8 @@ os.environ['CREWAI_DISABLE_TELEMETRY'] = 'true'
os.environ['OTEL_SDK_DISABLED'] = 'true'
```
`CREWAI_DISABLE_TELEMETRY=1`(`yes` / `on`도 동일)은 `true`와 같습니다. 인식되지 않는 값은 무시되며 텔레메트리는 켜진 채로 남습니다.
### 사용자 OpenTelemetry 설정과의 격리
CrewAI의 telemetry는 자체 전용 `TracerProvider`에서 실행되며 자신을 전역
@@ -58,8 +61,8 @@ provider로 등록하지 않습니다. 이를 통해 양방향이 분리됩니
| 예 | 작업 라이프사이클 데이터 | 생성 및 실행 시작/종료 시각, crew 및 작업 식별자, 그리고 작업의 성공 또는 실패 여부가 포함됩니다. 작업이 실패하면 실패를 집계하고 진단할 수 있도록 예외의 **클래스 이름**(예: `TimeoutError`)이 기록되며, 프롬프트·모델 출력·파일 경로·자격 증명이 포함될 수 있는 오류 메시지는 결코 기록되지 않습니다. 타임스탬프를 포함한 span으로 저장됩니다. 개인 정보 없음. |
| 예 | LLM 속성 | LLM의 이름, model_name, 모델, top_k, temperature 및 클래스명이 포함됩니다. 모두 기술적이고 비개인 정보입니다. |
| 예 | crewAI CLI를 통한 프로젝트 생성 | 포함 항목: `crewai create`로 새 프로젝트가 생성되었다는 사실, 그 종류(`crew`, `json_crew` 또는 `flow`), 그리고 그 새 프로젝트에 발급되어 해당 프로젝트의 `pyproject.toml`에 기록된 프로젝트 ID. 이는 새 프로젝트 자체의 ID이며, 명령을 실행한 디렉터리의 `project_id`와는 별개로 기록됩니다 — 두 값은 다를 수 있습니다. 프로젝트 이름, 파일 내용, 코드는 기록되지 않습니다. 개인 정보 없음. |
| 예 | crewAI CLI를 통한 Crew 배포 시도 | 포함 항목: 배포가 시도되고 있다는 사실과 crew id, 로그를 가져오려고 하는지 여부, 그리고 배포가 CLI 명령에서 시작되었는지 실행 TUI에서 시작되었는지 여부. 프로젝트나 crew의 내용은 기록되지 않습니다. 개인 정보 없음. |
| 예 | 실행 환경 | 포함: 프로세스를 실행 중인 AI 코딩 어시스턴트(있는 경우, `claude_code`, `codex`, `cursor`, `unknown` 등 고정 목록 중 하나), 프로세스가 실행되는 위치(`ci`, `container`, `serverless`, `interactive` 등 고정 목록 중 하나), 그리고 `pyproject.toml`에 설정된 경우 `project_id`. 감지는 알려진 환경 변수의 설정 여부만 확인하며 값은 읽지 않음. 개인 데이터 없음. |
| 예 | crewAI CLI를 통한 Crew 배포 시도 | 포함 항목: 배포가 시도되고 있다는 사실과 crew id, 로그를 가져오려고 하는지 여부, 그리고 배포가 CLI 명령에서 시작되었는지 실행 TUI에서 시작되었는지 여부. 배포 생성이 실패하면 실패 범주(`api_4xx`, `network_error`, `user_declined` 등 고정된 목록 중 하나)와 API 응답의 HTTP 상태 코드(있는 경우)가 기록되며, 오류 메시지는 절대 기록되지 않습니다. 프로젝트나 crew의 내용은 기록되지 않습니다. 개인 정보 없음. |
| 예 | 실행 환경 | 포함: 프로세스를 실행 중인 AI 코딩 어시스턴트(있는 경우, `claude_code`, `codex`, `cursor`, `unknown` 등 고정 목록 중 하나), 프로세스가 실행되는 위치(`ci`, `container`, `serverless`, `interactive` 등 고정 목록 중 하나), `pyproject.toml`에 설정된 경우 `project_id`, 그리고 머신 크기의 대략적인 구간(`1-2`, `3-4`, `5-8`, `9-16`, `17-32`, `33+`, `unknown` 중 하나). 구간은 범위이며 정확한 코어 수는 절대 포함하지 않습니다 — 정확한 코어 수는 아래 환경 정보에서 옵트인한 경우에만 수집됩니다. 크기 구간은 호스트 CPU 수에서 가져오며, 어시스턴트와 실행 위치 감지는 알려진 환경 변수의 설정 여부만 확인하고 값은 읽지 않음. 개인 데이터 없음. |
| 예 | Flow 라이프사이클 신호 | 포함 항목: flow의 시작, 완료 또는 실패 여부, 해당 메서드의 실패 여부, 사람의 입력이나 피드백을 위해 일시 중지되었는지 여부, 해당 시작이 재개된 실행이었는지 여부, 대화 턴의 실패 여부, flow 실행 시간, 그리고 해당 flow가 CrewAI가 내부적으로 실행하는 것인지 사용자가 작성한 것인지 여부. flow 이름은 flow 생성 및 실행에서와 마찬가지로 기록됩니다. flow 또는 해당 메서드가 실패하면 장애 진단을 위해 예외의 **클래스 이름**(예: `TimeoutError`)이 기록되며, 프롬프트·모델 출력·파일 경로·자격 증명이 포함될 수 있는 오류 메시지는 절대 기록되지 않습니다. 메서드 이름과 flow 상태는 절대 기록되지 않습니다. 개인 정보 없음. |
| 예 | 트레이스 공유 신호 | 포함 항목: 트레이스 배치가 CrewAI AMP에 성공적으로 공유되었는지 여부와, 익명으로(계정 생성 전) 공유되었는지 또는 계정에 연결되어 공유되었는지 여부. 모든 span과 마찬가지로 위에서 설명한 실행 환경 속성(구성된 경우 `project_id`, 코딩 어시스턴트, 런타임)도 함께 기록됩니다. 이 행은 공유 텔레메트리만 설명하며 — 트레이스 내용이나 공유된 트레이스 링크로 부여되는 접근 권한은 설명하지 않습니다. 트레이스 내용, 입력, 출력은 이 신호에는 기록되지 않습니다. 트레이스를 공유하기 전에 비밀 정보, 개인 데이터, AMP 편집 및 보존 설정을 검토하세요. |
| 아니오 | 에이전트 확장 데이터 | 목표 설명, 배경 이야기 텍스트, i18n 프롬프트 파일 식별자가 포함됩니다. 사용자들은 텍스트 필드에 개인 정보가 포함되지 않도록 해야 합니다. |

View File

@@ -48,17 +48,16 @@ mode: "wide"
- **AI 안전성**: 콘텐츠 모더레이션 및 안전성 점검 구현
```python
from crewai_tools import DallETool, VisionTool, CodeInterpreterTool
from crewai_tools import DallETool, VisionTool
# Create AI tools
image_generator = DallETool()
vision_processor = VisionTool()
code_executor = CodeInterpreterTool()
# Add to your agent
agent = Agent(
role="AI Specialist",
tools=[image_generator, vision_processor, code_executor],
tools=[image_generator, vision_processor],
goal="Create and analyze content using AI capabilities"
)
```

View File

@@ -1,6 +1,6 @@
---
title: RAG 도구
description: RagTool은 Retrieval-Augmented Generation을 사용하여 질문에 답변하는 동적 지식 기반 도구입니다.
description: `RagTool`은 Retrieval-Augmented Generation을 사용하여 질문에 답변하는 동적 지식 기반 도구입니다.
icon: vector-square
mode: "wide"
---
@@ -9,7 +9,7 @@ mode: "wide"
## 설명
`RagTool`은 EmbedChain을 통한 RAG(Retrieval-Augmented Generation)의 강력함을 활용하여 질문에 답하도록 설계되었습니다.
`RagTool`은 CrewAI의 네이티브 RAG 시스템을 통해 RAG(Retrieval-Augmented Generation)의 강력함을 활용하여 질문에 답하도록 설계되었습니다.
이는 다양한 데이터 소스에서 관련 정보를 검색할 수 있는 동적 지식 기반을 제공합니다.
이 도구는 방대한 정보에 접근해야 하고 맥락에 맞는 답변을 제공해야 하는 애플리케이션에 특히 유용합니다.
@@ -76,24 +76,24 @@ def knowledge_expert(self) -> Agent:
`RagTool`은 다음과 같은 매개변수를 허용합니다:
- **summarize**: 선택 사항. 검색된 콘텐츠를 요약할지 여부입니다. 기본값은 `False`입니다.
- **adapter**: 선택 사항. 지식 베이스에 대한 사용자 지정 어댑터입니다. 제공되지 않은 경우 EmbedchainAdapter가 사용됩니다.
- **config**: 선택 사항. 내부 EmbedChain App의 구성입니다.
- **adapter**: 선택 사항. 지식 기반을 위한 사용자 지정 어댑터입니다. 제공하지 않으면 CrewAIRagAdapter가 사용됩니다.
- **config**: 선택 사항. 내부 CrewAI RAG 시스템에 대한 구성입니다. 선택적 `embedding_model`(ProviderSpec) 및 `vectordb`(VectorDbConfig) 키를 포함하는 `RagToolConfig` TypedDict를 허용합니다. 프로그래밍 방식으로 제공된 모든 구성 값은 환경 변수보다 우선합니다.
## 콘텐츠 추가
`add` 메서드를 사용하여 지식 베이스에 콘텐츠를 추가할 수 있습니다:
```python Code
# PDF 파일 추가
# Add a PDF file
rag_tool.add(data_type="file", path="path/to/your/document.pdf")
# 웹 페이지 추가
# Add a web page
rag_tool.add(data_type="web_page", url="https://example.com")
# YouTube 비디오 추가
# Add a YouTube video
rag_tool.add(data_type="youtube_video", url="https://www.youtube.com/watch?v=VIDEO_ID")
# 파일이 있는 디렉터리 추가
# Add a directory of files
rag_tool.add(data_type="directory", path="path/to/your/directory")
```
@@ -123,51 +123,532 @@ def knowledge_expert(self) -> Agent:
## 고급 구성
`RagTool`의 동작을 구성 사전을 제공하여 사용자 지정할 수 있습니다.
구성 딕셔너리를 제공하여 `RagTool`의 동작을 사용자 지정할 수 있습니다.
```python Code
from crewai_tools import RagTool
from crewai_tools.tools.rag import RagToolConfig, VectorDbConfig, ProviderSpec
# 사용자 지정 구성으로 RAG 도구 생성
config = {
"app": {
"name": "custom_app",
},
"llm": {
"provider": "openai",
"config": {
"model": "gpt-4",
}
},
"embedding_model": {
"provider": "openai",
"config": {
"model": "text-embedding-ada-002"
}
},
"vectordb": {
"provider": "elasticsearch",
"config": {
"collection_name": "my-collection",
"cloud_id": "deployment-name:xxxx",
"api_key": "your-key",
"verify_certs": False
}
},
"chunker": {
"chunk_size": 400,
"chunk_overlap": 100,
"length_function": "len",
"min_chunk_size": 0
# Create a RAG tool with custom configuration
vectordb: VectorDbConfig = {
"provider": "qdrant",
"config": {
"collection_name": "my-collection"
}
}
embedding_model: ProviderSpec = {
"provider": "openai",
"config": {
"model_name": "text-embedding-3-small"
}
}
config: RagToolConfig = {
"vectordb": vectordb,
"embedding_model": embedding_model
}
rag_tool = RagTool(config=config, summarize=True)
```
내부 RAG 도구는 Embedchain 어댑터를 사용하므로 Embedchain에서 지원하는 모든 구성 옵션을 전달할 수 있습니다.
자세한 내용은 [Embedchain 문서](https://docs.embedchain.ai/components/introduction)를 참조하세요.
.yaml 파일에서 제공되는 구성 옵션을 반드시 검토하시기 바랍니다.
## 임베딩 모델 구성
`embedding_model` 매개변수는 다음 구조의 `crewai.rag.embeddings.types.ProviderSpec` 딕셔너리를 허용합니다.
```python
{
"provider": "provider-name", # Required
"config": { # Optional
# Provider-specific configuration
}
}
```
### 지원되는 프로바이더
<AccordionGroup>
<Accordion title="OpenAI">
```python main.py
from crewai.rag.embeddings.providers.openai.types import OpenAIProviderSpec
embedding_model: OpenAIProviderSpec = {
"provider": "openai",
"config": {
"api_key": "your-api-key",
"model_name": "text-embedding-ada-002",
"dimensions": 1536,
"organization_id": "your-org-id",
"api_base": "https://api.openai.com/v1",
"api_version": "v1",
"default_headers": {"Custom-Header": "value"}
}
}
```
**구성 옵션:**
- `api_key` (str): OpenAI API 키
- `model_name` (str): 사용할 모델. 기본값: `text-embedding-ada-002`. 옵션: `text-embedding-3-small`, `text-embedding-3-large`, `text-embedding-ada-002`
- `dimensions` (int): 임베딩 차원 수
- `organization_id` (str): OpenAI 조직 ID
- `api_base` (str): 사용자 지정 API 기본 URL
- `api_version` (str): API 버전
- `default_headers` (dict): API 요청을 위한 사용자 지정 헤더
**환경 변수:**
- `OPENAI_API_KEY` 또는 `EMBEDDINGS_OPENAI_API_KEY`: `api_key`
- `OPENAI_ORGANIZATION_ID` 또는 `EMBEDDINGS_OPENAI_ORGANIZATION_ID`: `organization_id`
- `OPENAI_MODEL_NAME` 또는 `EMBEDDINGS_OPENAI_MODEL_NAME`: `model_name`
- `OPENAI_API_BASE` 또는 `EMBEDDINGS_OPENAI_API_BASE`: `api_base`
- `OPENAI_API_VERSION` 또는 `EMBEDDINGS_OPENAI_API_VERSION`: `api_version`
- `OPENAI_DIMENSIONS` 또는 `EMBEDDINGS_OPENAI_DIMENSIONS`: `dimensions`
</Accordion>
<Accordion title="Cohere">
```python main.py
from crewai.rag.embeddings.providers.cohere.types import CohereProviderSpec
embedding_model: CohereProviderSpec = {
"provider": "cohere",
"config": {
"api_key": "your-api-key",
"model_name": "embed-english-v3.0"
}
}
```
**구성 옵션:**
- `api_key` (str): Cohere API 키
- `model_name` (str): 사용할 모델. 기본값: `large`. 옵션: `embed-english-v3.0`, `embed-multilingual-v3.0`, `large`, `small`
**환경 변수:**
- `COHERE_API_KEY` 또는 `EMBEDDINGS_COHERE_API_KEY`: `api_key`
- `EMBEDDINGS_COHERE_MODEL_NAME`: `model_name`
</Accordion>
<Accordion title="VoyageAI">
```python main.py
from crewai.rag.embeddings.providers.voyageai.types import VoyageAIProviderSpec
embedding_model: VoyageAIProviderSpec = {
"provider": "voyageai",
"config": {
"api_key": "your-api-key",
"model": "voyage-3",
"input_type": "document",
"truncation": True,
"output_dtype": "float32",
"output_dimension": 1024,
"max_retries": 3,
"timeout": 60.0
}
}
```
**구성 옵션:**
- `api_key` (str): VoyageAI API 키
- `model` (str): 사용할 모델. 기본값: `voyage-2`. 옵션: `voyage-3`, `voyage-3-lite`, `voyage-code-3`, `voyage-large-2`
- `input_type` (str): 입력 유형. 옵션: `document`(저장용), `query`(검색용)
- `truncation` (bool): 최대 길이를 초과하는 입력을 잘라낼지 여부. 기본값: `True`
- `output_dtype` (str): 출력 데이터 유형
- `output_dimension` (int): 출력 임베딩 차원
- `max_retries` (int): 최대 재시도 횟수. 기본값: `0`
- `timeout` (float): 요청 시간 제한(초)
**환경 변수:**
- `VOYAGEAI_API_KEY` 또는 `EMBEDDINGS_VOYAGEAI_API_KEY`: `api_key`
- `VOYAGEAI_MODEL` 또는 `EMBEDDINGS_VOYAGEAI_MODEL`: `model`
- `VOYAGEAI_INPUT_TYPE` 또는 `EMBEDDINGS_VOYAGEAI_INPUT_TYPE`: `input_type`
- `VOYAGEAI_TRUNCATION` 또는 `EMBEDDINGS_VOYAGEAI_TRUNCATION`: `truncation`
- `VOYAGEAI_OUTPUT_DTYPE` 또는 `EMBEDDINGS_VOYAGEAI_OUTPUT_DTYPE`: `output_dtype`
- `VOYAGEAI_OUTPUT_DIMENSION` 또는 `EMBEDDINGS_VOYAGEAI_OUTPUT_DIMENSION`: `output_dimension`
- `VOYAGEAI_MAX_RETRIES` 또는 `EMBEDDINGS_VOYAGEAI_MAX_RETRIES`: `max_retries`
- `VOYAGEAI_TIMEOUT` 또는 `EMBEDDINGS_VOYAGEAI_TIMEOUT`: `timeout`
</Accordion>
<Accordion title="Ollama">
```python main.py
from crewai.rag.embeddings.providers.ollama.types import OllamaProviderSpec
embedding_model: OllamaProviderSpec = {
"provider": "ollama",
"config": {
"model_name": "llama2",
"url": "http://localhost:11434/api/embeddings"
}
}
```
**구성 옵션:**
- `model_name` (str): Ollama 모델 이름(예: `llama2`, `mistral`, `nomic-embed-text`)
- `url` (str): Ollama API 엔드포인트 URL. 기본값: `http://localhost:11434/api/embeddings`
**환경 변수:**
- `OLLAMA_MODEL` 또는 `EMBEDDINGS_OLLAMA_MODEL`: `model_name`
- `OLLAMA_URL` 또는 `EMBEDDINGS_OLLAMA_URL`: `url`
</Accordion>
<Accordion title="Amazon Bedrock">
```python main.py
from crewai.rag.embeddings.providers.aws.types import BedrockProviderSpec
embedding_model: BedrockProviderSpec = {
"provider": "amazon-bedrock",
"config": {
"model_name": "amazon.titan-embed-text-v2:0",
"session": boto3_session
}
}
```
**구성 옵션:**
- `model_name` (str): Bedrock 모델 ID. 기본값: `amazon.titan-embed-text-v1`. 옵션: `amazon.titan-embed-text-v1`, `amazon.titan-embed-text-v2:0`, `cohere.embed-english-v3`, `cohere.embed-multilingual-v3`
- `session` (Any): AWS 인증을 위한 Boto3 세션 객체
**환경 변수:**
- `AWS_ACCESS_KEY_ID`: AWS 액세스 키
- `AWS_SECRET_ACCESS_KEY`: AWS 비밀 키
- `AWS_REGION`: AWS 리전(예: `us-east-1`)
</Accordion>
<Accordion title="Azure OpenAI">
```python main.py
from crewai.rag.embeddings.providers.microsoft.types import AzureProviderSpec
embedding_model: AzureProviderSpec = {
"provider": "azure",
"config": {
"deployment_id": "your-deployment-id",
"api_key": "your-api-key",
"api_base": "https://your-resource.openai.azure.com",
"api_version": "2024-02-01",
"model_name": "text-embedding-ada-002",
"api_type": "azure"
}
}
```
**구성 옵션:**
- `deployment_id` (str): **필수** - Azure OpenAI 배포 ID
- `api_key` (str): Azure OpenAI API 키
- `api_base` (str): Azure OpenAI 리소스 엔드포인트
- `api_version` (str): API 버전. 예: `2024-02-01`
- `model_name` (str): 모델 이름. 기본값: `text-embedding-ada-002`
- `api_type` (str): API 유형. 기본값: `azure`
- `dimensions` (int): 출력 차원
- `default_headers` (dict): 사용자 지정 헤더
**환경 변수:**
- `AZURE_OPENAI_API_KEY` 또는 `EMBEDDINGS_AZURE_API_KEY`: `api_key`
- `AZURE_OPENAI_ENDPOINT` 또는 `EMBEDDINGS_AZURE_API_BASE`: `api_base`
- `EMBEDDINGS_AZURE_DEPLOYMENT_ID`: `deployment_id`
- `EMBEDDINGS_AZURE_API_VERSION`: `api_version`
- `EMBEDDINGS_AZURE_MODEL_NAME`: `model_name`
- `EMBEDDINGS_AZURE_API_TYPE`: `api_type`
- `EMBEDDINGS_AZURE_DIMENSIONS`: `dimensions`
</Accordion>
<Accordion title="Google Generative AI">
```python main.py
from crewai.rag.embeddings.providers.google.types import GenerativeAiProviderSpec
embedding_model: GenerativeAiProviderSpec = {
"provider": "google-generativeai",
"config": {
"api_key": "your-api-key",
"model_name": "gemini-embedding-001",
"task_type": "RETRIEVAL_DOCUMENT"
}
}
```
**구성 옵션:**
- `api_key` (str): Google AI API 키
- `model_name` (str): 모델 이름. 기본값: `gemini-embedding-001`. 옵션: `gemini-embedding-001`, `text-embedding-005`, `text-multilingual-embedding-002`
- `task_type` (str): 임베딩 작업 유형. 기본값: `RETRIEVAL_DOCUMENT`. 옵션: `RETRIEVAL_DOCUMENT`, `RETRIEVAL_QUERY`
**환경 변수:**
- `GOOGLE_API_KEY`, `GEMINI_API_KEY` 또는 `EMBEDDINGS_GOOGLE_API_KEY`: `api_key`
- `EMBEDDINGS_GOOGLE_GENERATIVE_AI_MODEL_NAME`: `model_name`
- `EMBEDDINGS_GOOGLE_GENERATIVE_AI_TASK_TYPE`: `task_type`
</Accordion>
<Accordion title="Google Vertex AI">
```python main.py
from crewai.rag.embeddings.providers.google.types import VertexAIProviderSpec
embedding_model: VertexAIProviderSpec = {
"provider": "google-vertex",
"config": {
"model_name": "text-embedding-004",
"project_id": "your-project-id",
"region": "us-central1",
"api_key": "your-api-key"
}
}
```
**구성 옵션:**
- `model_name` (str): 모델 이름. 기본값: `textembedding-gecko`. 옵션: `text-embedding-004`, `textembedding-gecko`, `textembedding-gecko-multilingual`
- `project_id` (str): Google Cloud 프로젝트 ID. 기본값: `cloud-large-language-models`
- `region` (str): Google Cloud 리전. 기본값: `us-central1`
- `api_key` (str): 인증을 위한 API 키
**환경 변수:**
- `GOOGLE_APPLICATION_CREDENTIALS`: 서비스 계정 JSON 파일 경로
- `GOOGLE_CLOUD_PROJECT` 또는 `EMBEDDINGS_GOOGLE_VERTEX_PROJECT_ID`: `project_id`
- `EMBEDDINGS_GOOGLE_VERTEX_MODEL_NAME`: `model_name`
- `EMBEDDINGS_GOOGLE_VERTEX_REGION`: `region`
- `EMBEDDINGS_GOOGLE_VERTEX_API_KEY`: `api_key`
</Accordion>
<Accordion title="Jina AI">
```python main.py
from crewai.rag.embeddings.providers.jina.types import JinaProviderSpec
embedding_model: JinaProviderSpec = {
"provider": "jina",
"config": {
"api_key": "your-api-key",
"model_name": "jina-embeddings-v3"
}
}
```
**구성 옵션:**
- `api_key` (str): Jina AI API 키
- `model_name` (str): 모델 이름. 기본값: `jina-embeddings-v2-base-en`. 옵션: `jina-embeddings-v3`, `jina-embeddings-v2-base-en`, `jina-embeddings-v2-small-en`
**환경 변수:**
- `JINA_API_KEY` 또는 `EMBEDDINGS_JINA_API_KEY`: `api_key`
- `EMBEDDINGS_JINA_MODEL_NAME`: `model_name`
</Accordion>
<Accordion title="HuggingFace">
```python main.py
from crewai.rag.embeddings.providers.huggingface.types import HuggingFaceProviderSpec
embedding_model: HuggingFaceProviderSpec = {
"provider": "huggingface",
"config": {
"url": "https://api-inference.huggingface.co/models/sentence-transformers/all-MiniLM-L6-v2"
}
}
```
**구성 옵션:**
- `url` (str): HuggingFace 추론 API 엔드포인트의 전체 URL
**환경 변수:**
- `HUGGINGFACE_URL` 또는 `EMBEDDINGS_HUGGINGFACE_URL`: `url`
</Accordion>
<Accordion title="Instructor">
```python main.py
from crewai.rag.embeddings.providers.instructor.types import InstructorProviderSpec
embedding_model: InstructorProviderSpec = {
"provider": "instructor",
"config": {
"model_name": "hkunlp/instructor-xl",
"device": "cuda",
"instruction": "Represent the document"
}
}
```
**구성 옵션:**
- `model_name` (str): HuggingFace 모델 ID. 기본값: `hkunlp/instructor-base`. 옵션: `hkunlp/instructor-xl`, `hkunlp/instructor-large`, `hkunlp/instructor-base`
- `device` (str): 실행할 장치. 기본값: `cpu`. 옵션: `cpu`, `cuda`, `mps`, `xpu`
- `instruction` (str): 임베딩을 위한 명령어 접두사
**환경 변수:**
- `EMBEDDINGS_INSTRUCTOR_MODEL_NAME`: `model_name`
- `EMBEDDINGS_INSTRUCTOR_DEVICE`: `device`
- `EMBEDDINGS_INSTRUCTOR_INSTRUCTION`: `instruction`
</Accordion>
<Accordion title="Sentence Transformer">
```python main.py
from crewai.rag.embeddings.providers.sentence_transformer.types import SentenceTransformerProviderSpec
embedding_model: SentenceTransformerProviderSpec = {
"provider": "sentence-transformer",
"config": {
"model_name": "all-mpnet-base-v2",
"device": "cuda",
"normalize_embeddings": True
}
}
```
**구성 옵션:**
- `model_name` (str): Sentence Transformers 모델 이름. 기본값: `all-MiniLM-L6-v2`. 옵션: `all-mpnet-base-v2`, `all-MiniLM-L6-v2`, `paraphrase-multilingual-MiniLM-L12-v2`
- `device` (str): 실행할 장치. 기본값: `cpu`. 옵션: `cpu`, `cuda`, `mps`, `xpu`
- `normalize_embeddings` (bool): 임베딩을 정규화할지 여부. 기본값: `False`
**환경 변수:**
- `EMBEDDINGS_SENTENCE_TRANSFORMER_MODEL_NAME`: `model_name`
- `EMBEDDINGS_SENTENCE_TRANSFORMER_DEVICE`: `device`
- `EMBEDDINGS_SENTENCE_TRANSFORMER_NORMALIZE_EMBEDDINGS`: `normalize_embeddings`
</Accordion>
<Accordion title="ONNX">
```python main.py
from crewai.rag.embeddings.providers.onnx.types import ONNXProviderSpec
embedding_model: ONNXProviderSpec = {
"provider": "onnx",
"config": {
"preferred_providers": ["CUDAExecutionProvider", "CPUExecutionProvider"]
}
}
```
**구성 옵션:**
- `preferred_providers` (list[str]): 선호도 순으로 나열한 ONNX 실행 프로바이더 목록
**환경 변수:**
- `EMBEDDINGS_ONNX_PREFERRED_PROVIDERS`: `preferred_providers`(쉼표로 구분된 목록)
</Accordion>
<Accordion title="OpenCLIP">
```python main.py
from crewai.rag.embeddings.providers.openclip.types import OpenCLIPProviderSpec
embedding_model: OpenCLIPProviderSpec = {
"provider": "openclip",
"config": {
"model_name": "ViT-B-32",
"checkpoint": "laion2b_s34b_b79k",
"device": "cuda"
}
}
```
**구성 옵션:**
- `model_name` (str): OpenCLIP 모델 아키텍처. 기본값: `ViT-B-32`. 옵션: `ViT-B-32`, `ViT-B-16`, `ViT-L-14`
- `checkpoint` (str): 사전 학습된 체크포인트 이름. 기본값: `laion2b_s34b_b79k`. 옵션: `laion2b_s34b_b79k`, `laion400m_e32`, `openai`
- `device` (str): 실행할 장치. 기본값: `cpu`. 옵션: `cpu`, `cuda`
**환경 변수:**
- `EMBEDDINGS_OPENCLIP_MODEL_NAME`: `model_name`
- `EMBEDDINGS_OPENCLIP_CHECKPOINT`: `checkpoint`
- `EMBEDDINGS_OPENCLIP_DEVICE`: `device`
</Accordion>
<Accordion title="Text2Vec">
```python main.py
from crewai.rag.embeddings.providers.text2vec.types import Text2VecProviderSpec
embedding_model: Text2VecProviderSpec = {
"provider": "text2vec",
"config": {
"model_name": "shibing624/text2vec-base-multilingual"
}
}
```
**구성 옵션:**
- `model_name` (str): HuggingFace의 Text2Vec 모델 이름. 기본값: `shibing624/text2vec-base-chinese`. 옵션: `shibing624/text2vec-base-multilingual`, `shibing624/text2vec-base-chinese`
**환경 변수:**
- `EMBEDDINGS_TEXT2VEC_MODEL_NAME`: `model_name`
</Accordion>
<Accordion title="Roboflow">
```python main.py
from crewai.rag.embeddings.providers.roboflow.types import RoboflowProviderSpec
embedding_model: RoboflowProviderSpec = {
"provider": "roboflow",
"config": {
"api_key": "your-api-key",
"api_url": "https://infer.roboflow.com"
}
}
```
**구성 옵션:**
- `api_key` (str): Roboflow API 키. 기본값: `""`(빈 문자열)
- `api_url` (str): Roboflow 추론 API URL. 기본값: `https://infer.roboflow.com`
**환경 변수:**
- `ROBOFLOW_API_KEY` 또는 `EMBEDDINGS_ROBOFLOW_API_KEY`: `api_key`
- `ROBOFLOW_API_URL` 또는 `EMBEDDINGS_ROBOFLOW_API_URL`: `api_url`
</Accordion>
<Accordion title="WatsonX (IBM)">
```python main.py
from crewai.rag.embeddings.providers.ibm.types import WatsonXProviderSpec
embedding_model: WatsonXProviderSpec = {
"provider": "watsonx",
"config": {
"model_id": "ibm/slate-125m-english-rtrvr",
"url": "https://us-south.ml.cloud.ibm.com",
"api_key": "your-api-key",
"project_id": "your-project-id",
"batch_size": 100,
"concurrency_limit": 10,
"persistent_connection": True
}
}
```
**구성 옵션:**
- `model_id` (str): WatsonX 모델 식별자
- `url` (str): WatsonX API 엔드포인트
- `api_key` (str): IBM Cloud API 키
- `project_id` (str): WatsonX 프로젝트 ID
- `space_id` (str): WatsonX 공간 ID(project_id의 대안)
- `batch_size` (int): 임베딩 배치 크기. 기본값: `100`
- `concurrency_limit` (int): 최대 동시 요청 수. 기본값: `10`
- `persistent_connection` (bool): 지속 연결 사용 여부. 기본값: `True`
- 그 외 20개 이상의 추가 인증 및 구성 옵션
**환경 변수:**
- `WATSONX_API_KEY` 또는 `EMBEDDINGS_WATSONX_API_KEY`: `api_key`
- `WATSONX_URL` 또는 `EMBEDDINGS_WATSONX_URL`: `url`
- `WATSONX_PROJECT_ID` 또는 `EMBEDDINGS_WATSONX_PROJECT_ID`: `project_id`
- `EMBEDDINGS_WATSONX_MODEL_ID`: `model_id`
- `EMBEDDINGS_WATSONX_SPACE_ID`: `space_id`
- `EMBEDDINGS_WATSONX_BATCH_SIZE`: `batch_size`
- `EMBEDDINGS_WATSONX_CONCURRENCY_LIMIT`: `concurrency_limit`
- `EMBEDDINGS_WATSONX_PERSISTENT_CONNECTION`: `persistent_connection`
</Accordion>
<Accordion title="사용자 지정">
```python main.py
from crewai.rag.core.base_embeddings_callable import EmbeddingFunction
from crewai.rag.embeddings.providers.custom.types import CustomProviderSpec
class MyEmbeddingFunction(EmbeddingFunction):
def __call__(self, input):
# Your custom embedding logic
return embeddings
embedding_model: CustomProviderSpec = {
"provider": "custom",
"config": {
"embedding_callable": MyEmbeddingFunction
}
}
```
**구성 옵션:**
- `embedding_callable` (type[EmbeddingFunction]): 사용자 지정 임베딩 함수 클래스
**참고:** 사용자 지정 임베딩 함수는 `crewai.rag.core.base_embeddings_callable`에 정의된 `EmbeddingFunction` 프로토콜을 구현해야 합니다. `__call__` 메서드는 입력 데이터를 받아 numpy 배열 목록(또는 정규화할 수 있는 호환 형식)으로 임베딩을 반환해야 합니다. 반환된 임베딩은 자동으로 정규화되고 검증됩니다.
</Accordion>
</AccordionGroup>
### 참고
- **필수**로 표시되지 않은 모든 구성 필드는 선택 사항입니다.
- 일반적으로 API 키는 구성 대신 환경 변수를 통해 제공할 수 있습니다.
- 해당하는 경우 기본값이 표시됩니다.
## 결론
`RagTool`은 다양한 데이터 소스에서 지식 베이스를 생성하고 질의할 수 있는 강력한 방법을 제공합니다. Retrieval-Augmented Generation을 활용하여, 에이전트가 관련 정보를 효율적으로 접근하고 검색할 수 있게 하여, 보다 정확하고 상황에 맞는 응답을 제공하는 능력을 향상시킵니다.

View File

@@ -12,6 +12,16 @@ mode: "wide"
이 도구는 이미지에서 텍스트를 추출하는 데 사용됩니다. 에이전트에 전달되면 이미지에서 텍스트를 추출한 후 이를 사용하여 응답, 보고서 또는 기타 출력을 생성합니다.
이미지의 URL 또는 경로(PATH)를 에이전트에 전달해야 합니다.
이미지에 대한 사용자 지정 `query`를 요청하고, 요청에 가장 적합한 모델을 자동으로 선택하는 `complexity_level`을 지정할 수도 있습니다:
| 복잡도 수준 | 모델 |
| :--------------- | :------------ |
| `easy` | `gpt-5.6-luna` |
| `medium` (기본값) | `gpt-5.6-terra` |
| `hard` | `gpt-5.6-sol` |
도구에 명시적인 `llm` 또는 `model`을 제공하면, 복잡도 기반 모델 선택보다 우선합니다.
## 설치
crewai_tools 패키지를 설치하세요
@@ -43,8 +53,10 @@ def researcher(self) -> Agent:
## 인수
VisionTool은 다음과 같은 인수가 필요합니다:
VisionTool은 다음과 같은 인수를 받습니다:
| 인수 | 타입 | 설명 |
| :------------------ | :------- | :-------------------------------------------------------------------------------- |
| **image_path_url** | `string` | **필수**. 텍스트를 추출해야 하는 이미지 파일의 경로입니다. |
| **image_path_url** | `string` | **필수**. 텍스트를 추출해야 하는 이미지 파일의 경로(또는 URL)입니다. |
| **query** | `string` | **선택**. 이미지에 대해 모델에 묻는 질문 또는 지시입니다. 기본값은 `"What's in this image?"`입니다. |
| **complexity_level** | `string` | **선택**. 모델을 선택하는 요청의 복잡도입니다: `easy`, `medium`, `hard`. 기본값은 `medium`입니다. |

View File

@@ -4,7 +4,7 @@ description: >
Oxylabs 스크래퍼를 사용하면 해당 소스에서 정보를 쉽게 접근할 수 있습니다. 아래에서 사용 가능한 소스 목록을 확인하세요:
- `Amazon Product`
- `Amazon Search`
- `Google Seach`
- `Google Search`
- `Universal`
icon: globe
mode: "wide"
@@ -87,7 +87,7 @@ print(result)
### 파라미터
- `query` - Amazon 검색어.
- `domain` - Bestbuy의 도메인 로컬라이제이션.
- `domain` - Amazon의 도메인 로컬라이제이션.
- `start_page` - 시작 페이지 번호.
- `pages` - 가져올 페이지 수.
- `geo_location` - _배송지_ 위치.

View File

@@ -4,6 +4,145 @@ description: "Atualizações de produto, melhorias e correções do CrewAI"
icon: "clock"
mode: "wide"
---
<Update label="16 set 2026">
## v1.15.22
[Ver release no GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.15.22)
## O que mudou
### Recursos
- Suporte a aliases como identificadores de conexão
- Registrar razões para falhas na criação de implantações
- Coletar feedback humano e pausar eventos em rastreamento
- Adicionar variável de contexto `llm_overlay` para direcionar papéis de agentes a modelos
- Transportar `task_prompt` e saída nos payloads de execução de agentes
- Validar integrações de plataforma durante a configuração da equipe
- Adicionar ferramentas de plataforma ao assistente JSON da equipe
- Expor o catálogo de aplicações da CrewAI Platform
- Adicionar OpenRouter como um provedor de embedding suportado
### Correções de Bugs
- Aceitar CRLF nas definições de habilidades inline
- Carregar URLs de arquivos de texto através do fetcher seguro
- Fechar conexões SQLite no armazenamento de saídas da tarefa de início
- Transportar `from_cache` no `ToolUsageFinishedEvent` do caminho da ferramenta nativa
- Levantar `ValueError` em vez de uma elevação genérica no uploader
- Suportar tipos não primitivos na SQLiteFlowPersistence
- Melhorar as instruções para agentes de codificação
- Ler pontos de verificação JSON como UTF-8
- Sobrescrever backup obsoleto de `poetry.lock` no Windows
- Chavear chamadas de ferramentas transmitidas por índice de fio no Azure
- Preservar partes do conteúdo dos dados do arquivo no Gemini
- Honrar `read_only` nos tempos de acesso de `update()` e `recall()`
- Enviar `reasoning_effort` para cada modelo de raciocínio da OpenAI
- Prevenir falhas na TUI de execução quando a saída transmitida contém um literal `[...]`
- Rejeitar replay quando as tarefas armazenadas diferem
- Usar guardas `sys.platform` para compatibilidade com mypy no Windows
- Solicitar a resposta final forçada como uma ação do usuário
- Manter nulo no esquema de saída da tarefa incorporado no prompt
- Alinhar `DOCXSearchTool` com o padrão de esquema fixo RAG padrão
### Documentação
- Adicionar `xpu` às opções de dispositivo de embedding
- Listar todos os pacotes do workspace
## Contribuidores
@ASTion24, @BlueX888, @HUAN2022A, @RaycarlLei, @Rohitkanithi, @SWAPI03, @SharoonSharif, @ShivangiRay, @Theater-ahyeon, @Vidit-Ostwal, @gamal1osama, @github-actions[bot], @joaomdmoura, @lorenzejay, @mhbuehler, @modusensus, @monkscode, @rohitkanithi, @roli-lpci, @vinibrsl, @wangtaotaotao95
</Update>
<Update label="09 set 2026">
## v1.15.21
[Ver release no GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.15.21)
## O que Mudou
### Recursos
- Adicionar telemetria para rastrear o tempo de execução de checkpoints e o uso do CLI.
### Correções de Bugs
- Corrigir erros de gateway relatados dentro de uma resposta HTTP 200.
- Manter o deploy push na criação de fonte AMP.
- Relatar falhas de raspagem em vez de levantar IndexError na integração com Oxylabs.
- Roteirizar todos os modelos DashScope através do provedor nativo.
- Persistir checkpoints JSON como UTF-8.
- Remover $ soltos nas URLs de busca de f-string para BrightData.
- Suportar arrays do tipo lista na conversão de esquema JSON.
- Corrigir a janela de contexto do gpt-4o-mini de 200000 para 128000.
- Preservar os argumentos de chamada da ferramenta de streaming em contentBlockStop.
- Tornar os hooks de pré-compromisso portáteis no Windows.
### Documentação
- Esclarecer que o rastreamento é gerenciado separadamente da telemetria.
- Corrigir o link de referência de busca paralela.
- Remover parâmetros obsoletos da docstring de handle_llm_stream_chunk.
- Corrigir exemplos de docstring de saída de streaming.
- Usar UUIDs de organização na referência de instalação de habilidades.
## Contribuidores
@Alphaxiaoteng, @DrewWhittleNZ, @Ghraven, @Shxiao101, @Vaishnavi220506, @Vidit-Ostwal, @danielfsbarreto, @georgeatparallel, @github-actions[bot], @jessemiller, @joaomdmoura, @kimnamu, @kiwoongyoon, @liang0417, @lorenzejay, @oxy-giedrius, @simpleqt, @uoparaji
</Update>
<Update label="04 set 2026">
## v1.15.20
[Ver release no GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.15.20)
## O que Mudou
### Correções de Bugs
- Corrigir a descoberta de alias da ferramenta da plataforma legada
### Documentação
- Atualizar snapshot e changelog para v1.15.19
## Contribuidores
@joaomdmoura, @vinibrsl
</Update>
<Update label="04 set 2026">
## v1.15.19
[Ver release no GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.15.19)
## O que Mudou
### Recursos
- Adicionar cliente de integrações Clipper
- Adicionar `now()` ao ambiente de expressão CEL
- Registrar como uma execução de equipe terminou para cada usuário
- Relatar o tamanho da máquina como uma faixa grosseira, não uma contagem de núcleos
- Adicionar cliente injetável para ferramentas da plataforma CrewAI
### Correções de Bugs
- Corrigir leitura de URLs de octet-stream e xlsx em `urlreadtool`
- Corrigir a adição de turno de usuário final em provedor nativo Gemini
- Normalizar esquema e porta na URL base do Ollama
- Preservar configurações de escopo reutilizáveis na memória
- Atualizar `pypdf` para 6.16.2 devido a vulnerabilidade de segurança
- Atualizar `nltk` para 3.10.3 devido a vulnerabilidade de segurança
- Corrigir saídas estruturadas nativas para os modelos atuais do Claude e piso CVE do Snowflake
- Executar ganchos de chamada de modelo em cada caminho e propagar uma negação
### Documentação
- Remover `CodeInterpreterTool` dos exemplos de visão geral de IA/ML
- Apontar o link `prompt-template` para seu caminho atual
- Atualizar guia de canais para a API atual de canais do CopilotKit
- Atualizar IDs de modelos Gemini aposentados
## Contribuidores
@Vidit-Ostwal, @a-yeyang, @github-actions[bot], @hvlcrs, @joaomdmoura, @kikifrost, @lorenzejay, @lucasgomide, @parthiban-sivakumar, @ranst91, @tandede, @thiagomoretto, @vinibrsl
</Update>
<Update label="27 ago 2026">
## v1.15.18

View File

@@ -307,6 +307,7 @@ crewai org switch <organization_id>
- Inicia o processo de deployment na plataforma CrewAI AMP.
- Após a iniciação bem-sucedida, será exibida a mensagem Deployment created successfully! juntamente com o Nome do Deployment e um Deployment ID (UUID) único.
- O push mantém a origem usada na criação. Adicionar um `origin` git depois não troca um deployment ZIP por git.
- **Status do Deployment**: Você pode verificar o status do seu deployment com:

View File

@@ -601,6 +601,21 @@ agent = Agent(
}
}
)
# Option 4: Use OpenRouter embeddings (supports models across providers)
# Set OPENROUTER_API_KEY environment variable if api_key is omitted in config
crew = Crew(
agents=[agent],
tasks=[...],
knowledge_sources=[knowledge_source],
embedder={
"provider": "openrouter",
"config": {
"model_name": "openai/text-embedding-3-small",
"api_key": "your-openrouter-api-key" # Optional if OPENROUTER_API_KEY is set
}
}
)
```
#### Configurando Embeddings do Azure OpenAI

View File

@@ -919,6 +919,38 @@ Saiba como obter o máximo da configuração do seu LLM:
llm = LLM(model="gpt-4")
```
</Tab>
<Tab title="Erros de Gateway">
<Tip>
Gateways como o OpenRouter retornam `200 OK` assim que o provedor upstream aceita a requisição, então um timeout do provedor chega no corpo da resposta em vez do código de status.
</Tip>
O CrewAI lança a mesma exceção que o código upstream produziria como um status HTTP real, portanto uma falha mascarada é capturada pelo tratamento de retry que você já possui:
```python
import openai
from pydantic import BaseModel
from crewai import LLM
class Report(BaseModel):
summary: str
llm = LLM(model="openrouter/z-ai/glm-5.3", response_format=Report)
try:
result = llm.call("Summarize the incident", response_model=Report)
except openai.InternalServerError as e:
# "z-ai/glm-5.3 via openrouter.ai returned HTTP 200 with an upstream error
# and no choices: The operation was aborted (upstream code 504)"
print(f"Upstream provider failed, safe to retry: {e}")
```
<Warning>
Um `response_model` grande ou profundamente aninhado aumenta a chance de timeouts upstream. Trate esses casos como falhas transitórias do provedor, e não como o modelo produzindo saída estruturada malformada.
</Warning>
</Tab>
<Tab title="Comprimento do Contexto">
<Tip>
Use modelos de contexto expandido para tarefas extensas

View File

@@ -736,7 +736,7 @@ memory = Memory(llm="anthropic/claude-3-haiku-20240307")
memory = Memory(llm="ollama/llama3.2")
# Usar Google Gemini
memory = Memory(llm="gemini/gemini-2.0-flash")
memory = Memory(llm="gemini/gemini-3.7-flash")
# Passar uma instância LLM pré-configurada com configurações customizadas
llm = LLM(model="gpt-4o", temperature=0)

View File

@@ -202,13 +202,17 @@ A publicação lê `name`, `description` e `metadata.version` do frontmatter do
### Instalar
Instale uma skill publicada pela sua referência `@org/name`:
Instale uma skill publicada pela sua referência `@org-uuid/name`:
```shell Terminal
crewai skill install @acme/code-review
crewai skill install @your-org-uuid/code-review
```
Dentro de um projeto de crew, a skill é colocada em `./skills/{name}/`; fora de um projeto, vai para o cache compartilhado em `~/.crewai/skills/{org}/{name}/`.
<Note>
Use o **UUID** da sua organização, não o nome — nomes de organização não são únicos, então um nome pode resolver para a organização errada e a instalação falha com um erro de "não encontrado". Execute `crewai org list` para ver o UUID (a coluna `ID`) de cada organização à qual você pertence.
</Note>
Dentro de um projeto de crew, a skill é colocada em `./skills/{name}/`; fora de um projeto, vai para o cache compartilhado em `~/.crewai/skills/{org-uuid}/{name}/`.
Agentes também podem referenciar skills do registro diretamente — elas são resolvidas a partir do cache local (ou do diretório `skills/` do projeto) em tempo de execução:
@@ -217,7 +221,7 @@ agent = Agent(
role="Senior Code Reviewer",
goal="Review pull requests for quality and security issues",
backstory="Staff engineer with expertise in secure coding practices.",
skills=["@acme/code-review"], # registry ref, resolved locally
skills=["@your-org-uuid/code-review"], # registry ref, resolved locally
)
```

View File

@@ -26,7 +26,7 @@ Nos bastidores, o CrewAI adota um sistema de prompt modular que pode ser amplame
- **Tratamento de erros** – Definem como os agentes respondem a falhas, exceções ou timeouts.
- **Prompts específicos de ferramentas** – Definem instruções detalhadas para como as ferramentas são invocadas ou utilizadas.
Confira os [templates de prompt originais no repositório do CrewAI](https://github.com/crewAIInc/crewAI/blob/main/src/crewai/translations/en.json) para ver como esses elementos são organizados. A partir daí, você pode sobrescrever ou adaptar conforme necessário para desbloquear comportamentos avançados.
Confira os [templates de prompt originais no repositório do CrewAI](https://github.com/crewAIInc/crewAI/blob/main/lib/crewai/src/crewai/translations/en.json) para ver como esses elementos são organizados. A partir daí, você pode sobrescrever ou adaptar conforme necessário para desbloquear comportamentos avançados.
## Entendendo as Instruções de Sistema Padrão

View File

@@ -11,7 +11,7 @@ mode: "wide"
## Criar um Projeto com o CLI
Use o CLI do CrewAI para criar a estrutura de um projeto, e o `AGENTS.md` será automaticamente adicionado na raiz.
Use o CLI do CrewAI para criar a estrutura de um projeto. O `AGENTS.md` é adicionado na raiz, junto com um `CLAUDE.md` e um `GEMINI.md` que o importam, para que o Claude Code e o Gemini CLI leiam a mesma orientação que todos os outros assistentes.
```bash
# Crew
@@ -32,24 +32,28 @@ O Codex pode ser guiado por arquivos `AGENTS.md` colocados no seu repositório.
### Claude Code
O Claude Code armazena a memória do projeto em `CLAUDE.md`. Você pode inicializá-lo com `/init` e editá-lo usando `/memory`. O Claude Code também suporta importações dentro do `CLAUDE.md`, então você pode adicionar uma única linha como `@AGENTS.md` para incluir as instruções compartilhadas sem duplicá-las.
O Claude Code lê o `CLAUDE.md` e ignora o `AGENTS.md`. Projetos gerados pelo CLI já incluem um `CLAUDE.md` cuja única instrução é a linha de importação `@AGENTS.md`, para que a orientação compartilhada seja carregada sem duplicação. Adicione notas específicas do Claude abaixo dessa linha e mantenha as convenções compartilhadas no `AGENTS.md`.
Você pode simplesmente usar:
Para um projeto criado antes de o `CLAUDE.md` passar a ser gerado, adicione a importação você mesmo:
```bash
mv AGENTS.md CLAUDE.md
printf '@AGENTS.md\n' > CLAUDE.md
```
Não renomeie o `AGENTS.md` para `CLAUDE.md`: o Codex e o Cursor leem o `AGENTS.md`, e a renomeação o esconde deles.
### Gemini CLI e Google Antigravity
O Gemini CLI e o Antigravity carregam um arquivo de contexto do projeto (padrão: `GEMINI.md`) da raiz do repositório e diretórios pais. Você pode configurá-lo para ler o `AGENTS.md` em vez disso (ou além) definindo `context.fileName` nas configurações do Gemini CLI. Por exemplo, defina apenas para `AGENTS.md`, ou inclua tanto `AGENTS.md` quanto `GEMINI.md` se quiser manter o formato de cada ferramenta.
O Gemini CLI e o Antigravity carregam um arquivo de contexto do projeto (padrão: `GEMINI.md`) da raiz do repositório e diretórios pais. Projetos gerados pelo CLI já incluem um `GEMINI.md` cuja única instrução é a linha de importação `@./AGENTS.md`, para que a orientação compartilhada seja carregada sem duplicação. Adicione notas específicas do Gemini abaixo dessa linha e mantenha as convenções compartilhadas no `AGENTS.md`.
Você pode simplesmente usar:
Para um projeto criado antes de o `GEMINI.md` passar a ser gerado, adicione a importação você mesmo:
```bash
mv AGENTS.md GEMINI.md
printf '@./AGENTS.md\n' > GEMINI.md
```
Como alternativa, defina `context.fileName` nas configurações do Gemini CLI para incluir o `AGENTS.md` e o Gemini o lerá diretamente. Não renomeie o `AGENTS.md` para `GEMINI.md`: o Codex e o Cursor leem o `AGENTS.md`, e a renomeação o esconde deles.
### Cursor
O Cursor suporta `AGENTS.md` como arquivo de instruções do projeto. Coloque-o na raiz do projeto para fornecer orientação ao assistente de codificação do Cursor.

View File

@@ -77,7 +77,7 @@ Substitua o arquivo gerado `agents/researcher.jsonc` e adicione `agents/analyst.
}
```
Substitua `provider/model-id` pelo modelo usado, como `openai/gpt-4o`, `anthropic/claude-sonnet-4-6` ou `gemini/gemini-2.0-flash-001`.
Substitua `provider/model-id` pelo modelo usado, como `openai/gpt-4o`, `anthropic/claude-sonnet-4-6` ou `gemini/gemini-3.7-flash`.
## Etapa 3: Definir tarefas e configurações

View File

@@ -135,7 +135,7 @@ Agora, vamos configurar o crew de redatores com JSONC. Vamos definir dois agente
}
```
Substitua `provider/model-id` pelo modelo que você usa, como `openai/gpt-4o`, `gemini/gemini-2.0-flash-001` ou `anthropic/claude-sonnet-4-6`.
Substitua `provider/model-id` pelo modelo que você usa, como `openai/gpt-4o`, `gemini/gemini-3.7-flash` ou `anthropic/claude-sonnet-4-6`.
3. Crie `src/guide_creator_flow/crews/content_crew/crew.jsonc`:
@@ -481,7 +481,7 @@ Flows permitem que você faça chamadas diretas a modelos de linguagem quando pr
```python
llm = LLM(
model="model-id-here", # gpt-4o, gemini-2.0-flash, anthropic/claude...
model="model-id-here", # gpt-4o, gemini/gemini-3.7-flash, anthropic/claude...
response_format=GuideOutline
)
response = llm.call(messages=messages)

View File

@@ -0,0 +1,156 @@
---
title: Channels
description: Execute o mesmo agente CrewAI como um bot do Slack ou Teams com o Channels SDK do CopilotKit e a plataforma gerenciada Intelligence.
icon: messages
mode: "wide"
---
## Encontre seus usuários onde eles já estão
O agente CrewAI que você construiu na [Visão geral](/edge/pt-BR/guides/frontend/overview) não precisa viver por trás de um web app. O mesmo Crew ou Flow pode rodar como um bot dentro de uma plataforma de mensagens. Sem reconstruir, sem uma segunda cópia da lógica do seu agente: o agente permanece exposto pelo [protocolo AG-UI](https://docs.ag-ui.com), e um **channel** o aciona a partir do Slack ou do Microsoft Teams.
O [Channels SDK](https://docs.copilotkit.ai/slack) do CopilotKit fornece esse channel. Você declara um `createChannel` em um pequeno runtime, aponta-o para o seu agente CrewAI, e a plataforma gerenciada **Intelligence** do CopilotKit intermedia a conexão com o provedor de mensagens.
<Note>
Diferentemente do restante desta seção, Channels **não é self-hosted**. Ele roda através do **CopilotKit Intelligence** — uma superfície obrigatória para Channels, por design (há um plano gratuito disponível). O Intelligence detém a conexão com a plataforma e as credenciais, recebe cada evento da plataforma e entrega o turno ao processo do seu channel; seu processo executa o agente e transmite a resposta de volta. Você configura o Slack uma vez no painel do Intelligence, e as credenciais da plataforma nunca entram no seu processo. Seu agente, suas tools e seu estado continuam sendo seus.
</Note>
## Como tudo se encaixa
Nada muda no servidor do seu agente CrewAI. Ele continua servindo o seu Crew ou Flow por AG-UI exatamente como na Visão geral. O que você adiciona é um processo Node separado, de longa duração, construído com `@copilotkit/channels`: ele registra um channel no `CopilotRuntime`, conecta-se ao Intelligence e executa o seu agente sempre que chega uma mensagem.
```
Slack / Teams ──► CopilotKit Intelligence ──► channel process (Node) ──► CrewAI server (AG-UI) ──► Crew / Flow
```
O processo do channel mantém uma conexão persistente com o gateway do Intelligence, então ele precisa de um host de longa duração — um handler de requisições serverless não consegue ser dono dessa conexão. Seu servidor CrewAI pode continuar servindo o frontend web da Visão geral ao mesmo tempo: o web app e o channel são apenas dois clientes de um único endpoint AG-UI.
## Guia de integração
<Steps>
<Step title="Instale os pacotes do Channels">
O Channels SDK vem com tudo incluído — cada plataforma é entregue no mesmo pacote, sem nenhum adaptador por plataforma para instalar. Adicione-o junto ao runtime que hospeda o channel e ao cliente AG-UI do CrewAI:
```bash
npm install @copilotkit/channels @copilotkit/runtime @ag-ui/crewai
```
</Step>
<Step title="Crie um Channel no Intelligence">
No [painel do CopilotKit](https://docs.copilotkit.ai/slack), crie um Channel e conecte o Slack — o Intelligence guia você na criação do app do Slack e detém suas credenciais. Isso deixa duas variáveis de ambiente para o seu processo, ambas vindas do painel:
```bash
export INTELLIGENCE_API_KEY=... # authenticates the runtime with Intelligence (free tier available)
export INTELLIGENCE_CHANNEL_ID=... # the Channel ID, matched by createChannel({ name })
```
</Step>
<Step title="Defina o channel">
`createChannel` declara o channel e anexa o seu agente. Construa o agente como uma factory por thread, para que cada conversa ganhe sua própria sessão, usando o mesmo `CrewAIAgent` que a Visão geral usa no runtime web, apontado para o seu endpoint AG-UI. `identifyUser: "platform"` permite que o Intelligence mapeie cada usuário da plataforma para uma identidade estável.
```ts
// channel.ts
import { createChannel } from "@copilotkit/channels";
import { CrewAIAgent } from "@ag-ui/crewai";
const channel = createChannel({
name: process.env.INTELLIGENCE_CHANNEL_ID!, // must match the Channel ID in Intelligence
identifyUser: "platform",
// A fresh agent per conversation, pointed at your CrewAI AG-UI endpoint.
agent: (threadId) => {
const agent = new CrewAIAgent({ url: "http://localhost:8000/recipe" });
agent.threadId = threadId;
return agent;
},
});
// A mention subscribes the thread and runs the agent; afterwards every message
// in a subscribed thread runs it without needing another mention.
channel.onMention(async ({ thread }) => {
await thread.subscribe();
await thread.runAgent();
});
channel.onMessage(async ({ thread }) => {
if (await thread.isSubscribed()) await thread.runAgent();
});
export { channel };
```
</Step>
<Step title="Registre o channel no runtime">
Crie um `CopilotRuntime` com o gateway do Intelligence e o seu channel, e então sirva-o com `createCopilotNodeListener`. O mapa `agents` permanece vazio — o channel fornece seu próprio agente. Aguarde o channel ficar pronto, para que uma configuração quebrada faça a inicialização falhar de forma visível.
```ts
// server.ts
import { createServer } from "node:http";
import { CopilotRuntime, CopilotKitIntelligence } from "@copilotkit/runtime/v2";
import { createCopilotNodeListener } from "@copilotkit/runtime/v2/node";
import { channel } from "./channel";
const runtime = new CopilotRuntime({
agents: {}, // the channel supplies its own agent; no web-facing agents needed
intelligence: new CopilotKitIntelligence({
apiKey: process.env.INTELLIGENCE_API_KEY!, // free tier available
}),
channels: [channel],
});
const listener = createCopilotNodeListener({ runtime });
await listener.channels?.ready({ timeoutMs: 15_000 });
createServer(listener).listen(3123, () => {
console.log("Channels runtime listening on port 3123");
});
```
</Step>
<Step title="Execute o runtime do channel">
Inicie-o junto ao servidor do seu agente CrewAI:
```bash
uvicorn server:app --port 8000 # terminal 1 — CrewAI agent server
npx tsx server.ts # terminal 2 — Channels runtime
```
Mencione o bot no Slack ou no Teams e ele executa o seu Crew ou Flow, transmitindo a resposta de volta para a thread. A thread permanece inscrita, então mensagens de acompanhamento rodam sem outra menção.
</Step>
</Steps>
## O modelo de eventos
Um channel reage a eventos da plataforma com handlers, e cada handler recebe uma `thread` que você aciona com alguns métodos:
- **`channel.onMention`** dispara quando um usuário @-menciona o bot. Chame `thread.subscribe()` para entrar na thread, e então `thread.runAgent()` para executar o seu agente CrewAI na menção.
- **`channel.onMessage`** dispara em cada mensagem de uma thread que o bot consegue ver. Restrinja com `thread.isSubscribed()` para que o agente só responda onde tiver entrado, e então `thread.runAgent()`.
- **`thread.runAgent()`** executa o agente CrewAI anexado para o turno atual e transmite a saída dele de volta para o channel. Passe `{ prompt }` para sobrescrever o texto sobre o qual o agente roda.
Seu agente recebe um `RunAgentInput` comum do AG-UI e emite eventos comuns do AG-UI; as mecânicas da plataforma ficam por trás do channel, então o mesmo Crew ou Flow roda sem alterações em todas as plataformas. O channel também expõe handlers para boas-vindas, interrupções, comandos, reações e modais — consulte a [referência de `Channel`](https://docs.copilotkit.ai/reference/channels/classes/Channel) para conhecer toda a superfície.
## Suporte a plataformas
O caminho gerenciado do Intelligence cobre **Slack** e **Microsoft Teams** hoje — o mesmo código de channel roda em qualquer um dos dois, e `message.platform` / `thread.platform` reportam a origem nativa. Outras plataformas (Discord, Telegram, WhatsApp) são alcançadas através de **adaptadores diretos** operados pelo desenvolvedor, em vez do caminho gerenciado — o seu próprio processo detém as credenciais da plataforma e o transporte. Consulte a [documentação de Channels do CopilotKit](https://docs.copilotkit.ai/slack) para a lista atual de plataformas e a configuração por plataforma.
## Relacionados
<CardGroup cols={2}>
<Card title="Visão geral do Frontend" icon="browser" href="/edge/pt-BR/guides/frontend/overview">
Sirva o seu Crew ou Flow por AG-UI — a base sobre a qual todo channel é construído.
</Card>
<Card title="Human-in-the-Loop" icon="user-check" href="/edge/en/guides/frontend/human-in-the-loop">
Pause o agente para coletar aprovação ou input do usuário no meio da execução.
</Card>
</CardGroup>

View File

@@ -0,0 +1,238 @@
---
title: Frontend Overview
description: Construa interfaces de usuário interativas para seus agentes CrewAI com o CopilotKit e o protocolo AG-UI.
icon: browser
mode: "wide"
---
## Dê uma interface de usuário aos seus agentes
O CrewAI executa seus agentes. O [CopilotKit](https://copilotkit.ai) dá a eles um frontend. Juntos, eles permitem que você construa aplicações em que os usuários conversam com um Crew ou Flow, o observam trabalhar em tempo real, aprovam suas decisões e veem sua saída renderizada como UI ao vivo, em vez de paredes de texto.
Os dois se conectam através do [protocolo AG-UI](https://docs.ag-ui.com). O pacote `ag-ui-crewai` expõe qualquer Crew ou Flow como um endpoint AG-UI. Os hooks e componentes React do CopilotKit consomem esse endpoint. Isso desbloqueia experiências que vão muito além de uma caixa de chat:
<CardGroup cols={2}>
<Card title="Generative UI" icon="wand-magic-sparkles" href="/edge/en/guides/frontend/generative-ui">
Renderize as chamadas de tool e o estado do agente como seus próprios componentes React.
</Card>
<Card title="Human-in-the-Loop" icon="user-check" href="/edge/en/guides/frontend/human-in-the-loop">
Pause o agente para coletar aprovação ou input do usuário no meio da execução.
</Card>
<Card title="Shared State" icon="arrows-rotate" href="/edge/en/guides/frontend/shared-state">
Mantenha o estado do agente e a UI do seu app em sincronia bidirecional.
</Card>
<Card title="Channels" icon="messages" href="/edge/pt-BR/guides/frontend/channels">
Execute o mesmo agente como um bot do Slack, Discord ou Teams.
</Card>
</CardGroup>
Este guia coloca um Crew ou Flow conversando com um frontend Next.js de ponta a ponta. O restante da seção se apoia no app que você configura aqui.
## Arquitetura
Há três peças:
1. **CrewAI agent server** — um processo Python que serve o seu Crew ou Flow por AG-UI (FastAPI + `ag-ui-crewai`).
2. **CopilotKit runtime** — uma rota Next.js que registra o seu agente e faz o proxy das requisições para ele.
3. **React frontend** — o provider `<CopilotKit>` mais os componentes de chat e de generative UI.
```
React app ──► CopilotKit runtime (/api/copilotkit) ──► CrewAI server (AG-UI) ──► Crew / Flow
```
<Note>
Este guia cobre o caminho **self-hosted**: você mesmo executa o servidor do agente CrewAI com `ag-ui-crewai`, e ele funciona localmente sem nenhum serviço gerenciado. O CopilotKit também oferece um caminho **gerenciado** (CopilotKit Cloud / Enterprise Intelligence) com threads hospedadas e um inspetor — consulte o [quickstart de CrewAI do CopilotKit](https://docs.copilotkit.ai/crewai-crews/quickstart) se preferir isso. O código do frontend nesta seção é o mesmo de qualquer forma; apenas como o agente é hospedado e registrado é que muda.
</Note>
<Note>
O CrewAI roda por trás do AG-UI em três formatos: **Flows** comuns (usados ao longo destes guias), **[Conversational Flows](/edge/en/guides/frontend/conversational-flows)** (nativos, cientes de sessão, baseados em turnos, com paridade total de recursos) e **Crews** (chat básico). O frontend nesta seção é idêntico entre eles — apenas a autoria e o registro no backend é que diferem.
</Note>
## Guia de integração
<Steps>
<Step title="Sirva seu agente por AG-UI">
Instale o pacote de integração no seu projeto CrewAI:
```bash
pip install ag-ui-crewai
```
Exponha o seu agente a partir de um app FastAPI. Flows usam `add_crewai_flow_fastapi_endpoint`; Crews usam `add_crewai_crew_fastapi_endpoint`. Você pode registrar quantos quiser, cada um em seu próprio path.
<CodeGroup>
```python Flow
# server.py
from fastapi import FastAPI
from ag_ui_crewai.endpoint import add_crewai_flow_fastapi_endpoint
from my_agents.recipe_flow import RecipeFlow
app = FastAPI(title="CrewAI Agent Server")
add_crewai_flow_fastapi_endpoint(
app=app,
flow=RecipeFlow(),
path="/recipe",
)
```
```python Crew
# server.py
from fastapi import FastAPI
from ag_ui_crewai.endpoint import add_crewai_crew_fastapi_endpoint
from my_agents.research_crew import ResearchCrew
app = FastAPI(title="CrewAI Agent Server")
add_crewai_crew_fastapi_endpoint(
app=app,
crew=ResearchCrew().crew(),
path="/research",
)
```
</CodeGroup>
Execute:
```bash
uvicorn server:app --port 8000
```
<Note>
Defina as variáveis de ambiente do seu provedor de LLM (por exemplo `OPENAI_API_KEY`) antes de iniciar o servidor.
</Note>
</Step>
<Step title="Crie um app Next.js">
Se você ainda não tem um frontend, gere um:
```bash
npx create-next-app@latest my-app
cd my-app
```
Instale o CopilotKit e o cliente AG-UI do CrewAI:
```bash
npm install @copilotkit/react-core @copilotkit/react-ui @copilotkit/runtime @ag-ui/crewai
```
</Step>
<Step title="Adicione o runtime do CopilotKit">
Crie uma rota que registre o(s) seu(s) agente(s) CrewAI no runtime do CopilotKit. Cada agente aponta para um path no seu servidor Python via `CrewAIAgent`.
```ts
// app/api/copilotkit/route.ts
import {
CopilotRuntime,
InMemoryAgentRunner,
createCopilotEndpoint,
} from "@copilotkit/runtime/v2";
import { CrewAIAgent } from "@ag-ui/crewai";
import { handle } from "hono/vercel";
const runtime = new CopilotRuntime({
agents: {
recipe: new CrewAIAgent({ url: "http://localhost:8000/recipe" }),
},
runner: new InMemoryAgentRunner(),
});
const app = createCopilotEndpoint({
runtime,
basePath: "/api/copilotkit",
});
const handler = handle(app);
export const GET = handler;
export const POST = handler;
```
</Step>
<Step title="Envolva seu app com o provider">
Aponte `<CopilotKit>` para a rota do runtime e nomeie o agente que você registrou.
```tsx
// app/page.tsx
"use client";
import { CopilotKit } from "@copilotkit/react-core";
import { CopilotSidebar } from "@copilotkit/react-core/v2";
import "@copilotkit/react-core/v2/styles.css";
export default function Page() {
return (
<CopilotKit runtimeUrl="/api/copilotkit" agent="recipe">
<YourApp />
<CopilotSidebar agentId="recipe" labels={{ modalHeaderTitle: "Assistant" }} />
</CopilotKit>
);
}
```
</Step>
<Step title="Execute">
Inicie os dois processos e abra o app. Conversar na sidebar agora executa o seu Crew ou Flow.
```bash
uvicorn server:app --port 8000 # terminal 1
npm run dev # terminal 2
```
</Step>
</Steps>
## Opções de UI de chat
O CopilotKit entrega três superfícies de chat intercambiáveis. Troque o componente; a fiação é idêntica.
<CodeGroup>
```tsx Sidebar
import { CopilotSidebar } from "@copilotkit/react-core/v2";
<CopilotSidebar agentId="recipe" />
```
```tsx Popup
import { CopilotPopup } from "@copilotkit/react-core/v2";
<CopilotPopup agentId="recipe" />
```
```tsx Inline
import { CopilotChat } from "@copilotkit/react-core/v2";
<CopilotChat agentId="recipe" />
```
</CodeGroup>
## Para onde ir em seguida
<CardGroup cols={2}>
<Card title="Generative UI" icon="wand-magic-sparkles" href="/edge/en/guides/frontend/generative-ui">
Renderize chamadas de tool e o estado do agente como componentes personalizados.
</Card>
<Card title="Frontend Actions" icon="bolt" href="/edge/en/guides/frontend/frontend-actions">
Permita que o agente chame funções que rodam no navegador.
</Card>
<Card title="Human-in-the-Loop" icon="user-check" href="/edge/en/guides/frontend/human-in-the-loop">
Restrinja ações do agente por trás da aprovação do usuário.
</Card>
<Card title="Predictive State" icon="gauge-high" href="/edge/en/guides/frontend/predictive-state-updates">
Transmita o estado em andamento para a UI enquanto o agente trabalha.
</Card>
</CardGroup>

View File

@@ -140,7 +140,7 @@ Você pode se conectar a LLMs compatíveis com a OpenAI usando variáveis de amb
# Exemplo usando a API compatível com OpenAI do Gemini.
os.environ["OPENAI_API_KEY"] = "your-gemini-key" # Deve começar com AIza...
os.environ["OPENAI_API_BASE"] = "https://generativelanguage.googleapis.com/v1beta/openai/"
os.environ["OPENAI_MODEL_NAME"] = "openai/gemini-2.0-flash" # Adicione aqui seu modelo do Gemini, sob openai/
os.environ["OPENAI_MODEL_NAME"] = "openai/gemini-3.7-flash" # Adicione aqui seu modelo do Gemini, sob openai/
```
</CodeGroup>
</Tab>
@@ -158,7 +158,7 @@ Você pode se conectar a LLMs compatíveis com a OpenAI usando variáveis de amb
```python Google
# Exemplo usando a API compatível com OpenAI do Gemini
llm = LLM(
model="openai/gemini-2.0-flash",
model="openai/gemini-3.7-flash",
base_url="https://generativelanguage.googleapis.com/v1beta/openai/",
api_key="your-gemini-key", # Deve começar com AIza...
)

View File

@@ -148,7 +148,7 @@ Agentes de planejamento se beneficiam de modelos de raciocínio para pensamento
from crewai import Agent, Task, Crew, LLM
# Modelo de raciocínio para planejamento estratégico
manager_llm = LLM(model="gemini-2.5-flash-preview-05-20", temperature=0.1)
manager_llm = LLM(model="gemini/gemini-3.7-flash", temperature=0.1)
# Modelo criativo para gerar conteúdo
content_llm = LLM(model="claude-3-5-sonnet-20241022", temperature=0.7)
@@ -413,7 +413,7 @@ Em vez de repetir o framework estratégico, segue um checklist tático para impl
# Agentes gerenciadores ou de coordenação
manager_agent = Agent(
role="Project Manager",
llm=LLM(model="gemini-2.5-flash-preview-05-20"),
llm=LLM(model="gemini/gemini-3.7-flash"),
# ... demais configs
)

View File

@@ -9,7 +9,7 @@ mode: "wide"
O CrewAI fornece recursos de rastreamento integrados que permitem monitorar e depurar seus Crews e Flows em tempo real. Este guia demonstra como habilitar o rastreamento para **Crews** e **Flows** usando a plataforma de observabilidade integrada do CrewAI.
> **O que é o CrewAI Tracing?** O rastreamento integrado do CrewAI fornece observabilidade abrangente para seus agentes de IA, incluindo decisões de agentes, cronogramas de execução de tarefas, uso de ferramentas e chamadas de LLM - tudo acessível através da [plataforma CrewAI AMP](https://app.crewai.com).
> **O que é o CrewAI Tracing?** O rastreamento integrado do CrewAI fornece observabilidade abrangente para seus agentes de IA, incluindo decisões de agentes, cronogramas de execução de tarefas, uso de ferramentas e chamadas de LLM - tudo acessível através da [plataforma CrewAI AMP](https://app.crewai.com). O rastreamento é gerenciado de forma independente da [telemetria](/pt-BR/telemetry).
![CrewAI Tracing Interface](/images/crewai-tracing.png)
@@ -150,8 +150,8 @@ result = flow.kickoff()
### Passo 5: Visualize os Rastreamentos no Painel CrewAI AMP
Após executar o crew ou flow, você pode visualizar os rastreamentos gerados pela sua aplicação CrewAI no painel CrewAI AMP. Você verá etapas detalhadas das interações dos agentes, usos de ferramentas e chamadas de LLM.
Basta clicar no link abaixo para visualizar os rastreamentos ou ir para a aba de rastreamentos no painel [aqui](https://app.crewai.com/crewai_plus/trace_batches)
Os rastreamentos são enviados somente após uma exportação autenticada bem-sucedida ou um upload anônimo explicitamente aprovado e concluído com sucesso. Uma execução cujo buffer local foi descartado não tem rastreamento enviado.
Para rastreamentos associados à sua conta, abra a [aba Traces no painel CrewAI AMP](https://app.crewai.com/crewai_plus/trace_batches) para visualizar interações dos agentes, uso de ferramentas e chamadas de LLM.
![CrewAI Tracing Interface](/images/view-traces.png)
### Alternativa: Configuração de Variável de Ambiente
@@ -170,6 +170,52 @@ CREWAI_TRACING_ENABLED=true
Quando esta variável de ambiente estiver definida, todos os Crews e Flows terão automaticamente o rastreamento habilitado, mesmo sem definir explicitamente `tracing=True`.
## Visualizando rastreamentos após a primeira execução
Na primeira vez que você executa um Crew ou Flow, um terminal interativo pode perguntar:
```text
Share this execution trace with CrewAI? [y/N]
```
Escolha **yes** para enviar o rastreamento armazenado no buffer ao CrewAI.
Os rastreamentos podem conter prompts, entradas e saídas. Recusar, deixar o
prazo expirar ou executar sem uma solicitação interativa de consentimento
descarta o buffer. Você pode alterar o rastreamento depois com
`crewai traces enable` ou `crewai traces disable`, ou definindo `tracing`
no Crew ou Flow.
### Buffer local e exportação autenticada
A coleta de rastreamentos da primeira execução permanece na memória do processo
até você concordar em compartilhar, mesmo com credenciais de login salvas.
O rastreamento sem autenticação usa o mesmo fluxo de consentimento. Antes do
consentimento, o CrewAI não solicita autorização de upload nem envia spans de execução.
O buffer retém até **1.000 spans** e **8 MiB de dados OTLP codificados**.
Defina `CREWAI_EPHEMERAL_TRACE_MAX_SPANS` e
`CREWAI_EPHEMERAL_TRACE_MAX_BYTES` como inteiros positivos para ajustar esses limites.
Ao exceder o limite, os spans mais antigos são descartados; um span maior que o
limite de bytes é descartado. O buffer é esvaziado após o compartilhamento ou descarte.
Quando o rastreamento está habilitado e há credenciais disponíveis, o CrewAI troca
seu login da CLI, `CREWAI_USER_PAT` ou credencial de integração da plataforma
com o AMP por uma autorização específica para a execução. Em seguida, exporta
spans OpenTelemetry diretamente para o Wharf usando essa autorização.
Credenciais inválidas não resultam em upload anônimo como alternativa.
### Sessões de execução hospedadas
Os hosts podem envolver a execução com `telemetry_session` de
`crewai.telemetry.tracing`. A sessão usa eventos do ciclo de vida do CrewAI
para criar e finalizar spans, preservando timestamps, relações de parentesco e
links de pausa/retomada de HITL. Passe um provedor existente com `providers=`
para manter o tracer e a integração de logs do host. Passe processadores de
spans com `processors=` e um callback de logs do host com `log_emitter=`.
O host é responsável por qualquer remoção de dados sensíveis nessas integrações. Cada sessão gerencia
seu próprio ciclo de vida de rastreamento e mantém o provedor OpenTelemetry
global da aplicação inalterado.
## Visualizando seus Rastreamentos
### Acesse o Painel CrewAI AMP
@@ -210,5 +256,5 @@ Se os rastreamentos não estiverem aparecendo no painel:
1. Confirme que `tracing=True` está definido em seu Crew/Flow
2. Verifique se `CREWAI_TRACING_ENABLED=true` se estiver usando variáveis de ambiente
3. Certifique-se de estar autenticado com `crewai login`
4. Verifique se seu crew/flow está realmente executando
3. Para exportação autenticada, verifique seu login da CLI, `CREWAI_USER_PAT` ou credencial de integração da plataforma. Para compartilhamento anônimo, aprove explicitamente a solicitação de consentimento; não é necessário fazer login
4. Verifique se seu crew/flow foi executado e se a exportação do rastreamento foi bem-sucedida. Recusar o consentimento, deixar o prazo expirar ou executar sem uma solicitação interativa de consentimento descarta o buffer local sem enviá-lo

View File

@@ -23,7 +23,8 @@ uso de ferramentas, chamadas de API, respostas, quaisquer dados processados pelo
Quando o recurso `share_crew` está ativado, dados detalhados, incluindo descrições das tarefas, histórias ou objetivos dos agentes e outros atributos específicos são coletados
para fornecer insights mais detalhados. Essa coleta expandida pode incluir informações pessoais caso o usuário as tenha inserido em seus crews ou tarefas.
Usuários devem considerar cuidadosamente o conteúdo de seus crews e tarefas antes de habilitar o `share_crew`.
A telemetria pode ser desabilitada ao definir a variável de ambiente `CREWAI_DISABLE_TELEMETRY` como `true` ou ao definir `OTEL_SDK_DISABLED` como `true` (observe que esta última desabilita toda instrumentação OpenTelemetry globalmente).
A telemetria do CrewAI pode ser desabilitada ao definir `CREWAI_DISABLE_TELEMETRY` como `true`, `1`, `yes` ou `on` (qualquer capitalização). `OTEL_SDK_DISABLED` com os mesmos valores também desabilita o exportador do CrewAI. O SDK do OpenTelemetry em si ainda só reconhece `true` para desabilitar as demais instrumentações do processo.
O rastreamento AMP é tratado em [Tracing](/pt-BR/observability/tracing).
### Exemplos:
```python
@@ -34,6 +35,8 @@ os.environ['CREWAI_DISABLE_TELEMETRY'] = 'true'
os.environ['OTEL_SDK_DISABLED'] = 'true'
```
`CREWAI_DISABLE_TELEMETRY=1` (ou `yes` / `on`) funciona como `true`. Valores não reconhecidos são ignorados e a telemetria permanece ligada.
### Isolamento da sua própria configuração do OpenTelemetry
A telemetria do CrewAI roda em seu próprio `TracerProvider` privado e nunca se
@@ -60,8 +63,8 @@ por meio do próprio tracer provider, que é independente do descrito aqui.
| Sim | Dados do Ciclo de Vida da Tarefa | Inclui: horários de criação, início/fim de execução, identificadores de crew e tarefa, e se a tarefa foi bem-sucedida ou falhou. Quando uma tarefa falha, o **nome da classe** da exceção é registrado (por exemplo `TimeoutError`) para que as falhas possam ser contadas e diagnosticadas — nunca a mensagem de erro, que pode conter prompts, saída do modelo, caminhos de arquivos ou credenciais. Armazenado como spans com timestamps. Sem dados pessoais. |
| Sim | Atributos do LLM | Inclui: nome, model_name, model, top_k, temperatura e nome da classe do LLM. Todos técnicos, sem dados pessoais. |
| Sim | Criação de Projeto pelo CLI do crewAI | Inclui: o fato de um novo projeto ter sido criado por `crewai create`, de qual tipo ele é (`crew`, `json_crew` ou `flow`) e o ID de projeto gerado para esse novo projeto e gravado no `pyproject.toml` dele. É o ID do próprio projeto novo, registrado separadamente do `project_id` do diretório de onde o comando foi executado — os dois podem diferir. Sem nome de projeto, sem conteúdo de arquivos, sem código. Sem dados pessoais. |
| Sim | Tentativa de Deploy do Crew pelo CLI do crewAI | Inclui: O fato de um deploy estar sendo realizado e o crew id, se está tentando buscar logs, e se o deploy foi iniciado por um comando do CLI ou pela TUI de execução. Não inclui conteúdo do projeto ou do crew nem dados pessoais. |
| Sim | Ambiente de Execução | Inclui: qual assistente de código com IA está executando o processo, se houver (um de uma lista fixa como `claude_code`, `codex`, `cursor` ou `unknown`), onde o processo é executado (um de uma lista fixa como `ci`, `container`, `serverless`, `interactive`) e o `project_id` do seu `pyproject.toml` quando houver um configurado. A detecção lê apenas se variáveis de ambiente conhecidas estão definidas, nunca seus valores. Sem dados pessoais. |
| Sim | Tentativa de Deploy do Crew pelo CLI do crewAI | Inclui: O fato de um deploy estar sendo realizado e o crew id, se está tentando buscar logs, e se o deploy foi iniciado por um comando do CLI ou pela TUI de execução. Se a criação de um deploy falhar, são registradas a categoria da falha (uma de uma lista fixa, como `api_4xx`, `network_error` ou `user_declined`) e o código de status HTTP da resposta da API, quando houver — nunca a mensagem de erro. Não inclui conteúdo do projeto ou do crew nem dados pessoais. |
| Sim | Ambiente de Execução | Inclui: qual assistente de código com IA está executando o processo, se houver (um valor de uma lista fixa como `claude_code`, `codex`, `cursor` ou `unknown`), onde o processo é executado (um valor de uma lista fixa como `ci`, `container`, `serverless`, `interactive`), o `project_id` do seu `pyproject.toml` quando houver um configurado e uma faixa aproximada de tamanho da máquina (uma de `1-2`, `3-4`, `5-8`, `9-16`, `17-32`, `33+` ou `unknown`). A faixa é um intervalo, nunca a contagem exata de núcleos — a contagem exata é opcional, em Informações de Ambiente abaixo. A faixa de tamanho vem da contagem de núcleos do host; a detecção do assistente e do local de execução lê apenas se variáveis de ambiente conhecidas estão definidas, nunca seus valores. Sem dados pessoais. |
| Sim | Sinais de Ciclo de Vida do Flow | Inclui: que um flow iniciou, se foi concluído ou falhou, se um de seus métodos falhou, se pausou para entrada ou feedback humano, se o início foi uma execução retomada, se um turno de conversa falhou, quanto tempo o flow executou, e se o flow é um que a CrewAI executa internamente ou um que você escreveu. O nome do flow é registrado, como já é para criação e execução de flow. Quando um flow ou um de seus métodos falha, o **nome da classe** da exceção é registrado (por exemplo `TimeoutError`) para permitir o diagnóstico de falhas — nunca a mensagem de erro, que pode conter prompts, saída do modelo, caminhos de arquivo ou credenciais. Nomes de métodos e estado do flow nunca são registrados. Nenhum dado pessoal. |
| Sim | Sinal de Compartilhamento de Trace | Inclui: que um lote de traces foi compartilhado com sucesso com o CrewAI AMP, e se foi compartilhado anonimamente (antes de você ter uma conta) ou vinculado à sua conta. Como todo span, também carrega os atributos de Ambiente de Execução descritos acima (`project_id` quando configurado, o assistente de programação e o runtime). Esta linha descreve apenas a telemetria do compartilhamento — não o conteúdo dos traces nem o acesso concedido por links de traces compartilhados. O conteúdo dos traces, entradas e saídas nunca são registrados neste sinal. Antes de compartilhar traces, revise segredos, dados pessoais e as configurações de redação e retenção do AMP. |
| Não | Dados Expandidos do Agente | Inclui: descrição do objetivo, texto da história, identificador de arquivo i18n prompt. Usuários devem garantir que não haja info pessoal nesses campos de texto. |

View File

@@ -50,17 +50,16 @@ Essas ferramentas se integram com serviços de IA e machine learning para aprimo
- **Segurança em IA**: Implemente moderação de conteúdo e checagens de segurança
```python
from crewai_tools import DallETool, VisionTool, CodeInterpreterTool
from crewai_tools import DallETool, VisionTool
# Create AI tools
image_generator = DallETool()
vision_processor = VisionTool()
code_executor = CodeInterpreterTool()
# Add to your agent
agent = Agent(
role="AI Specialist",
tools=[image_generator, vision_processor, code_executor],
tools=[image_generator, vision_processor],
goal="Create and analyze content using AI capabilities"
)
```

View File

@@ -9,7 +9,7 @@ mode: "wide"
## Descrição
O `RagTool` foi desenvolvido para responder perguntas aproveitando o poder da Geração Aumentada por Recuperação (RAG) através do EmbedChain.
O `RagTool` foi desenvolvido para responder perguntas aproveitando o poder da Geração Aumentada por Recuperação (RAG) por meio do sistema RAG nativo da CrewAI.
Ele fornece uma base de conhecimento dinâmica que pode ser consultada para recuperar informações relevantes de várias fontes de dados.
Esta ferramenta é particularmente útil para aplicações que exigem acesso a uma ampla variedade de informações e precisam fornecer respostas contextualmente relevantes.
@@ -76,8 +76,8 @@ O `RagTool` pode ser utilizado com uma grande variedade de fontes de dados, incl
O `RagTool` aceita os seguintes parâmetros:
- **summarize**: Opcional. Indica se o conteúdo recuperado deve ser resumido. O padrão é `False`.
- **adapter**: Opcional. Um adaptador personalizado para a base de conhecimento. Se não for fornecido, será utilizado o EmbedchainAdapter.
- **config**: Opcional. Configuração para o aplicativo EmbedChain subjacente.
- **adapter**: Opcional. Um adaptador personalizado para a base de conhecimento. Se não for fornecido, será utilizado o CrewAIRagAdapter.
- **config**: Opcional. Configuração do sistema RAG subjacente da CrewAI. Aceita um TypedDict `RagToolConfig` com as chaves opcionais `embedding_model` (ProviderSpec) e `vectordb` (VectorDbConfig). Todos os valores de configuração fornecidos programaticamente têm precedência sobre as variáveis de ambiente.
## Adicionando Conteúdo
@@ -127,47 +127,528 @@ def knowledge_expert(self) -> Agent:
```python Code
from crewai_tools import RagTool
from crewai_tools.tools.rag import RagToolConfig, VectorDbConfig, ProviderSpec
# Create a RAG tool with custom configuration
config = {
"app": {
"name": "custom_app",
},
"llm": {
"provider": "openai",
"config": {
"model": "gpt-4",
}
},
"embedding_model": {
"provider": "openai",
"config": {
"model": "text-embedding-ada-002"
}
},
"vectordb": {
"provider": "elasticsearch",
"config": {
"collection_name": "my-collection",
"cloud_id": "deployment-name:xxxx",
"api_key": "your-key",
"verify_certs": False
}
},
"chunker": {
"chunk_size": 400,
"chunk_overlap": 100,
"length_function": "len",
"min_chunk_size": 0
vectordb: VectorDbConfig = {
"provider": "qdrant",
"config": {
"collection_name": "my-collection"
}
}
embedding_model: ProviderSpec = {
"provider": "openai",
"config": {
"model_name": "text-embedding-3-small"
}
}
config: RagToolConfig = {
"vectordb": vectordb,
"embedding_model": embedding_model
}
rag_tool = RagTool(config=config, summarize=True)
```
A ferramenta RAG interna utiliza o adaptador Embedchain, possibilitando que você forneça quaisquer opções de configuração suportadas pelo Embedchain.
Você pode consultar a [documentação do Embedchain](https://docs.embedchain.ai/components/introduction) para mais detalhes.
Certifique-se de revisar as opções de configuração disponíveis no arquivo .yaml.
## Configuração do Modelo de Embedding
O parâmetro `embedding_model` aceita um dicionário `crewai.rag.embeddings.types.ProviderSpec` com a seguinte estrutura:
```python
{
"provider": "provider-name", # Required
"config": { # Optional
# Provider-specific configuration
}
}
```
### Provedores Suportados
<AccordionGroup>
<Accordion title="OpenAI">
```python main.py
from crewai.rag.embeddings.providers.openai.types import OpenAIProviderSpec
embedding_model: OpenAIProviderSpec = {
"provider": "openai",
"config": {
"api_key": "your-api-key",
"model_name": "text-embedding-ada-002",
"dimensions": 1536,
"organization_id": "your-org-id",
"api_base": "https://api.openai.com/v1",
"api_version": "v1",
"default_headers": {"Custom-Header": "value"}
}
}
```
**Opções de Configuração:**
- `api_key` (str): Chave da API OpenAI
- `model_name` (str): Modelo a ser utilizado. Padrão: `text-embedding-ada-002`. Opções: `text-embedding-3-small`, `text-embedding-3-large`, `text-embedding-ada-002`
- `dimensions` (int): Número de dimensões do embedding
- `organization_id` (str): ID da organização OpenAI
- `api_base` (str): URL base personalizada da API
- `api_version` (str): Versão da API
- `default_headers` (dict): Cabeçalhos personalizados para solicitações à API
**Variáveis de Ambiente:**
- `OPENAI_API_KEY` ou `EMBEDDINGS_OPENAI_API_KEY`: `api_key`
- `OPENAI_ORGANIZATION_ID` ou `EMBEDDINGS_OPENAI_ORGANIZATION_ID`: `organization_id`
- `OPENAI_MODEL_NAME` ou `EMBEDDINGS_OPENAI_MODEL_NAME`: `model_name`
- `OPENAI_API_BASE` ou `EMBEDDINGS_OPENAI_API_BASE`: `api_base`
- `OPENAI_API_VERSION` ou `EMBEDDINGS_OPENAI_API_VERSION`: `api_version`
- `OPENAI_DIMENSIONS` ou `EMBEDDINGS_OPENAI_DIMENSIONS`: `dimensions`
</Accordion>
<Accordion title="Cohere">
```python main.py
from crewai.rag.embeddings.providers.cohere.types import CohereProviderSpec
embedding_model: CohereProviderSpec = {
"provider": "cohere",
"config": {
"api_key": "your-api-key",
"model_name": "embed-english-v3.0"
}
}
```
**Opções de Configuração:**
- `api_key` (str): Chave da API Cohere
- `model_name` (str): Modelo a ser utilizado. Padrão: `large`. Opções: `embed-english-v3.0`, `embed-multilingual-v3.0`, `large`, `small`
**Variáveis de Ambiente:**
- `COHERE_API_KEY` ou `EMBEDDINGS_COHERE_API_KEY`: `api_key`
- `EMBEDDINGS_COHERE_MODEL_NAME`: `model_name`
</Accordion>
<Accordion title="VoyageAI">
```python main.py
from crewai.rag.embeddings.providers.voyageai.types import VoyageAIProviderSpec
embedding_model: VoyageAIProviderSpec = {
"provider": "voyageai",
"config": {
"api_key": "your-api-key",
"model": "voyage-3",
"input_type": "document",
"truncation": True,
"output_dtype": "float32",
"output_dimension": 1024,
"max_retries": 3,
"timeout": 60.0
}
}
```
**Opções de Configuração:**
- `api_key` (str): Chave da API VoyageAI
- `model` (str): Modelo a ser utilizado. Padrão: `voyage-2`. Opções: `voyage-3`, `voyage-3-lite`, `voyage-code-3`, `voyage-large-2`
- `input_type` (str): Tipo de entrada. Opções: `document` (para armazenamento), `query` (para pesquisa)
- `truncation` (bool): Indica se entradas que excedem o comprimento máximo devem ser truncadas. Padrão: `True`
- `output_dtype` (str): Tipo de dados da saída
- `output_dimension` (int): Dimensão dos embeddings de saída
- `max_retries` (int): Número máximo de tentativas. Padrão: `0`
- `timeout` (float): Tempo limite da solicitação em segundos
**Variáveis de Ambiente:**
- `VOYAGEAI_API_KEY` ou `EMBEDDINGS_VOYAGEAI_API_KEY`: `api_key`
- `VOYAGEAI_MODEL` ou `EMBEDDINGS_VOYAGEAI_MODEL`: `model`
- `VOYAGEAI_INPUT_TYPE` ou `EMBEDDINGS_VOYAGEAI_INPUT_TYPE`: `input_type`
- `VOYAGEAI_TRUNCATION` ou `EMBEDDINGS_VOYAGEAI_TRUNCATION`: `truncation`
- `VOYAGEAI_OUTPUT_DTYPE` ou `EMBEDDINGS_VOYAGEAI_OUTPUT_DTYPE`: `output_dtype`
- `VOYAGEAI_OUTPUT_DIMENSION` ou `EMBEDDINGS_VOYAGEAI_OUTPUT_DIMENSION`: `output_dimension`
- `VOYAGEAI_MAX_RETRIES` ou `EMBEDDINGS_VOYAGEAI_MAX_RETRIES`: `max_retries`
- `VOYAGEAI_TIMEOUT` ou `EMBEDDINGS_VOYAGEAI_TIMEOUT`: `timeout`
</Accordion>
<Accordion title="Ollama">
```python main.py
from crewai.rag.embeddings.providers.ollama.types import OllamaProviderSpec
embedding_model: OllamaProviderSpec = {
"provider": "ollama",
"config": {
"model_name": "llama2",
"url": "http://localhost:11434/api/embeddings"
}
}
```
**Opções de Configuração:**
- `model_name` (str): Nome do modelo Ollama (por exemplo, `llama2`, `mistral`, `nomic-embed-text`)
- `url` (str): URL do endpoint da API Ollama. Padrão: `http://localhost:11434/api/embeddings`
**Variáveis de Ambiente:**
- `OLLAMA_MODEL` ou `EMBEDDINGS_OLLAMA_MODEL`: `model_name`
- `OLLAMA_URL` ou `EMBEDDINGS_OLLAMA_URL`: `url`
</Accordion>
<Accordion title="Amazon Bedrock">
```python main.py
from crewai.rag.embeddings.providers.aws.types import BedrockProviderSpec
embedding_model: BedrockProviderSpec = {
"provider": "amazon-bedrock",
"config": {
"model_name": "amazon.titan-embed-text-v2:0",
"session": boto3_session
}
}
```
**Opções de Configuração:**
- `model_name` (str): ID do modelo Bedrock. Padrão: `amazon.titan-embed-text-v1`. Opções: `amazon.titan-embed-text-v1`, `amazon.titan-embed-text-v2:0`, `cohere.embed-english-v3`, `cohere.embed-multilingual-v3`
- `session` (Any): Objeto de sessão Boto3 para autenticação da AWS
**Variáveis de Ambiente:**
- `AWS_ACCESS_KEY_ID`: Chave de acesso da AWS
- `AWS_SECRET_ACCESS_KEY`: Chave secreta da AWS
- `AWS_REGION`: Região da AWS (por exemplo, `us-east-1`)
</Accordion>
<Accordion title="Azure OpenAI">
```python main.py
from crewai.rag.embeddings.providers.microsoft.types import AzureProviderSpec
embedding_model: AzureProviderSpec = {
"provider": "azure",
"config": {
"deployment_id": "your-deployment-id",
"api_key": "your-api-key",
"api_base": "https://your-resource.openai.azure.com",
"api_version": "2024-02-01",
"model_name": "text-embedding-ada-002",
"api_type": "azure"
}
}
```
**Opções de Configuração:**
- `deployment_id` (str): **Obrigatório** - ID de implantação do Azure OpenAI
- `api_key` (str): Chave da API Azure OpenAI
- `api_base` (str): Endpoint do recurso Azure OpenAI
- `api_version` (str): Versão da API. Exemplo: `2024-02-01`
- `model_name` (str): Nome do modelo. Padrão: `text-embedding-ada-002`
- `api_type` (str): Tipo de API. Padrão: `azure`
- `dimensions` (int): Dimensões da saída
- `default_headers` (dict): Cabeçalhos personalizados
**Variáveis de Ambiente:**
- `AZURE_OPENAI_API_KEY` ou `EMBEDDINGS_AZURE_API_KEY`: `api_key`
- `AZURE_OPENAI_ENDPOINT` ou `EMBEDDINGS_AZURE_API_BASE`: `api_base`
- `EMBEDDINGS_AZURE_DEPLOYMENT_ID`: `deployment_id`
- `EMBEDDINGS_AZURE_API_VERSION`: `api_version`
- `EMBEDDINGS_AZURE_MODEL_NAME`: `model_name`
- `EMBEDDINGS_AZURE_API_TYPE`: `api_type`
- `EMBEDDINGS_AZURE_DIMENSIONS`: `dimensions`
</Accordion>
<Accordion title="Google Generative AI">
```python main.py
from crewai.rag.embeddings.providers.google.types import GenerativeAiProviderSpec
embedding_model: GenerativeAiProviderSpec = {
"provider": "google-generativeai",
"config": {
"api_key": "your-api-key",
"model_name": "gemini-embedding-001",
"task_type": "RETRIEVAL_DOCUMENT"
}
}
```
**Opções de Configuração:**
- `api_key` (str): Chave da API Google AI
- `model_name` (str): Nome do modelo. Padrão: `gemini-embedding-001`. Opções: `gemini-embedding-001`, `text-embedding-005`, `text-multilingual-embedding-002`
- `task_type` (str): Tipo de tarefa para embeddings. Padrão: `RETRIEVAL_DOCUMENT`. Opções: `RETRIEVAL_DOCUMENT`, `RETRIEVAL_QUERY`
**Variáveis de Ambiente:**
- `GOOGLE_API_KEY`, `GEMINI_API_KEY` ou `EMBEDDINGS_GOOGLE_API_KEY`: `api_key`
- `EMBEDDINGS_GOOGLE_GENERATIVE_AI_MODEL_NAME`: `model_name`
- `EMBEDDINGS_GOOGLE_GENERATIVE_AI_TASK_TYPE`: `task_type`
</Accordion>
<Accordion title="Google Vertex AI">
```python main.py
from crewai.rag.embeddings.providers.google.types import VertexAIProviderSpec
embedding_model: VertexAIProviderSpec = {
"provider": "google-vertex",
"config": {
"model_name": "text-embedding-004",
"project_id": "your-project-id",
"region": "us-central1",
"api_key": "your-api-key"
}
}
```
**Opções de Configuração:**
- `model_name` (str): Nome do modelo. Padrão: `textembedding-gecko`. Opções: `text-embedding-004`, `textembedding-gecko`, `textembedding-gecko-multilingual`
- `project_id` (str): ID do projeto Google Cloud. Padrão: `cloud-large-language-models`
- `region` (str): Região do Google Cloud. Padrão: `us-central1`
- `api_key` (str): Chave de API para autenticação
**Variáveis de Ambiente:**
- `GOOGLE_APPLICATION_CREDENTIALS`: Caminho para o arquivo JSON da conta de serviço
- `GOOGLE_CLOUD_PROJECT` ou `EMBEDDINGS_GOOGLE_VERTEX_PROJECT_ID`: `project_id`
- `EMBEDDINGS_GOOGLE_VERTEX_MODEL_NAME`: `model_name`
- `EMBEDDINGS_GOOGLE_VERTEX_REGION`: `region`
- `EMBEDDINGS_GOOGLE_VERTEX_API_KEY`: `api_key`
</Accordion>
<Accordion title="Jina AI">
```python main.py
from crewai.rag.embeddings.providers.jina.types import JinaProviderSpec
embedding_model: JinaProviderSpec = {
"provider": "jina",
"config": {
"api_key": "your-api-key",
"model_name": "jina-embeddings-v3"
}
}
```
**Opções de Configuração:**
- `api_key` (str): Chave da API Jina AI
- `model_name` (str): Nome do modelo. Padrão: `jina-embeddings-v2-base-en`. Opções: `jina-embeddings-v3`, `jina-embeddings-v2-base-en`, `jina-embeddings-v2-small-en`
**Variáveis de Ambiente:**
- `JINA_API_KEY` ou `EMBEDDINGS_JINA_API_KEY`: `api_key`
- `EMBEDDINGS_JINA_MODEL_NAME`: `model_name`
</Accordion>
<Accordion title="HuggingFace">
```python main.py
from crewai.rag.embeddings.providers.huggingface.types import HuggingFaceProviderSpec
embedding_model: HuggingFaceProviderSpec = {
"provider": "huggingface",
"config": {
"url": "https://api-inference.huggingface.co/models/sentence-transformers/all-MiniLM-L6-v2"
}
}
```
**Opções de Configuração:**
- `url` (str): URL completa do endpoint da API de inferência do HuggingFace
**Variáveis de Ambiente:**
- `HUGGINGFACE_URL` ou `EMBEDDINGS_HUGGINGFACE_URL`: `url`
</Accordion>
<Accordion title="Instructor">
```python main.py
from crewai.rag.embeddings.providers.instructor.types import InstructorProviderSpec
embedding_model: InstructorProviderSpec = {
"provider": "instructor",
"config": {
"model_name": "hkunlp/instructor-xl",
"device": "cuda",
"instruction": "Represent the document"
}
}
```
**Opções de Configuração:**
- `model_name` (str): ID do modelo HuggingFace. Padrão: `hkunlp/instructor-base`. Opções: `hkunlp/instructor-xl`, `hkunlp/instructor-large`, `hkunlp/instructor-base`
- `device` (str): Dispositivo no qual executar. Padrão: `cpu`. Opções: `cpu`, `cuda`, `mps`, `xpu`
- `instruction` (str): Prefixo de instrução para embeddings
**Variáveis de Ambiente:**
- `EMBEDDINGS_INSTRUCTOR_MODEL_NAME`: `model_name`
- `EMBEDDINGS_INSTRUCTOR_DEVICE`: `device`
- `EMBEDDINGS_INSTRUCTOR_INSTRUCTION`: `instruction`
</Accordion>
<Accordion title="Sentence Transformer">
```python main.py
from crewai.rag.embeddings.providers.sentence_transformer.types import SentenceTransformerProviderSpec
embedding_model: SentenceTransformerProviderSpec = {
"provider": "sentence-transformer",
"config": {
"model_name": "all-mpnet-base-v2",
"device": "cuda",
"normalize_embeddings": True
}
}
```
**Opções de Configuração:**
- `model_name` (str): Nome do modelo Sentence Transformers. Padrão: `all-MiniLM-L6-v2`. Opções: `all-mpnet-base-v2`, `all-MiniLM-L6-v2`, `paraphrase-multilingual-MiniLM-L12-v2`
- `device` (str): Dispositivo no qual executar. Padrão: `cpu`. Opções: `cpu`, `cuda`, `mps`, `xpu`
- `normalize_embeddings` (bool): Indica se os embeddings devem ser normalizados. Padrão: `False`
**Variáveis de Ambiente:**
- `EMBEDDINGS_SENTENCE_TRANSFORMER_MODEL_NAME`: `model_name`
- `EMBEDDINGS_SENTENCE_TRANSFORMER_DEVICE`: `device`
- `EMBEDDINGS_SENTENCE_TRANSFORMER_NORMALIZE_EMBEDDINGS`: `normalize_embeddings`
</Accordion>
<Accordion title="ONNX">
```python main.py
from crewai.rag.embeddings.providers.onnx.types import ONNXProviderSpec
embedding_model: ONNXProviderSpec = {
"provider": "onnx",
"config": {
"preferred_providers": ["CUDAExecutionProvider", "CPUExecutionProvider"]
}
}
```
**Opções de Configuração:**
- `preferred_providers` (list[str]): Lista de provedores de execução ONNX em ordem de preferência
**Variáveis de Ambiente:**
- `EMBEDDINGS_ONNX_PREFERRED_PROVIDERS`: `preferred_providers` (lista separada por vírgulas)
</Accordion>
<Accordion title="OpenCLIP">
```python main.py
from crewai.rag.embeddings.providers.openclip.types import OpenCLIPProviderSpec
embedding_model: OpenCLIPProviderSpec = {
"provider": "openclip",
"config": {
"model_name": "ViT-B-32",
"checkpoint": "laion2b_s34b_b79k",
"device": "cuda"
}
}
```
**Opções de Configuração:**
- `model_name` (str): Arquitetura do modelo OpenCLIP. Padrão: `ViT-B-32`. Opções: `ViT-B-32`, `ViT-B-16`, `ViT-L-14`
- `checkpoint` (str): Nome do checkpoint pré-treinado. Padrão: `laion2b_s34b_b79k`. Opções: `laion2b_s34b_b79k`, `laion400m_e32`, `openai`
- `device` (str): Dispositivo no qual executar. Padrão: `cpu`. Opções: `cpu`, `cuda`
**Variáveis de Ambiente:**
- `EMBEDDINGS_OPENCLIP_MODEL_NAME`: `model_name`
- `EMBEDDINGS_OPENCLIP_CHECKPOINT`: `checkpoint`
- `EMBEDDINGS_OPENCLIP_DEVICE`: `device`
</Accordion>
<Accordion title="Text2Vec">
```python main.py
from crewai.rag.embeddings.providers.text2vec.types import Text2VecProviderSpec
embedding_model: Text2VecProviderSpec = {
"provider": "text2vec",
"config": {
"model_name": "shibing624/text2vec-base-multilingual"
}
}
```
**Opções de Configuração:**
- `model_name` (str): Nome do modelo Text2Vec do HuggingFace. Padrão: `shibing624/text2vec-base-chinese`. Opções: `shibing624/text2vec-base-multilingual`, `shibing624/text2vec-base-chinese`
**Variáveis de Ambiente:**
- `EMBEDDINGS_TEXT2VEC_MODEL_NAME`: `model_name`
</Accordion>
<Accordion title="Roboflow">
```python main.py
from crewai.rag.embeddings.providers.roboflow.types import RoboflowProviderSpec
embedding_model: RoboflowProviderSpec = {
"provider": "roboflow",
"config": {
"api_key": "your-api-key",
"api_url": "https://infer.roboflow.com"
}
}
```
**Opções de Configuração:**
- `api_key` (str): Chave da API Roboflow. Padrão: `""` (string vazia)
- `api_url` (str): URL da API de inferência do Roboflow. Padrão: `https://infer.roboflow.com`
**Variáveis de Ambiente:**
- `ROBOFLOW_API_KEY` ou `EMBEDDINGS_ROBOFLOW_API_KEY`: `api_key`
- `ROBOFLOW_API_URL` ou `EMBEDDINGS_ROBOFLOW_API_URL`: `api_url`
</Accordion>
<Accordion title="WatsonX (IBM)">
```python main.py
from crewai.rag.embeddings.providers.ibm.types import WatsonXProviderSpec
embedding_model: WatsonXProviderSpec = {
"provider": "watsonx",
"config": {
"model_id": "ibm/slate-125m-english-rtrvr",
"url": "https://us-south.ml.cloud.ibm.com",
"api_key": "your-api-key",
"project_id": "your-project-id",
"batch_size": 100,
"concurrency_limit": 10,
"persistent_connection": True
}
}
```
**Opções de Configuração:**
- `model_id` (str): Identificador do modelo WatsonX
- `url` (str): Endpoint da API WatsonX
- `api_key` (str): Chave da API IBM Cloud
- `project_id` (str): ID do projeto WatsonX
- `space_id` (str): ID do espaço WatsonX (alternativa ao project_id)
- `batch_size` (int): Tamanho do lote para embeddings. Padrão: `100`
- `concurrency_limit` (int): Número máximo de solicitações simultâneas. Padrão: `10`
- `persistent_connection` (bool): Utilizar conexões persistentes. Padrão: `True`
- Mais de 20 opções adicionais de autenticação e configuração
**Variáveis de Ambiente:**
- `WATSONX_API_KEY` ou `EMBEDDINGS_WATSONX_API_KEY`: `api_key`
- `WATSONX_URL` ou `EMBEDDINGS_WATSONX_URL`: `url`
- `WATSONX_PROJECT_ID` ou `EMBEDDINGS_WATSONX_PROJECT_ID`: `project_id`
- `EMBEDDINGS_WATSONX_MODEL_ID`: `model_id`
- `EMBEDDINGS_WATSONX_SPACE_ID`: `space_id`
- `EMBEDDINGS_WATSONX_BATCH_SIZE`: `batch_size`
- `EMBEDDINGS_WATSONX_CONCURRENCY_LIMIT`: `concurrency_limit`
- `EMBEDDINGS_WATSONX_PERSISTENT_CONNECTION`: `persistent_connection`
</Accordion>
<Accordion title="Personalizado">
```python main.py
from crewai.rag.core.base_embeddings_callable import EmbeddingFunction
from crewai.rag.embeddings.providers.custom.types import CustomProviderSpec
class MyEmbeddingFunction(EmbeddingFunction):
def __call__(self, input):
# Your custom embedding logic
return embeddings
embedding_model: CustomProviderSpec = {
"provider": "custom",
"config": {
"embedding_callable": MyEmbeddingFunction
}
}
```
**Opções de Configuração:**
- `embedding_callable` (type[EmbeddingFunction]): Classe da função de embedding personalizada
**Observação:** As funções de embedding personalizadas devem implementar o protocolo `EmbeddingFunction` definido em `crewai.rag.core.base_embeddings_callable`. O método `__call__` deve aceitar dados de entrada e retornar embeddings como uma lista de arrays numpy (ou um formato compatível que será normalizado). Os embeddings retornados são normalizados e validados automaticamente.
</Accordion>
</AccordionGroup>
### Observações
- Todos os campos de configuração são opcionais, a menos que estejam marcados como **Obrigatório**
- Normalmente, as chaves de API podem ser fornecidas por meio de variáveis de ambiente em vez da configuração
- Os valores padrão são exibidos quando aplicável
## Conclusão
O `RagTool` oferece uma maneira poderosa de criar e consultar bases de conhecimento a partir de diversas fontes de dados. Ao explorar a Geração Aumentada por Recuperação, ele permite que agentes acessem e recuperem informações relevantes de forma eficiente, ampliando a capacidade de fornecer respostas precisas e contextualmente apropriadas.
O `RagTool` oferece uma maneira poderosa de criar e consultar bases de conhecimento a partir de diversas fontes de dados. Ao explorar a Geração Aumentada por Recuperação, ele permite que agentes acessem e recuperem informações relevantes de forma eficiente, ampliando a capacidade de fornecer respostas precisas e contextualmente apropriadas.

View File

@@ -12,6 +12,16 @@ mode: "wide"
Esta ferramenta é utilizada para extrair texto de imagens. Quando passada para o agente, ela extrai o texto da imagem e depois o utiliza para gerar uma resposta, relatório ou qualquer outra saída.
A URL ou o CAMINHO da imagem deve ser passado para o Agente.
Você também pode fazer uma `query` personalizada sobre a imagem e escolher um `complexity_level` que seleciona automaticamente o modelo mais adequado para a solicitação:
| Nível de complexidade | Modelo |
| :--------------- | :------------ |
| `easy` | `gpt-5.6-luna` |
| `medium` (padrão) | `gpt-5.6-terra` |
| `hard` | `gpt-5.6-sol` |
Quando um `llm` ou `model` explícito é fornecido à ferramenta, ele tem precedência sobre a seleção de modelo baseada na complexidade.
## Instalação
Instale o pacote crewai_tools
@@ -43,8 +53,10 @@ def researcher(self) -> Agent:
## Argumentos
O VisionTool requer os seguintes argumentos:
O VisionTool aceita os seguintes argumentos:
| Argumento | Tipo | Descrição |
| :------------------ | :------- | :------------------------------------------------------------------------------- |
| **image_path_url** | `string` | **Obrigatório**. O caminho para o arquivo de imagem do qual o texto será extraído. |
| **image_path_url** | `string` | **Obrigatório**. O caminho para o arquivo de imagem (ou URL) do qual o texto será extraído. |
| **query** | `string` | **Opcional**. A pergunta ou instrução a ser feita ao modelo sobre a imagem. O padrão é `"What's in this image?"`. |
| **complexity_level** | `string` | **Opcional**. A complexidade da solicitação, que seleciona o modelo: `easy`, `medium` ou `hard`. O padrão é `medium`. |

View File

@@ -4,7 +4,7 @@ description: >
Os Scrapers da Oxylabs permitem acessar facilmente informações de fontes específicas. Veja abaixo a lista de fontes disponíveis:
- `Amazon Product`
- `Amazon Search`
- `Google Seach`
- `Google Search`
- `Universal`
icon: globe
mode: "wide"
@@ -87,7 +87,7 @@ print(result)
### Parâmetros
- `query` - termo de busca da Amazon.
- `domain` - Domínio de localização para Bestbuy.
- `domain` - domínio de localização da Amazon.
- `start_page` - número da página inicial.
- `pages` - quantidade de páginas a ser recuperada.
- `geo_location` - local de entrega (_Deliver to_).

View File

@@ -1,117 +1,148 @@
---
title: Channels
description: Run the same CrewAI agent as a chat bot on Slack and Discord with the CopilotKit Channels SDK.
icon: slack
description: Run the same CrewAI agent as a Slack or Teams bot with the CopilotKit Channels SDK and managed Intelligence platform.
icon: messages
mode: "wide"
---
## Meet your users where they already are
The CrewAI agent you built in the [Overview](/edge/en/guides/frontend/overview) does not have to live behind a web app. The same Crew or Flow can run as a bot inside a messaging platform. No rebuild, no second copy of your agent logic: the agent stays exposed over the [AG-UI protocol](https://docs.ag-ui.com), and a bot process drives it.
The CrewAI agent you built in the [Overview](/edge/en/guides/frontend/overview) does not have to live behind a web app. The same Crew or Flow can run as a bot inside a messaging platform. No rebuild, no second copy of your agent logic: the agent stays exposed over the [AG-UI protocol](https://docs.ag-ui.com), and a **channel** drives it from Slack or Microsoft Teams.
CopilotKit's [Channels SDK](https://docs.copilotkit.ai/reference/channels) provides that bot process. It ships a platform-agnostic engine plus per-platform adapters.
CopilotKit's [Channels SDK](https://docs.copilotkit.ai/slack) provides that channel. You declare a `createChannel` in a small runtime, point it at your CrewAI agent, and CopilotKit's managed **Intelligence** platform brokers the connection to the messaging provider.
<Note>
Unlike the rest of this section, Channels is **not self-hosted**. It runs through **CopilotKit Intelligence** — a required surface for Channels, by design (a free tier is available). Intelligence holds the platform connection and credentials, receives each platform event, and delivers the turn to your channel process; your process runs the agent and streams the reply back. You configure Slack once in the Intelligence dashboard, and platform credentials never enter your process. Your agent, tools, and state stay yours.
</Note>
## How it fits together
Nothing about your agent server changes. It keeps serving your Crew or Flow over AG-UI exactly as in the Overview. What you add is a separate **bot process**: it connects to a platform adapter, listens for messages, and runs your agent when it is messaged. The reply streams back into the channel.
Nothing about your CrewAI agent server changes. It keeps serving your Crew or Flow over AG-UI exactly as in the Overview. What you add is a separate long-running Node process built with `@copilotkit/channels`: it registers a channel on the `CopilotRuntime`, connects to Intelligence, and runs your agent whenever a message arrives.
```
Slack / Discord ──► Channels bot process ──► CrewAI server (AG-UI) ──► Crew / Flow
Slack / Teams ──► CopilotKit Intelligence ──► channel process (Node) ──► CrewAI server (AG-UI) ──► Crew / Flow
```
Your agent server can keep serving the web frontend from the Overview at the same time. The web app and the bot are just two clients of one AG-UI endpoint.
The channel process holds a persistent connection to the Intelligence gateway, so it needs a long-running host — a serverless request handler cannot own that connection. Your CrewAI server can keep serving the web frontend from the Overview at the same time: the web app and the channel are just two clients of one AG-UI endpoint.
## Slack
## Integration guide
<Steps>
<Step title="Install the Channels packages">
The Channels SDK is batteries-included — every platform ships in the one package, with no per-platform adapter to install. Add it alongside the runtime that hosts the channel and the CrewAI AG-UI client:
```bash
npm install @copilotkit/channels @copilotkit/channels-slack @ag-ui/crewai
npm install @copilotkit/channels @copilotkit/runtime @ag-ui/crewai
```
</Step>
<Step title="Create a Slack app and get tokens">
<Step title="Create a Channel in Intelligence">
Create an app in the Slack API dashboard for your workspace, enable Socket Mode, and grant it the message and event scopes it needs to read and post in channels. Then expose its tokens to the bot process:
In the [CopilotKit dashboard](https://docs.copilotkit.ai/slack), create a Channel and connect Slack — Intelligence walks you through creating the Slack app and holds its credentials. That leaves two environment variables for your process, both from the dashboard:
```bash
export SLACK_BOT_TOKEN=xoxb-... # bot user token
export SLACK_APP_TOKEN=xapp-... # app-level token (Socket Mode)
export INTELLIGENCE_API_KEY=... # authenticates the runtime with Intelligence (free tier available)
export INTELLIGENCE_CHANNEL_ID=... # the Channel ID, matched by createChannel({ name })
```
</Step>
<Step title="Point the bot at your CrewAI agent">
<Step title="Define the channel">
`createBot` wires a Slack adapter to your agent. The `agent` factory returns a `CrewAIAgent` pointed at the AG-UI path your server exposes (the same URL you registered in the runtime in the Overview).
`createChannel` declares the channel and attaches your agent. Build the agent as a per-thread factory so each conversation gets its own session, using the same `CrewAIAgent` the Overview uses in the web runtime, pointed at your AG-UI endpoint. `identifyUser: "platform"` lets Intelligence map each platform user to a stable identity.
```ts
// bot.ts
import { createBot } from "@copilotkit/channels";
import { slack, defaultSlackTools, defaultSlackContext } from "@copilotkit/channels-slack";
// channel.ts
import { createChannel } from "@copilotkit/channels";
import { CrewAIAgent } from "@ag-ui/crewai";
const bot = createBot({
adapters: [
slack({
botToken: process.env.SLACK_BOT_TOKEN!, // xoxb-…
appToken: process.env.SLACK_APP_TOKEN!, // xapp-… (Socket Mode)
}),
],
agent: (threadId) => new CrewAIAgent({ url: "http://localhost:8000/recipe" }),
tools: [...defaultSlackTools],
context: [...defaultSlackContext],
const channel = createChannel({
name: process.env.INTELLIGENCE_CHANNEL_ID!, // must match the Channel ID in Intelligence
identifyUser: "platform",
// A fresh agent per conversation, pointed at your CrewAI AG-UI endpoint.
agent: (threadId) => {
const agent = new CrewAIAgent({ url: "http://localhost:8000/recipe" });
agent.threadId = threadId;
return agent;
},
});
bot.start();
// A mention subscribes the thread and runs the agent; afterwards every message
// in a subscribed thread runs it without needing another mention.
channel.onMention(async ({ thread }) => {
await thread.subscribe();
await thread.runAgent();
});
channel.onMessage(async ({ thread }) => {
if (await thread.isSubscribed()) await thread.runAgent();
});
export { channel };
```
</Step>
<Step title="Run the bot">
<Step title="Register the channel on the runtime">
Start the bot process alongside your agent server:
Create a `CopilotRuntime` with the Intelligence gateway and your channel, then serve it with `createCopilotNodeListener`. The `agents` map stays empty — the channel supplies its own agent. Wait for the channel to be ready so a broken config fails startup loudly.
```ts
// server.ts
import { createServer } from "node:http";
import { CopilotRuntime, CopilotKitIntelligence } from "@copilotkit/runtime/v2";
import { createCopilotNodeListener } from "@copilotkit/runtime/v2/node";
import { channel } from "./channel";
const runtime = new CopilotRuntime({
agents: {}, // the channel supplies its own agent; no web-facing agents needed
intelligence: new CopilotKitIntelligence({
apiKey: process.env.INTELLIGENCE_API_KEY!, // free tier available
}),
channels: [channel],
});
const listener = createCopilotNodeListener({ runtime });
await listener.channels?.ready({ timeoutMs: 15_000 });
createServer(listener).listen(3123, () => {
console.log("Channels runtime listening on port 3123");
});
```
</Step>
<Step title="Run the channel runtime">
Start it alongside your CrewAI agent server:
```bash
uvicorn server:app --port 8000 # terminal 1 — CrewAI agent server
node bot.ts # terminal 2 — Slack bot
npx tsx server.ts # terminal 2 — Channels runtime
```
Message the bot in Slack and it runs your Crew or Flow, streaming the reply back into the thread.
Mention the bot in Slack or Teams and it runs your Crew or Flow, streaming the reply back into the thread. The thread stays subscribed, so follow-up messages run without another mention.
</Step>
</Steps>
<Note>
Slack app scopes, Socket Mode setup, and the full adapter options are maintained by CopilotKit. Follow the [Slack channel reference](https://docs.copilotkit.ai/reference/channels/slack) together with Slack's own app setup guide for the authoritative steps.
</Note>
## The event model
## Discord
A channel reacts to platform events with handlers, and each handler receives a `thread` you drive with a few methods:
Discord uses the same `createBot` engine with the Discord adapter from `@copilotkit/channels-discord`:
- **`channel.onMention`** fires when a user @-mentions the bot. Call `thread.subscribe()` to join the thread, then `thread.runAgent()` to run your CrewAI agent on the mention.
- **`channel.onMessage`** fires on every message in a thread the bot can see. Gate it with `thread.isSubscribed()` so the agent only responds where it has joined, then `thread.runAgent()`.
- **`thread.runAgent()`** runs the attached CrewAI agent for the current turn and streams its output back into the channel. Pass `{ prompt }` to override the text the agent runs on.
```ts
import { createBot } from "@copilotkit/channels";
import { discord } from "@copilotkit/channels-discord";
import { CrewAIAgent } from "@ag-ui/crewai";
const bot = createBot({
adapters: [discord({ token: process.env.DISCORD_BOT_TOKEN! })],
agent: (threadId) => new CrewAIAgent({ url: "http://localhost:8000/recipe" }),
});
bot.start();
```
See the [Discord channel reference](https://docs.copilotkit.ai/reference/channels/discord) for the exact adapter options and bot setup.
Your agent receives an ordinary AG-UI `RunAgentInput` and emits ordinary AG-UI events; the platform mechanics stay behind the channel, so the same Crew or Flow runs unchanged across every platform. The channel also exposes handlers for welcomes, interrupts, commands, reactions, and modals — see the [`Channel` reference](https://docs.copilotkit.ai/reference/channels/classes/Channel) for the full surface.
## Platform support
Slack and Discord have official Channels adapters (`@copilotkit/channels-slack`, `@copilotkit/channels-discord`). Microsoft Teams is available through CopilotKit's managed offering (currently waitlisted). Check the [Channels reference](https://docs.copilotkit.ai/reference/channels) for the current list before promising a platform.
The managed Intelligence path covers **Slack** and **Microsoft Teams** today — the same channel code runs on either, and `message.platform` / `thread.platform` report the native origin. Other messaging platforms connect the same managed way, with your channel code unchanged. Check the [CopilotKit Channels documentation](https://docs.copilotkit.ai/slack) for the current platform list and per-platform setup.
## Related

View File

@@ -21,7 +21,7 @@ The two connect through the [AG-UI protocol](https://docs.ag-ui.com). The `ag-ui
<Card title="Shared State" icon="arrows-rotate" href="/edge/en/guides/frontend/shared-state">
Keep agent state and your app UI in two-way sync.
</Card>
<Card title="Channels" icon="slack" href="/edge/en/guides/frontend/channels">
<Card title="Channels" icon="messages" href="/edge/en/guides/frontend/channels">
Run the same agent as a Slack, Discord, or Teams bot.
</Card>
</CardGroup>

View File

@@ -0,0 +1,8 @@
---
title: "GET /inputs"
description: "الحصول على المدخلات المطلوبة لطاقمك"
openapi: "/v1.15.19/enterprise-api.en.yaml GET /inputs"
mode: "wide"
---

View File

@@ -0,0 +1,135 @@
---
title: "مقدمة"
description: "المرجع الكامل لواجهة برمجة تطبيقات CrewAI AMP REST"
icon: "code"
mode: "wide"
---
# واجهة برمجة تطبيقات CrewAI AMP
مرحبًا بك في مرجع واجهة برمجة تطبيقات CrewAI AMP. تتيح لك هذه الواجهة التفاعل برمجيًا مع الأطقم المنشورة، مما يمكّنك من دمجها مع تطبيقاتك وسير عملك وخدماتك.
## البدء السريع
<Steps>
<Step title="الحصول على بيانات اعتماد API">
انتقل إلى صفحة تفاصيل طاقمك في لوحة تحكم CrewAI AMP وانسخ رمز Bearer من علامة تبويب الحالة.
</Step>
<Step title="اكتشاف المدخلات المطلوبة">
استخدم نقطة النهاية `GET /inputs` لمعرفة المعاملات التي يتوقعها طاقمك.
</Step>
<Step title="بدء تنفيذ الطاقم">
استدعِ `POST /kickoff` مع مدخلاتك لبدء تنفيذ الطاقم واستلام
`kickoff_id`.
</Step>
<Step title="مراقبة التقدم">
استخدم `GET /status/{kickoff_id}` للتحقق من حالة التنفيذ واسترجاع النتائج.
</Step>
</Steps>
## المصادقة
تتطلب جميع طلبات API المصادقة باستخدام رمز Bearer. أدرج رمزك في ترويسة `Authorization`:
```bash
curl -H "Authorization: Bearer YOUR_CREW_TOKEN" \
https://your-crew-url.crewai.com/inputs
```
### أنواع الرموز
| نوع الرمز | النطاق | حالة الاستخدام |
| :-------------------- | :------------------------ | :----------------------------------------------------------- |
| **Bearer Token** | وصول على مستوى المؤسسة | عمليات الطاقم الكاملة، مثالي للتكامل بين الخوادم |
| **User Bearer Token** | وصول محدد بالمستخدم | صلاحيات محدودة، مناسب للعمليات الخاصة بالمستخدم |
<Tip>
يمكنك العثور على كلا نوعي الرموز في علامة تبويب الحالة من صفحة تفاصيل طاقمك في
لوحة تحكم CrewAI AMP.
</Tip>
## عنوان URL الأساسي
لكل طاقم منشور نقطة نهاية API فريدة خاصة به:
```
https://your-crew-name.crewai.com
```
استبدل `your-crew-name` بعنوان URL الفعلي لطاقمك من لوحة التحكم.
## سير العمل النموذجي
1. **الاكتشاف**: استدعِ `GET /inputs` لفهم ما يحتاجه طاقمك
2. **التنفيذ**: أرسل المدخلات عبر `POST /kickoff` لبدء المعالجة
3. **المراقبة**: استعلم عن `GET /status/{kickoff_id}` حتى الاكتمال
4. **النتائج**: استخرج المخرجات النهائية من الاستجابة المكتملة
## معالجة الأخطاء
تستخدم الواجهة أكواد حالة HTTP القياسية:
| الكود | المعنى |
| ----- | :----------------------------------------- |
| `200` | نجاح |
| `400` | طلب غير صالح - تنسيق مدخلات غير صحيح |
| `401` | غير مصرّح - رمز bearer غير صالح |
| `404` | غير موجود - المورد غير موجود |
| `422` | خطأ في التحقق - مدخلات مطلوبة مفقودة |
| `500` | خطأ في الخادم - تواصل مع الدعم |
## الاختبار التفاعلي
<Info>
**لماذا لا يوجد زر "إرسال"؟** نظرًا لأن كل مستخدم CrewAI AMP لديه عنوان URL
فريد للطاقم، نستخدم **وضع المرجع** بدلاً من بيئة تفاعلية لتجنب
الالتباس. يوضح لك هذا بالضبط كيف يجب أن تبدو الطلبات بدون
أزرار إرسال غير فعالة.
</Info>
تعرض لك كل صفحة نقطة نهاية:
- **تنسيق الطلب الدقيق** مع جميع المعاملات
- **أمثلة الاستجابة** لحالات النجاح والخطأ
- **عينات الكود** بلغات متعددة (cURL، Python، JavaScript، إلخ)
- **أمثلة المصادقة** بتنسيق رمز Bearer الصحيح
### **لاختبار واجهتك الفعلية:**
<CardGroup cols={2}>
<Card title="نسخ أمثلة cURL" icon="terminal">
انسخ أمثلة cURL واستبدل العنوان URL + الرمز بقيمك الحقيقية
</Card>
<Card title="استخدام Postman/Insomnia" icon="play">
استورد الأمثلة في أداة اختبار API المفضلة لديك
</Card>
</CardGroup>
**مثال على سير العمل:**
1. **انسخ مثال cURL هذا** من أي صفحة نقطة نهاية
2. **استبدل `your-actual-crew-name.crewai.com`** بعنوان URL الحقيقي لطاقمك
3. **استبدل رمز Bearer** برمزك الحقيقي من لوحة التحكم
4. **نفّذ الطلب** في طرفيتك أو عميل API
## هل تحتاج مساعدة؟
<CardGroup cols={2}>
<Card
title="دعم المؤسسات"
icon="headset"
href="mailto:support@crewai.com"
>
احصل على مساعدة في تكامل API واستكشاف الأخطاء وإصلاحها
</Card>
<Card
title="لوحة تحكم المؤسسات"
icon="chart-line"
href="https://app.crewai.com"
>
إدارة أطقمك وعرض سجلات التنفيذ
</Card>
</CardGroup>

View File

@@ -0,0 +1,8 @@
---
title: "POST /kickoff"
description: "بدء تنفيذ الطاقم"
openapi: "/v1.15.19/enterprise-api.en.yaml POST /kickoff"
mode: "wide"
---

View File

@@ -0,0 +1,6 @@
---
title: "POST /resume"
description: "استئناف تنفيذ الطاقم مع التغذية الراجعة البشرية"
openapi: "/v1.15.19/enterprise-api.en.yaml POST /resume"
mode: "wide"
---

View File

@@ -0,0 +1,6 @@
---
title: "GET /status/{kickoff_id}"
description: "الحصول على حالة التنفيذ"
openapi: "/v1.15.19/enterprise-api.en.yaml GET /status/{kickoff_id}"
mode: "wide"
---

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,147 @@
---
title: "قدرات الوكيل"
description: "فهم الطرق الخمس لتوسيع وكلاء CrewAI: الأدوات، MCP، التطبيقات، المهارات، والمعرفة."
icon: puzzle-piece
mode: "wide"
---
## نظرة عامة
يمكن توسيع وكلاء CrewAI بـ **خمسة أنواع مميزة من القدرات**، كل منها يخدم غرضًا مختلفًا. فهم متى تستخدم كل نوع — وكيف يعملون معًا — هو المفتاح لبناء وكلاء فعّالين.
<CardGroup cols={2}>
<Card title="الأدوات" icon="wrench" href="/ar/concepts/tools" color="#3B82F6">
**دوال قابلة للاستدعاء** — تمنح الوكلاء القدرة على اتخاذ إجراءات. البحث على الويب، عمليات الملفات، استدعاءات API، تنفيذ الكود.
</Card>
<Card title="خوادم MCP" icon="plug" href="/ar/mcp/overview" color="#8B5CF6">
**خوادم أدوات عن بُعد** — تربط الوكلاء بخوادم أدوات خارجية عبر Model Context Protocol. نفس تأثير الأدوات، لكن مستضافة خارجيًا.
</Card>
<Card title="التطبيقات" icon="grid-2" color="#EC4899">
**تكاملات المنصة** — تربط الوكلاء بتطبيقات SaaS (Gmail، Slack، Jira، Salesforce) عبر منصة CrewAI. تعمل محليًا مع رمز تكامل المنصة.
</Card>
<Card title="المهارات" icon="bolt" href="/ar/concepts/skills" color="#F59E0B">
**خبرة المجال** — تحقن التعليمات والإرشادات والمواد المرجعية في إرشادات الوكلاء. المهارات تخبر الوكلاء *كيف يفكرون*.
</Card>
<Card title="المعرفة" icon="book" href="/ar/concepts/knowledge" color="#10B981">
**حقائق مُسترجعة** — توفر للوكلاء بيانات من المستندات والملفات وعناوين URL عبر البحث الدلالي (RAG). المعرفة تعطي الوكلاء *ما يحتاجون معرفته*.
</Card>
</CardGroup>
---
## التمييز الأساسي
أهم شيء يجب فهمه: **هذه القدرات تنقسم إلى فئتين**.
### قدرات الإجراء (الأدوات، MCP، التطبيقات)
تمنح الوكلاء القدرة على **فعل أشياء** — استدعاء APIs، قراءة الملفات، البحث على الويب، إرسال رسائل البريد الإلكتروني. عند التنفيذ، تتحول الأنواع الثلاثة إلى نفس التنسيق الداخلي (مثيلات `BaseTool`) وتظهر في قائمة أدوات موحدة يمكن للوكيل استدعاؤها.
```python
from crewai import Agent
from crewai_tools import SerperDevTool, FileReadTool
agent = Agent(
role="Researcher",
goal="Find and compile market data",
backstory="Expert market analyst",
tools=[SerperDevTool(), FileReadTool()], # أدوات محلية
mcps=["https://mcp.example.com/sse"], # أدوات خادم MCP عن بُعد
apps=["gmail", "google_sheets"], # تكاملات المنصة
)
```
### قدرات السياق (المهارات، المعرفة)
تُعدّل **إرشادات** الوكيل — بحقن الخبرة أو التعليمات أو البيانات المُسترجعة قبل أن يبدأ الوكيل في التفكير. لا تمنح الوكلاء إجراءات جديدة؛ بل تُشكّل كيف يفكر الوكلاء وما هي المعلومات التي يمكنهم الوصول إليها.
```python
from crewai import Agent
agent = Agent(
role="Security Auditor",
goal="Audit cloud infrastructure for vulnerabilities",
backstory="Expert in cloud security with 10 years of experience",
skills=["./skills/security-audit"], # تعليمات المجال
knowledge_sources=[pdf_source, url_source], # حقائق مُسترجعة
)
```
---
## متى تستخدم ماذا
| تحتاج إلى... | استخدم | مثال |
| :------------------------------------------------------- | :---------------- | :--------------------------------------- |
| الوكيل يبحث على الويب | **الأدوات** | `tools=[SerperDevTool()]` |
| الوكيل يستدعي API عن بُعد عبر MCP | **MCP** | `mcps=["https://api.example.com/sse"]` |
| الوكيل يرسل بريد إلكتروني عبر Gmail | **التطبيقات** | `apps=["gmail"]` |
| الوكيل يتبع إجراءات محددة | **المهارات** | `skills=["./skills/code-review"]` |
| الوكيل يرجع لمستندات الشركة | **المعرفة** | `knowledge_sources=[pdf_source]` |
| الوكيل يبحث على الويب ويتبع إرشادات المراجعة | **الأدوات + المهارات** | استخدم كليهما معًا |
---
## دمج القدرات
في الممارسة العملية، غالبًا ما يستخدم الوكلاء **أنواعًا متعددة من القدرات معًا**. إليك مثال واقعي:
```python
from crewai import Agent
from crewai_tools import SerperDevTool, FileReadTool, CodeInterpreterTool
# وكيل بحث مجهز بالكامل
researcher = Agent(
role="Senior Research Analyst",
goal="Produce comprehensive market analysis reports",
backstory="Expert analyst with deep industry knowledge",
# الإجراء: ما يمكن للوكيل فعله
tools=[
SerperDevTool(), # البحث على الويب
FileReadTool(), # قراءة الملفات المحلية
CodeInterpreterTool(), # تشغيل كود Python للتحليل
],
mcps=["https://data-api.example.com/sse"], # الوصول لـ API بيانات عن بُعد
apps=["google_sheets"], # الكتابة في Google Sheets
# السياق: ما يعرفه الوكيل
skills=["./skills/research-methodology"], # كيفية إجراء البحث
knowledge_sources=[company_docs], # بيانات خاصة بالشركة
)
```
---
## جدول المقارنة
| الميزة | الأدوات | MCP | التطبيقات | المهارات | المعرفة |
| :--- | :---: | :---: | :---: | :---: | :---: |
| **يمنح الوكيل إجراءات** | ✅ | ✅ | ✅ | ❌ | ❌ |
| **يُعدّل الإرشادات** | ❌ | ❌ | ❌ | ✅ | ✅ |
| **يتطلب كود** | نعم | إعداد فقط | إعداد فقط | Markdown فقط | إعداد فقط |
| **يعمل محليًا** | نعم | يعتمد | نعم (مع متغير بيئة) | غير متاح | نعم |
| **يحتاج مفاتيح API** | لكل أداة | لكل خادم | رمز التكامل | لا | المُضمّن فقط |
| **يُعيَّن على Agent** | `tools=[]` | `mcps=[]` | `apps=[]` | `skills=[]` | `knowledge_sources=[]` |
| **يُعيَّن على Crew** | ❌ | ❌ | ❌ | `skills=[]` | `knowledge_sources=[]` |
---
## تعمّق أكثر
هل أنت مستعد لمعرفة المزيد عن كل نوع من أنواع القدرات؟
<CardGroup cols={2}>
<Card title="الأدوات" icon="wrench" href="/ar/concepts/tools">
إنشاء أدوات مخصصة، استخدام كتالوج OSS مع أكثر من 75 خيارًا، تكوين التخزين المؤقت والتنفيذ غير المتزامن.
</Card>
<Card title="تكامل MCP" icon="plug" href="/ar/mcp/overview">
الاتصال بخوادم MCP عبر stdio أو SSE أو HTTP. تصفية الأدوات، تكوين المصادقة.
</Card>
<Card title="المهارات" icon="bolt" href="/ar/concepts/skills">
بناء حزم المهارات مع SKILL.md، حقن خبرة المجال، استخدام الكشف التدريجي.
</Card>
<Card title="المعرفة" icon="book" href="/ar/concepts/knowledge">
إضافة المعرفة من ملفات PDF وCSV وعناوين URL والمزيد. تكوين المُضمّنات والاسترجاع.
</Card>
</CardGroup>

Some files were not shown because too many files have changed in this diff Show More