Compare commits

..

110 Commits

Author SHA1 Message Date
Vinicius Brasil
386a1650da Add script/code blocks to FlowDefinition
Let a Flow method run trusted inline Python with `call: script`. The code
is compiled once into a generated function and receives the runtime
values as arguments.

```yaml
methods:
  normalize:
    start: true
    do:
      call: script
      code: |
        import math
        state["rounded"] = math.ceil(state["raw_score"])
        return f"rounded:{state['rounded']}"
```

Even though this shares the same surface of tools (custom code), I
decided to make it opt-in for now, using
`CREWAI_ALLOW_FLOW_SCRIPT_EXECUTION=1`.
2026-06-16 22:12:44 -07:00
Vinicius Brasil
7bb9bc7e1a Discriminate FlowDefinition state types (#6196)
Some checks are pending
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (python) (push) Waiting to run
Check Documentation Broken Links / Check broken links (push) Waiting to run
Vulnerability Scan / pip-audit (push) Waiting to run
Replace the single FlowStateDefinition model with a `type`-discriminated
union of FlowDictStateDefinition, FlowPydanticStateDefinition,
FlowJsonSchemaStateDefinition, and FlowUnknownStateDefinition.

Each branch only carries the fields it actually uses and forbids extras,
so an invalid combination like a `dict` state with a `ref` now fails
validation instead of being silently accepted. The runtime reads `ref`
and `json_schema` defensively since they no longer exist on every branch.

```yaml
state:
  type: json_schema
  json_schema:
    type: object
    properties:
      topic:
        type: string
```

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 21:31:07 -07:00
João Moura
ee4f853270 Update installation and quickstart documentation for JSON-first crew projects (#6181)
* Update installation and quickstart documentation for JSON-first crew projects

- Revised the installation guide to reflect the new JSON-first project structure, detailing the creation of `crew.jsonc` and `agents/*.jsonc` files.
- Updated the quickstart guide to demonstrate setting up agents and tasks using JSONC format, replacing previous YAML examples.
- Enhanced the agents and tasks documentation to clarify the transition from YAML to JSONC, including examples and explanations of the new structure.
- Added notes on the classic YAML structure for legacy projects and provided guidance on migrating to the new format.

* docs: clarify json crew quickstart guidance

* docs: address json docs review feedback
2026-06-16 19:55:23 -03:00
João Moura
ebbc0998ef Implement DMN mode support in crew creation and execution (#6194)
* Implement DMN mode support in crew creation and execution

- Added `is_dmn_mode_enabled` utility to check for enterprise non-interactive mode based on the `CREWAI_DMN` environment variable.
- Updated `create` function in `cli.py` to enforce required parameters when DMN mode is active, raising appropriate usage errors.
- Enhanced `create_crew` and `create_json_crew` functions to skip provider prompts and handle folder existence checks in DMN mode.
- Introduced non-interactive defaults for agent and task creation in DMN mode, ensuring seamless project setup without user input.
- Modified `run_crew` to bypass TUI and handle runtime inputs directly when in DMN mode, improving execution flow for JSON-defined crews.
- Added tests to validate DMN mode behavior, ensuring correct handling of required inputs and non-interactive defaults.

* Implement DMN mode support in crew creation and execution

- Introduced `is_dmn_mode_enabled()` utility to check for non-interactive mode based on the `CREWAI_DMN` environment variable.
- Updated `create` function to enforce required parameters when DMN mode is active, raising appropriate usage errors.
- Modified `create_crew` and `create_json_crew` functions to skip provider prompts and utilize non-interactive defaults in DMN mode.
- Enhanced `run_crew` to bypass TUI and handle runtime inputs directly in DMN mode, ensuring smooth execution without user interaction.
- Added tests to validate DMN mode behavior, including requirements for type and name, and ensuring proper handling of existing folders and missing inputs.
2026-06-16 19:48:31 -03:00
João Moura
06ada68083 Enhance crew loading and validation logic (#6182)
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
* Enhance crew loading and validation logic

- Updated `crew_loader.py` to pass the project root when loading task and agent definitions, improving the handling of Python references.
- Refactored `json_loader.py` to include additional validation for Python references, ensuring they are resolved within the project root and enforcing depth limits.
- Added tests in `test_crew_loader.py` and `test_json_loader.py` to validate rejection of unsafe Python references and input files outside the project root.
- Improved error handling for JSON project validation, ensuring clearer feedback for invalid configurations.

* Refactor tests for hierarchical verbose manager agent

- Removed `@pytest.mark.vcr()` decorators from `test_hierarchical_verbose_manager_agent` and `test_hierarchical_verbose_false_manager_agent`.
- Introduced mocking for task outputs in both tests to simulate execution without relying on external dependencies.
- Ensured that the `crew.kickoff()` method is called within a context that patches the `Task.execute_sync` method, improving test isolation and reliability.

* Fix JSON loader PR review comments

* Fix JSON loader project root after rebase

* Handle UNC paths in JSON input files
2026-06-16 18:45:26 -03:00
Vinicius Brasil
4eb90ffbf3 Add crew actions to FlowDefinition (#6184) 2026-06-16 12:59:48 -07:00
Vinicius Brasil
a6cf52ec7e Add inline crew definition loading (#6183) 2026-06-16 11:51:22 -07:00
Vinicius Brasil
9d44d0a5e5 Serialize concrete Pydantic subclasses (#6187) 2026-06-16 11:00:07 -07:00
João Moura
e9d568dc69 Deep Crew / Agent / Task attributes support on json (#6172)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Nightly Canary Release / Check for new commits (push) Has been cancelled
Nightly Canary Release / Build nightly packages (push) Has been cancelled
Nightly Canary Release / Publish nightly to PyPI (push) Has been cancelled
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
* Enhance JSON crew project handling and validation

- Updated `create_json_crew.py` to specify input files with a brief path.
- Refactored `crew_loader.py` to improve agent and task loading logic, including the introduction of a `build_agent` function and better handling of task classes.
- Enhanced `json_loader.py` with additional validation for agent and task definitions, including support for Python references and conditional tasks.
- Added tests in `test_crew_loader.py` and `test_json_loader.py` to ensure proper loading of agents, tasks, and validation of project structures, including custom types and conditional tasks.
- Improved error handling and validation safety across the project loading process.

* Enhance JSON crew configuration options in create_json_crew.py

- Added optional fields for custom agent subclasses and advanced task options, including condition checks and output specifications.
- Improved documentation comments for better clarity on agent and task configurations.
- Updated JSON crew handling to support additional callbacks for pre- and post-execution processes.

* Enhance JSON crew template tests in test_create_crew.py

- Added assertions for new optional fields in crew and agent templates, including conditional tasks, custom converters, and input file specifications.
- Improved validation checks for manager agents and callback references to ensure proper configuration in JSON crew definitions.
- Expanded documentation references within the tests to provide clearer guidance on the expected structure and usage of crew templates.

* Fix JSON crew PR review issues
2026-06-16 02:00:19 -03:00
Vinicius Brasil
fe2c236601 Add each composite action to FlowDefinition (#6164)
Lets a definition loop over an array without writing Python. Each
iteration exposes `item` and prior steps `outputs`.

```yaml
do:
  call: each
  in: state.rows
  do:
    - normalize:
        call: tool
        ref: my_tools:NormalizeRowTool
        with: { row: "${ item }" }
    - lead_scoring:
        call: agent
        # ...
```
2026-06-15 21:44:33 -07:00
João Moura
53c2284484 Support ZIP deployment fallback and JSON crew project env runs (#6166)
* Update crewAI CLI with various enhancements and fixes

- Updated `create_json_crew.py` to require `crewai[tools]>=1.14.7`.
- Enhanced `git.py` with improved repository initialization, including automatic initial commit creation and exclusion patterns for initial commits.
- Modified `install_crew.py` to allow error handling during installation with an optional `raise_on_error` parameter.
- Expanded `plus_api.py` to include methods for creating and updating crews from ZIP files.
- Introduced a new `archive.py` for creating deployable ZIP archives of CrewAI projects, ensuring local artifacts are excluded.
- Updated `run_crew.py` to manage JSON crew dependencies and run crews in the project's environment.
- Enhanced deployment logic in `main.py` to handle ZIP uploads and improve user feedback during deployment processes.
- Added tests for new functionalities and ensured existing tests reflect recent changes in behavior and requirements.

* fix(cli): address deploy zip review feedback

* fix(cli): sync missing lockfile before deploy

* fix(cli): preserve remote deploy on git setup warnings

* test(cli): use single deploy main import style

* fix(cli): skip project install for json crew sync

* fix(cli): load json runner from source checkout

* fix(cli): skip json crew sync when locked

* fix(cli): address deploy zip review feedback

* fix(cli): pass env on zip redeploy

* fix(cli): harden json run and zip fallback

* fix(cli): validate before deploy lock install

* fix(cli): respect poetry lock for json runs

* fix(cli): align json zip wrapper detection

* fix(deps): bump starlette audit floor

* fix(cli): avoid auth retry for deploy exits

* fix(cli): update json zip script entrypoints
2026-06-15 18:46:54 -03:00
Lorenze Jay
a5cc6f6d0e Add crewai_version to flow execution telemetry (#6167)
Some checks failed
CodeQL Advanced / Analyze (python) (push) Has been cancelled
CodeQL Advanced / Analyze (actions) (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
2026-06-15 09:34:01 -07:00
João Moura
bb477f8a91 JSON first crews (#6131)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Check Documentation Broken Links / Check broken links (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Nightly Canary Release / Check for new commits (push) Has been cancelled
Nightly Canary Release / Build nightly packages (push) Has been cancelled
Nightly Canary Release / Publish nightly to PyPI (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
* feat(cli): introduce JSON crew project support and TUI enhancements

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

* fix: refine json-first crew interactions

* fix: prioritize common json crew tools

* fix: make json crew more tools expandable

* fix: show json crew tools by category

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

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

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

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

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

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

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

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

* fix: address second round of PR review comments

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Addresses the latest Bugbot review round:

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

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

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

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

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

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

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

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

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

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

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

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

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-06-14 04:19:48 -03:00
Vini Brasil
d80719df81 Add experimental crewai run --definition for flows (#6147)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Build uv cache / build-cache (3.10) (push) Has been cancelled
Build uv cache / build-cache (3.11) (push) Has been cancelled
Build uv cache / build-cache (3.12) (push) Has been cancelled
Build uv cache / build-cache (3.13) (push) Has been cancelled
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
Let users run a Flow from a Flow Definition YAML file or inline string
without writing Python, passing kickoff inputs as `--inputs` JSON. The
flag is gated behind an experimental warning since the definition format
may still change.
2026-06-12 22:31:05 -07:00
Vini Brasil
6ad821b157 Add expressions to FlowDefinition actions (#6145)
* Add expressions to FlowDefinition actions

Let definitions compute values without Python. A new `call: expression`
action evaluates a Common Expression Language (CEL) expression, and tool
`with:` blocks now render `${...}` CEL templates.

Example 1:

```yaml
decide:
  do:
    call: expression
    expr: "state.score >= 80 ? 'qualified' : 'nurture'"
  router: true
  emit: [qualified, nurture]
```

Example 2:

```yaml
search:
  do:
    call: tool
    ref: my.pkg:SearchTool
    with:
      search_query: "${outputs.build_query.query + ' news'}"
      max_results: "${state.limit}"
```

* Address code review comments

* Address code review comments

* Fix linting offenses

* Address code review comments

* Fix scrapgraph issue
2026-06-12 21:56:02 -07:00
Vini Brasil
2444895ca4 Implement Flow definition run tools without Python code (#6144)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Nightly Canary Release / Check for new commits (push) Has been cancelled
Nightly Canary Release / Build nightly packages (push) Has been cancelled
Nightly Canary Release / Publish nightly to PyPI (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
A `do:` step can now say `call: tool` and name a CrewAI tool to run,
passing its inputs under `with:`. Before this, a definition could only
point at Python code to run.

```yaml
methods:
  search:
    start: true
    do:
      call: tool
      ref: crewai_tools:ExaSearchTool
      with:
        search_query: ai agents
```
2026-06-12 19:47:58 -07:00
Vini Brasil
bf291a7a55 Drive human feedback from the flow definition (#6133)
* Drive human feedback from the flow definition

@human_feedback previously wrapped methods with the full HITL runtime (feedback
request, outcome collapse, learn loop), so flows built from a YAML definition —
which carry no decorated callables — could not pause for or route on human
feedback.

# Conflicts:
#	lib/crewai/src/crewai/flow/persistence/decorators.py
#	lib/crewai/src/crewai/flow/runtime/__init__.py

* Address code review comments
2026-06-12 14:48:43 -07:00
Vini Brasil
64438cba37 Wire config and persistence from FlowDefinition into the runtime (#6132)
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
Check Documentation Broken Links / Check broken links (push) Has been cancelled
* Wire config and persistence from FlowDefinition into the runtime

`from_definition` was silently dropping all config fields; it now passes
`config.model_dump()` so suppress_flow_events, max_method_calls, etc.
actually apply.

Persistence is now engine-driven: `_persist_method_completion` fires
after every method using the definition's persist metadata, so
`@persist` no longer needs to wrap methods — it just stamps them.

* Address code review comments
2026-06-12 11:51:44 -07:00
Lucas Gomide
887adafd2c fix: aggregate token usage across all LLM calls (#6122)
* feat: aggregate LLM token usage at the flow level

Introduces `flow.usage_metrics`, a snapshot of every LLMCallCompletedEvent
emitted under the flow's `current_flow_id` for the duration of one kickoff
(or resume) call. Aggregation happens on the singleton event bus so it
covers crews, direct `LLM.call`s, and nested listener calls — solving the
mismatch where the SDK reported only the last crew's usage while the
Enterprise UI showed the correct full total.

Co-authored-by: Cursor <cursoragent@cursor.com>

* refactor: centralize provider key normalization in UsageMetrics

Add UsageMetrics.from_provider_dict to normalize raw LLM usage dicts
across providers (LiteLLM, native Anthropic, native Gemini, OpenAI
nested cached). BaseLLM._track_token_usage_internal and the flow-level
aggregator now share this single source of truth, so `flow.usage_metrics`
agrees with per-LLM totals on every provider — including the native
Anthropic path that emits `input_tokens`/`output_tokens` instead of
`prompt_tokens`/`completion_tokens`.

* fix: flush event bus before reading aggregated usage_metrics

`crewai_event_bus.emit` dispatches LLMCallCompletedEvent handlers on a
ThreadPoolExecutor (fire-and-forget), so a flow whose last LLM call
completes right before kickoff_async/resume_async returns can detach
the usage listener while that handler is still queued, leaving its
tokens off `flow.usage_metrics`. Match `Crew.kickoff()` and call
`crewai_event_bus.flush()` in both finally blocks so every handler
drains before the listener is detached.

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-12 12:55:22 -04:00
Rip&Tear
d3fc0d31f8 [codex] Redact file tool paths (#6134)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
* Redact file tool paths

* Fix for pull request finding 'Empty except'

* Potential fix for pull request finding

---------
2026-06-12 15:50:40 +08:00
Vini Brasil
373dca3d04 Run flows from a definition without a Python subclass (#6104)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Nightly Canary Release / Check for new commits (push) Has been cancelled
Nightly Canary Release / Build nightly packages (push) Has been cancelled
Nightly Canary Release / Publish nightly to PyPI (push) Has been cancelled
* Read flow dispatch from FlowDefinition

Store the definition in a `_definition` PrivateAttr at post-init and
convert the dispatch helpers (`_start_method_names`, `_listener_methods`,
`_start_condition`, `_listen_condition`, `_is_router`) from classmethods
to instance methods that read it. Event names now fall back to
`self._definition.name` instead of `self.__class__.__name__`.

Behavior is identical for decorator subclasses, but the engine no longer
assumes the definition comes from the class. This is the seam for
`Flow.from_definition`, where an instance runs a definition that was
loaded rather than built from a Python subclass.

* Add Flow.from_definition to run flows without a subclass

A FlowDefinition (e.g. loaded from YAML) was only usable for dispatch on
decorator-authored subclasses. Now each method definition records an
importable `module:qualname` handler ref, and `Flow.from_definition`
resolves and binds those handlers to build a runnable flow directly.

* Build flow state from FlowDefinition

Definition-driven flows previously always started with a bare dict
state.

* Replace handler string with structured FlowActionDefinition

`handler: str | None` was optional and opaque — missing handlers only
surfaced at kickoff time. `do: FlowActionDefinition` is required, so
Pydantic rejects invalid definitions at parse time.

The `call: "code"` discriminator prepares the schema for future
non-Python action types (e.g. MCP tool, crew) without touching
`FlowMethodDefinition`. Resolution logic is extracted to
`runtime/_action_resolvers.py` to keep the dispatch point isolated.

* Fix conversational start router missing required do field

FlowMethodDefinition.do became required when the handler string was
replaced with FlowActionDefinition, but _conversation_start_router still
built its fragment without it, breaking crewai import entirely.

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

* Add event scoping to flow test

* Change lib/crewai/tests/test_flow_from_definition.py

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 14:18:49 -07:00
Greyson LaLonde
21fa8e32d9 docs: update changelog and version for v1.14.7
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
Check Documentation Broken Links / Check broken links (push) Has been cancelled
2026-06-11 10:13:40 -07:00
Greyson LaLonde
f18c03cd8f feat: bump versions to 1.14.7 2026-06-11 10:06:07 -07:00
Greyson LaLonde
50b9c02272 fix(checkpoint): rebuild custom BaseLLM as concrete LLM on restore
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Check Documentation Broken Links / Check broken links (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
A custom BaseLLM subclass serializes with the inherited llm_type "base",
which the registry maps to the abstract BaseLLM. Restore then crashed on
cls(**value). Rebuild a concrete LLM from the saved config when the
resolved class is abstract.
2026-06-10 22:21:35 -07:00
Greyson LaLonde
c55334be5f docs: update changelog and version for v1.14.7rc2 2026-06-10 20:52:56 -07:00
Greyson LaLonde
05a2ba9ca4 feat: bump versions to 1.14.7rc2 2026-06-10 20:45:29 -07:00
Greyson LaLonde
fbafe1f0d3 fix(flow): gate restore on a flag so live snapshots don't replay as resume
Checkpoint serialization stamps checkpoint_completed_methods onto every live
Flow in RuntimeState.root, including the agent executor reused across a crew's
tasks. kickoff_async read that stamp as a restore signal, so the second task
replayed the first task's completed methods and never reached a final answer.

Gate is_restoring on _restored_from_checkpoint, set only by
_restore_from_checkpoint, and consume it single-shot.
2026-06-10 20:40:08 -07:00
Greyson LaLonde
5267c059f5 test(flow): pass show=False in test_flow_plotting to not open a browser
flow.plot defaults to show=True, which calls webbrowser.open on every run.
The test only asserts FlowPlotEvent is emitted, so disable the browser open.
2026-06-10 20:36:14 -07:00
Greyson LaLonde
243c9edc1c docs: update changelog and version for v1.14.7rc1
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Check Documentation Broken Links / Check broken links (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Nightly Canary Release / Check for new commits (push) Has been cancelled
Nightly Canary Release / Build nightly packages (push) Has been cancelled
Nightly Canary Release / Publish nightly to PyPI (push) Has been cancelled
2026-06-10 18:56:52 -07:00
Greyson LaLonde
68910b70c0 feat: bump versions to 1.14.7rc1 2026-06-10 18:50:54 -07:00
Greyson LaLonde
299782765c ci: ignore GHSA-rrmf-rvhw-rf47 (torch alias of PYSEC-2025-194)
* ci: ignore GHSA-rrmf-rvhw-rf47 (torch alias of PYSEC-2025-194)

pip-audit reports CVE-2025-3000 under its GHSA id, which the existing
PYSEC-2025-194 ignore does not match. Same advisory: memory corruption
in torch.jit.script, CVSS 1.9, local-only, no fix for torch 2.11.0.

* ci: sync GHSA-rrmf-rvhw-rf47 ignore into pre-commit pip-audit
2026-06-10 18:45:42 -07:00
Greyson LaLonde
a1f44eb272 fix(events): scope runtime state per run to bound growth and isolate concurrent runs 2026-06-10 18:39:05 -07:00
Lorenze Jay
036b032ab6 handle supporting both custom prompts (#6108)
* handle supporting both custom prompts

* handle translations

* handle deprecation warnings better
2026-06-10 17:52:53 -07:00
Lorenze Jay
f88ae54f96 fix telemetry setup on crewai-login (#6106)
* fix telemetry setup on crewai-login

* type check fix
2026-06-10 17:03:25 -07:00
Lorenze Jay
b6e5d632c1 improve convo routing cycle with one less route (#6102)
* improve one less route

* flows in flows, new agent executor causing early trace batch finalization

* addressing comments

* addressing comments pt2

* lint and typecheck fix
2026-06-10 16:49:16 -07:00
Greyson LaLonde
0d971e5bc5 feat(events): add reset_runtime_state to release accumulated bus state 2026-06-10 16:12:28 -07:00
Lucas Gomide
b3f175b56f docs: update otel images (#6103)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Check Documentation Broken Links / Check broken links (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
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
2026-06-10 14:34:30 -04:00
Lucas Gomide
f523a7d029 docs: udpate docs to reflect new state of OpenTelemetry collector (#6100)
* docs: udpate docs to reflect new state of OpenTelemetry collector

* docs: add OTel collector and Datadog screenshots

These images are referenced by the capture_telemetry_logs guides but were
missing from the tree, which broke the link checker across all locales.

* docs: address PR review on OTel collector guide

- Clarify that OpenTelemetry Traces and Logs are separate integrations
  sharing the same fields (resolves Traces/Logs wording inconsistency)
- List regional Datadog OTLP hosts (US1/US3/US5/EU1/AP1) so users outside
  US5 can copy the right domain
2026-06-10 14:26:35 -04:00
Lorenze Jay
f214ff4b7b decouple convo logic from runtime and added a conversational_definition (#6091)
* decouple convo logic from runtime and added a conversational_definition

* type check fix

* always defer traces for convo and so fix tests to reflect that
2026-06-10 10:49:39 -07:00
Vini Brasil
a9e7c3a44f Simplify flow condition evaluation to be stateless per event (#6097)
Re-evaluate the whole `@listen`/`@router` condition tree against the set
of events seen so far, instead of tracking which AND sub-branches remain
pending.

Net effect:
* Fixes a regression where `or_()` short-circuited at the first
  satisfied branch, leaving a sibling `and_()` half-complete so a later
  trigger could spuriously re-fire the listener
* Removes the fragile per-branch pending state and `id()`-based keys
* Shrinks the evaluator to one readable predicate
2026-06-10 10:35:25 -07:00
Lucas Gomide
da8fe8c715 fix: respect suppress_flow_events for method-execution events (#6095)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Check Documentation Broken Links / Check broken links (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Nightly Canary Release / Check for new commits (push) Has been cancelled
Nightly Canary Release / Build nightly packages (push) Has been cancelled
Nightly Canary Release / Publish nightly to PyPI (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
* fix: respect suppress_flow_events for method-execution events

* test: align suppressed-flow test with new method-event behavior
2026-06-09 17:19:25 -04:00
Greyson LaLonde
ce42994ae3 docs: update changelog and version for v1.14.7a4 2026-06-09 12:58:38 -07:00
Greyson LaLonde
820c3905e3 feat: bump versions to 1.14.7a4 2026-06-09 12:51:55 -07:00
Vini Brasil
703ffe67ee Migrate @listen/@router runtime to read from FlowDefinition (#6084)
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
* Migrate @listen/@router runtime to read from FlowDefinition

The runtime now resolves listener conditions, router status, and emit
values from `FlowMethodDefinition` instead of legacy method metadata and
the `_listeners`/`_routers`/`_router_emit` registries.

* Evaluate AND/OR listener conditions over the definition shape via
  `_evaluate_definition_condition`
* Drop the class registries and the `FlowMeta` extraction that built
  them; stop stamping `__trigger_methods__`, `__is_router__`,
  `__router_emit__`, and friends
* `@human_feedback` emit now lives only on its config

* Simplify conditionals DSL
2026-06-09 09:40:30 -07:00
Matt Aitchison
8919026326 feat(storage): pluggable default backends for memory, knowledge, rag, flow (#6079)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
Add opt-in extension seams so an application can route memory, knowledge,
RAG, and flow persistence through a custom backend without subclassing or
threading an explicit instance through every construction site -- mirroring
the existing crewai_core.lock_store.set_lock_backend seam.

- memory:    crewai.memory.storage.factory.set_memory_storage_factory
- knowledge: crewai.knowledge.storage.factory.set_knowledge_storage_factory
- rag:       crewai.rag.factory.register_rag_client_factory (provider registry)
- flow:      crewai.flow.persistence.factory.set_flow_persistence_factory

Each construction site consults the registered factory and falls back to the
built-in default when none is set; an explicit instance always wins. Widen
Knowledge.storage and the knowledge source base classes to BaseKnowledgeStorage
(consistent with BaseAgent.knowledge_storage) so any base-interface backend
plugs in. Runtime-free tests cover each seam.
2026-06-08 21:14:13 -05:00
Greyson LaLonde
988927006c docs: update changelog and version for v1.14.7a3
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
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
Build uv cache / build-cache (3.12) (push) Has been cancelled
Build uv cache / build-cache (3.10) (push) Has been cancelled
Build uv cache / build-cache (3.11) (push) Has been cancelled
Build uv cache / build-cache (3.13) (push) Has been cancelled
2026-06-08 18:56:39 -07:00
Greyson LaLonde
48c1987fcf feat: bump versions to 1.14.7a3 2026-06-08 18:43:15 -07:00
Greyson LaLonde
af62b7b583 fix: expose ask_for_human_input on experimental AgentExecutor
fixes #6065
2026-06-08 17:55:19 -07:00
Greyson LaLonde
1b14e162e9 fix: resolve pip-audit CVEs (aiohttp, docling, docling-core, pip)
* fix: resolve pip-audit CVEs for aiohttp, docling, docling-core, pip

- aiohttp 3.13.4 → 3.14.0: fixes GHSA-jg22-mg44-37j8, GHSA-hg6j-4rv6-33pg
- docling 2.84.0 → 2.97.0: fixes GHSA-cjqg-rq2h-2fvj, GHSA-pj2v-ggqh-cmq2,
  GHSA-r3xg-rg9j-67fv, GHSA-q29v-xc37-wh5m
- docling-core 2.74.0 → 2.79.0: fixes GHSA-j5xp-7m2f-49jv, GHSA-jmmv-h3mp-59v8
- pip 26.1.1 → 26.1.2: fixes PYSEC-2026-196

docling-core 2.74.1+ requires pydantic-settings>=2.14.0, so the crewai pin
is loosened from ~=2.10.1 to >=2.10.1,<3. pydantic-settings resolves to
2.14.1 in the lock.

* fix: correct aiohttp CVE floor to 3.14.0 (not 3.13.5)

* test: shim AsyncStreamReaderMixin for vcrpy under aiohttp 3.14.0

aiohttp 3.14.0 removed aiohttp.streams.AsyncStreamReaderMixin (folded into
StreamReader). vcrpy's aiohttp stub still subclasses it, so vcr's patch
machinery raised AttributeError at test collection. Restore an equivalent
mixin in conftest before vcr is imported.

* test: rebuild vcrpy MockClientResponse init for aiohttp 3.14.0

aiohttp 3.14.0 added a required stream_writer kwarg to ClientResponse.__init__
and reads stream_writer.output_size when writer is None. vcrpy's
MockClientResponse doesn't pass it, raising TypeError at cassette playback.
Rebuild the super().__init__ call from the live signature (defaulting required
keyword-only args to None, with a stream_writer stub exposing output_size) so
it survives future aiohttp signature additions too.

* test: avoid deprecated get_event_loop in vcrpy aiohttp shim

asyncio.get_event_loop() emits a DeprecationWarning (and can RuntimeError)
when no current loop is set on Python 3.12+. Prefer get_running_loop() (the
real cassette-playback path always has one) and fall back to a single cached
loop in sync contexts, since the mock only stores the loop and calls
get_debug().

* fix: pull docling-core[chunking] so HierarchicalChunker imports

docling 2.97 split into docling-slim, moving the chunker's code-chunking
deps (tree-sitter, semchunk, language grammars) behind docling-core's
[chunking] extra. crewai's knowledge source imports HierarchicalChunker,
whose package __init__ eagerly imports those submodules -> ModuleNotFoundError
('tree_sitter') without the extra. Request docling-core[chunking]; carry the
extra in override-dependencies too, since overrides replace the whole
requirement and would otherwise strip it.
2026-06-08 17:45:07 -07:00
Vini Brasil
e570534f15 Migrate @start to read from FlowDefinition (#6071)
* Remove `_start_methods` and `__is_start_method__` stamping
* Add helpers to read start info from the definition
* Scan `__dict__` instead of `dir()` to find flow methods
2026-06-08 15:03:50 -07:00
Lorenze Jay
913a3abead docs: update changelog and version for v1.14.7a2 (#6055)
Some checks failed
Check Documentation Broken Links / Check broken links (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
CodeQL Advanced / Analyze (actions) (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-06-05 14:19:42 -07:00
Lorenze Jay
17cfbdf95f feat: bump versions to 1.14.7a2 (#6054) 2026-06-05 14:15:43 -07:00
Lorenze Jay
8cd51fc67e Lorenze/imp/conversational flow traces (#6044)
* feat: add conversation message and route selection events

- Introduced `ConversationMessageAddedEvent` and `ConversationRouteSelectedEvent` to enhance conversational flow tracking.
- Updated event listeners to emit these events during message handling and routing decisions.
- Enhanced the `_ConversationalMixin` class to emit events for user and assistant messages, as well as selected routes.
- Added tests to verify the correct emission of these events during conversational turns.

* ensure flow started events only emiited once

* refactor(tracing): rename trace event handler methods to action event handlers

Updated the  class to replace  with  for  and  events, improving clarity in event handling.

Additionally, adjusted comments in the  class to clarify the application of pending user messages in relation to state restoration and flow scope initialization.

* fix(conversational_mixin): handle empty message index in route events

Updated the message index handling in the  class to return  when there are no messages. Added tests to ensure that route events do not reference index zero when the transcript is empty, and verified the correct emission of conversation message events during flow handling.
2026-06-05 14:10:19 -07:00
Lorenze Jay
3723f0db76 Update conversational flow docs to use handle_turn (#6053) 2026-06-05 11:04:28 -07:00
Lucas Gomide
cab3319af9 feat(otel): surface real finish_reason + sampling params + response.id on LLM events (#5945)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Build uv cache / build-cache (3.10) (push) Has been cancelled
Build uv cache / build-cache (3.11) (push) Has been cancelled
Build uv cache / build-cache (3.12) (push) Has been cancelled
Build uv cache / build-cache (3.13) (push) Has been cancelled
* feat(otel): surface real finish_reason + sampling params + response.id on LLM events

Companion to the OTel GenAI emitter compliance work in crewai-enterprise
(CON-172). Today the enterprise emitter reads these fields off the OSS
LLM events via `getattr(..., None)`, so it produces valid (but partial)
spans against the existing OSS surface. This change makes those fields
first-class on the events so spans can carry the real provider data.

What this adds:

- `LLMCallStartedEvent` gains the sampling-param fields the emitter needs
  for `gen_ai.request.*`: `temperature`, `top_p`, `max_tokens`, `stream`,
  `seed`, `stop_sequences`, `frequency_penalty`, `presence_penalty`, `n`.
  All optional; existing call sites keep working.
- `BaseLLM._emit_call_started_event` introspects those values off `self`
  (the LLM instance) via `getattr(..., None)` so every provider gets the
  fields propagated for free without per-provider plumbing.
- `LLMCallCompletedEvent` gains `finish_reason: str | None` and
  `response_id: str | None`. A field validator coerces any non-string
  value (MagicMock, unexpected provider object) to None so the event
  never raises on construction.
- `LLM._emit_call_completed_event` accepts both as kwargs.
- `LLM` (LiteLLM path) gets a defensive `_extract_finish_reason_and_response_id`
  helper that handles both streaming (`StreamingChoices`) and non-streaming
  (`Choices`) shapes and is wired into every completion-event emission site.
- Provider completions extract native values from their SDK responses and
  pass them through:
  - OpenAI: `_extract_responses_finish_reason_and_id` for Responses-API,
    `_extract_finish_reason_and_id` for Chat-Completions.
  - Anthropic: `_extract_finish_reason_and_id` (Messages API + streaming).
  - Bedrock: `_extract_finish_reason_and_id` (`stopReason` from converse).
  - Gemini: `_extract_finish_reason_and_id` (`finish_reason` from candidates).
  - Azure: inherits via OpenAI sub-class; adds the helper for Azure-specific
    response shapes.
  - openai_compatible: inherits from OpenAICompletion, no edits needed.

Compatibility:

- All new fields are optional with sensible defaults. No existing call
  sites need to change.
- The validator on `LLMCallCompletedEvent` swallows non-string values for
  the new fields so legacy mocks / exotic provider types don't blow up
  event construction.
- Enterprise side already reads these fields defensively, so OSS and
  enterprise can merge independently and cut on the same synchronized
  release.

Tested against the full LLM + events + provider test suite — all green;
the 14 pre-existing multimodal failures on main are unrelated and
reproduce without this diff.

* fix(bedrock): propagate finish_reason + response_id on async paths

The original commit covered every provider's sync path and Bedrock's
sync streaming path, but two Bedrock async paths still emitted
LLMCallCompletedEvent without finish_reason/response_id:

- _ahandle_converse: the final fallback emit_call_completed_event call
  was missing both fields. Added stop_reason + response_id matching the
  other emission sites in the same function.

- _ahandle_streaming_converse: response_id was never seeded from the
  initial response object, and stream_finish_reason wasn't propagated
  to the structured-output and final-text emissions. Now extracts
  response_id up front and threads stream_finish_reason through every
  completion event.

Adds a dedicated test file covering the new event fields end-to-end:
- LLMCallCompletedEvent.finish_reason / response_id Pydantic validation
  (string accepted, None default, non-string coerced to None).
- LLMCallStartedEvent sampling params (all nine fields accepted, default
  to None).
- BaseLLM._emit_call_started_event introspecting sampling params off
  self, with explicit kwargs overriding.
- BaseLLM._emit_call_completed_event passing finish_reason/response_id
  through to the event.
- LLM._extract_finish_reason_and_response_id across the LiteLLM shapes
  (non-streaming response, streaming chunk, dict, missing fields,
  non-string values, unexpected input).

* fix(otel): correct streaming finish_reason + bedrock response_id semantics

Two correctness fixes uncovered while landing the OTel finish_reason +
response_id plumbing:

- LiteLLM streaming (sync + async): `stream_options={"include_usage": True}`
  causes LiteLLM to emit a final usage-only chunk with `choices=[]`. The
  post-loop `_extract_finish_reason_and_response_id(last_chunk)` silently
  returned `(None, None)` because the last chunk has no choices, even though
  earlier chunks carried `finish_reason="stop"`. Track both fields
  incrementally inside the loop (mirroring how OpenAI/Gemini/Azure already
  handle their native streams) and use the tracked values for the
  LLMCallCompletedEvent emission and the partial-response error path.

- Bedrock Converse: `ResponseMetadata.RequestId` is an AWS infra trace id,
  not a model-level response id (semantically different from OpenAI's
  `chatcmpl-XXX`). Return None for `response_id` rather than mislead
  downstream telemetry consumers. The audit-fix's async propagation chain
  still works — None propagates through unchanged.

Adds `test_llm_streaming_finish_reason.py` pinning both the sync and async
LiteLLM streaming paths against the include_usage chunk shape.

* refactor(otel): unify LLM event introspection + drop redundant defensive code

Three cohesion cleanups uncovered during PR review, all behavior-preserving:

- LLM.call / LLM.acall in llm.py now delegate to BaseLLM._emit_call_started_event
  instead of constructing LLMCallStartedEvent inline. The base helper already
  introspects sampling params off self via getattr; the inline duplication was
  accidental, not justified, and a duplication risk if anyone adds a tenth
  OTel sampling param later.

- Extracted lib/crewai/llms/_finish_reason_utils.py:extract_choices_finish_reason_and_id
  as the shared extractor for the choices-based response shape. OpenAI Chat,
  Azure, and LiteLLM all read the same shape (response.id + choices[0].finish_reason)
  as both object attrs and dict keys. Providers with genuinely different shapes
  - Anthropic (stop_reason), Bedrock (stopReason), Gemini (protobuf enum),
  OpenAI Responses (status) - keep their own provider-specific helpers.

- Dropped redundant try/except (AttributeError, TypeError) wrappers around
  bare getattr(obj, "field", None) calls across the new extraction helpers.
  getattr with a default already suppresses AttributeError, and the inner
  isinstance / dict.get / int-coercion ops can't raise TypeError in practice.
  Kept the catches that legitimately guard against IndexError (e.g. choices[0]
  on an empty list).

Tests: 600 passed, 23 skipped, 14 pre-existing multimodal failures unchanged.
Added 12 parametrized tests for the shared helper covering object + dict
shapes, missing fields, non-string coercion, and never-raises invariants.

* chore(otel): drop dead last_chunk variable from async streaming

The streaming-fix commit (49e5581b5) replaced the post-loop
`_extract_finish_reason_and_response_id(last_chunk)` call with the
incrementally-tracked `stream_finish_reason` / `stream_response_id`,
which removed the only reader of `last_chunk` in
`_ahandle_streaming_response`. The declaration and per-iteration
assignment were left behind — harmless but confusing for future
readers because the sync sibling still legitimately uses `last_chunk`
(for usage and content fallbacks via `_handle_streaming_callbacks`).

The async path inlines its usage extraction directly inside the loop
(`chunk.model_extra.get("usage")`), so there's no fallback consumer.
Drop both lines.

Sync path untouched — `last_chunk` there is still load-bearing.

* fix(otel): coerce non-list stop_sequences to list[str] on LLMCallStartedEvent

Observed in Datadog: gen_ai.request.stop_sequences on a Gemini/Vertex
span surfaced the textproto repr of a google.protobuf.struct_pb2.ListValue
(values { string_value: "\nObservation:" }) instead of a real Sequence[str].

Root cause is upstream - a Vertex AI / Gemini code path stores the stop
list in a protobuf container (RepeatedScalarContainer or ListValue) rather
than a plain Python list. When that container reaches LLMCallStartedEvent
and then BaseLLM._emit_call_started_event hands it to the OTel SDK as a
span attribute, the SDK falls back to str(value) because the type isn't a
recognised Sequence[str] - producing the protobuf textproto string instead
of an array attribute.

* chore: fix ruff lint findings

* refactor(otel): declare sampling params on BaseLLM + honor stop overrides + dict chunk id

* fix: widen max_tokens to int | float | None + apply ruff format

* fix(otel): coerce unknown finish_reason / response_id to None instead of stringifying

* fix(otel): extract Azure stream finish_reason/id before usage-continue

Match the LiteLLM ordering so a finish_reason or response id riding on a
usage-carrying chunk isn't dropped by the early `continue`.

* fix(otel): report effective max_tokens cap + bedrock structured finish_reason
2026-06-05 07:23:38 -04:00
Vini Brasil
906cd9769d feat(flow): type DSL triggers as route-aware decorators (#6042)
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
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
Mark stale issues and pull requests / stale (push) Has been cancelled
Centralize FlowTrigger and FlowMethodDecorator so start/listen/router and the boolean trigger helpers share one authoring contract. This preserves decorated method signatures for static checking while allowing route-label strings in nested FlowCondition data.

Export the shared typing helpers for static analyzers, use an explicit Protocol body, align condition validation with Sequence-backed condition data, and drop the stale call-arg ignore exposed by the signature-preserving decorators.

Update the flow guide to use or_(...) for multi-label listeners.
2026-06-04 18:07:49 -03:00
Lorenze Jay
14ce97d787 chat api for convo flows (#6034)
* Add conversational Flow chat helper

* Document conversational flow chat APIs in translations

* Stringify conversational chat REPL output
2026-06-04 13:36:48 -07:00
Matt Aitchison
f3a15a4f07 feat(lock_store): make locking backend overridable (#6015)
* feat(lock_store): make locking backend overridable

Allow the centralised lock factory to use a pluggable backend instead of
the hardcoded Redis/file selection. Backends are resolved with precedence
override > CREWAI_LOCK_FACTORY env > built-in default:

- set_lock_backend()/reset_lock_backend() and a scoped lock_backend()
  context manager for programmatic overrides
- CREWAI_LOCK_FACTORY="module:callable" env import-path, resolved lazily
  and cached, with clear errors on malformed or non-callable specs
- LockBackend Protocol documenting the contract (raw name in, context
  manager out; backend owns its namespacing)

Default Redis/file behavior is unchanged when nothing is overridden.

* refactor(lock_store): use explicit body for LockBackend protocol method

Replace the no-op `...` body with `raise NotImplementedError` to satisfy
the CodeQL ineffectual-statement check while keeping the Protocol
structural-typing only.

* refactor(lock_store): drop scoped lock_backend context manager

Keep the backend overridable via set_lock_backend/reset_lock_backend and
the CREWAI_LOCK_FACTORY env path, but remove the scoped lock_backend()
context manager. It was speculative surface and the only thread-unsafe
piece (racy save/restore of the module global); nothing depends on it.

* refactor(lock_store): drop reset_lock_backend alias

reset_lock_backend() was just set_lock_backend(None); callers use that
directly. Clearing the override is documented on set_lock_backend.

* style(lock_store): apply ruff format

* refactor(lock_store): simplify overridable backend to a single setter

Reduce the override surface to just set_lock_backend(): lock() uses the
custom backend when one is set, otherwise the unchanged Redis/file default.

Drop the CREWAI_LOCK_FACTORY env import-path, the runtime_checkable
Protocol, the precedence resolver, and the getter — a custom backend is
now any callable(name, *, timeout) -> context manager, registered in
process.

* fix(lock_store): snapshot backend to avoid check-then-call race

Read the module-global backend once into a local before the None check
and the call, so a concurrent set_lock_backend(None) cannot make lock()
invoke None.

* docs(lock_store): clarify name handling for custom backends

The default namespaces the lock name; custom backends receive it
verbatim. Correct the lock() docstring which implied namespacing always
happens.

* docs(lock_store): note set_lock_backend is for one-time startup setup
2026-06-04 13:28:31 -05:00
Vini Brasil
75dad212a2 Split flow DSL monolith into focused decorator modules (#6040)
The Flow DSL lived in one 1033-line `dsl.py` that mixed every decorator
(`@start`/`@listen`/`@router`), the `human_feedback` decorator,
condition combinators, and FlowDefinition extraction helpers in a single
file.

Split it into a `dsl/` package where each decorator gets its own module
(`start.py` 68 lines, `listen.py` 55, `router.py` 164,
`human_feedback.py` 98) and the shared extraction/condition helpers stay
in `utils.py`. The public API is re-exported from `dsl/__init__.py`, so
import paths are unchanged.

This is simpler because each decorator is now read and changed in
isolation instead of scanning a 1000-line file to find one of them, and
router-specific annotation parsing no longer sits next to unrelated
start/listen logic.
2026-06-04 15:02:06 -03:00
alex-clawd
aed69237d4 docs: add NVIDIA Nemotron LLM guide (#6037)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Check Documentation Broken Links / Check broken links (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
2026-06-04 09:22:41 -03:00
Vini Brasil
051fa0c1cb Build FlowDefinition from Flow DSL metadata (#6017)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Check Documentation Broken Links / Check broken links (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
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
Mark stale issues and pull requests / stale (push) Has been cancelled
* Build FlowDefinition from Flow DSL metadata

Introduce `FlowDefinition`, a serializable model built from the Flow
DSL's runtime metadata. It becomes the structural contract for Flow
methods, triggers, routers, state, and configuration.

The visualization layer is the first consumer: `flow_structure` and
`build_flow_structure` now project from the definition instead of
re-introspecting the class. The runner still executes from live
registries, but the definition gives future runners a single static
contract to read.

This replaces AST source parsing for router return values, crew
references, and state schema with runtime metadata plus explicit
`@router(paths=...)` or `Literal`/`Enum` return hints. AST parsing was
fragile and could silently fail for dynamic or non-inspectable methods.

The refactor removes obsolete introspection and serializer code:

* Delete `flow_serializer.py`, `flow/utils.py`, and
  `visualization/schema.py`
* Move flow structure modeling into `flow_definition.py`
* Simplify visualization building around the static definition contract

* Format files
2026-06-03 18:02:56 -03:00
Gui Vieira
73d20fb0c3 Document monorepo deployments (#6018)
* Document monorepo deployments

* Add localized monorepo docs
2026-06-03 17:01:10 -03:00
Lucas Gomide
d09e3f4544 feat: flatten LiteLLM cache/reasoning usage sub-counts in _usage_to_dict (#6033)
LiteLLM returns provider usage as-is, nesting cache-read / cache-creation /
reasoning counts under provider-specific shapes (e.g.
prompt_tokens_details.cached_tokens, Anthropic-style cache_read_input_tokens).
Surface them as flat cached_prompt_tokens / reasoning_tokens /
cache_creation_tokens keys so the span pipeline can read them; prompt /
completion / total token counts are left untouched.
2026-06-03 15:13:30 -04:00
Lorenze Jay
1357491f0d Lorenze/feat/conversational flows (#5896)
* feat: add conversational flows documentation and chat session support

- Introduced a new guide for building multi-turn chat applications using , detailing session management and message handling.
- Added  class to facilitate chat interactions, including streaming support and event handling.
- Implemented  for class-level defaults and improved input normalization for conversational turns.
- Enhanced event listeners to manage flow events and tracing more effectively, including support for nested crew executions.
- Added tests for conversational flow helpers and kickoff parameters to ensure functionality and reliability.

* linted

* feat: enhance flow event tracing and session management

- Updated TraceCollectionListener to handle nested flows without re-claiming parent session batches.
- Ensured that method execution events are always emitted for tracing, regardless of flow event suppression.
- Improved finalization logic for flow trace batches to respect session deferral flags.
- Added tests to verify that method execution events are emitted correctly when flow events are suppressed and that deferred session finalization is respected in nested flows.

* updated docs

* feat: introduce experimental conversational flow framework

- Added a new module for conversational flow, including classes for managing conversation state, messages, and events.
- Implemented  and  for structured intent handling and routing.
- Enhanced the  class to support turn-oriented conversational applications with built-in routing and message handling.
- Updated  to include new classes in the public API.
- Added tests to validate the functionality of the new conversational flow features.

* handled docs

* feat(flow): enhance conversational flow handling and tracing

- Introduced support for deferred multi-turn tracing to maintain continuous event sequences.
- Updated  method to delegate to restored checkpoint flows, improving session management.
- Added tests to validate the new tracing behavior and ensure correct event handling in conversational flows.

* fix multimodal test

* better conversational

* adjusted prompt

* drop unused

* fix test

* refactor: rename  to  and update related documentation

This commit refactors the  class to  for clarity and consistency across the codebase. The documentation has been updated to reflect this change, ensuring that references to the new  class are accurate. Additionally, the alias for legacy imports is maintained for backward compatibility. The changes enhance the overall structure and readability of the conversational flow implementation.

* fix test

* adding experimetnal indicators

* fix test and reloaded cassettes

* cleanup ConversationalFlow class

* addressing double finalization and fixed tests

* improve on emphemeral tracing and adddressing comments
2026-06-03 11:53:16 -07:00
Lorenze Jay
ea88904d35 docs: update changelog and version for v1.14.7a1 (#6032) 2026-06-03 10:40:43 -07:00
Lorenze Jay
be3cf62b63 feat: bump versions to 1.14.7a1 (#6031) 2026-06-03 10:30:33 -07:00
Greyson LaLonde
68cdd44520 fix(cli): restore [project.scripts] in crewai package for uv tool install 2026-06-03 09:50:39 -07:00
Greyson LaLonde
7676b0937c fix(deps): bump authlib to >=1.6.12 to patch PYSEC-2026-188 2026-06-03 09:45:59 -07:00
Greyson LaLonde
ee707028db chore: remove testing pdf from root
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
2026-06-02 17:53:26 -07:00
Lorenze Jay
770d1b284f Lorenze/fix/file input not working reliably (#6020)
* fix filesystem

* Refine commit message formatting

* fix for async kickoffs

* added suggestion
2026-06-02 17:14:51 -07:00
alex-clawd
b047c96756 Handle Snowflake Claude stringified tool calls (#6008)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Build uv cache / build-cache (3.10) (push) Has been cancelled
Build uv cache / build-cache (3.11) (push) Has been cancelled
Build uv cache / build-cache (3.12) (push) Has been cancelled
Build uv cache / build-cache (3.13) (push) Has been cancelled
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
* Handle Snowflake Claude stringified tool calls

* Fix Snowflake tool id type narrowing

* Extract Snowflake tool result text in summaries

* Bump PyJWT for vulnerability scan

---------

Co-authored-by: João Moura <joaomdmoura@gmail.com>
2026-06-02 19:37:18 -03:00
Greyson LaLonde
d37af0d404 perf(knowledge): lazy-load docling imports to speed up crewai import 2026-06-02 15:16:48 -07:00
Greyson LaLonde
c81b4fe11e fix(deps): bump pyjwt to >=2.13.0 to patch CVEs 2026-06-02 10:01:53 -07:00
Lorenze Jay
a9cb7867bb Add crew trained agents file support (#6012)
* Add crew trained agents file support

* Add crew trained agents file support
2026-06-02 09:38:34 -07:00
Jesse Miller
383ae66b55 docs: add Databricks integration guide (#6001)
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 (python) (push) Has been cancelled
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
Check Documentation Broken Links / Check broken links (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
* docs: add Databricks integration guide to enterprise integrations

Add documentation for connecting CrewAI agents to Databricks via the
Databricks managed MCP servers. Highlights Genie, Databricks SQL, Unity
Catalog Functions, and Vector Search, each configured as a separate MCP
connection, and covers OAuth/PAT setup. Includes ko, pt-BR, and ar
translations and registers the page in all docs.json navigation blocks.

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

* fix: use locale-specific slugs for Databricks nav entries

Add databricks integration entries to pt-BR, ko, and ar nav blocks
using locale-specific prefixes instead of only having en/ entries.

Co-authored-by: Luzk <2128595+Luzk@users.noreply.github.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Iris <iris@crewai.com>
Co-authored-by: Luzk <2128595+Luzk@users.noreply.github.com>
Co-authored-by: Greyson LaLonde <greyson.r.lalonde@gmail.com>
Co-authored-by: Lucas Gomide <lucaslg200@gmail.com>
2026-06-02 09:43:05 -04:00
alex-clawd
774fd871a8 Fix Snowflake Claude incomplete tool result histories (#6006)
* Fix Snowflake Claude incomplete tool result histories

* Filter Snowflake Claude preserved tool results
2026-06-02 09:11:59 -03:00
alex-clawd
4a0769d97c Add native Snowflake Cortex LLM provider (#6005) 2026-06-02 08:10:13 -03:00
Greyson LaLonde
fee5b3e395 fix(devtools): point template bumper at lib/cli templates dir 2026-06-02 02:02:12 -07:00
devin-ai-integration[bot]
3010f1286f chore: widen click dependency constraint to allow 8.2+
Addresses #6002
2026-06-02 00:06:25 -07:00
Greyson LaLonde
e53a676c04 fix(flow): re-arm multi-source or_ listeners across router-driven cycles
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Nightly Canary Release / Check for new commits (push) Has been cancelled
Nightly Canary Release / Build nightly packages (push) Has been cancelled
Nightly Canary Release / Publish nightly to PyPI (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
The previous discard-after-body approach cleared the gate mid-wave, so
a slow parallel @start finishing after the listener body could re-fire
the same multi-source or_ listener. Re-arm only when a router emits a
signal that matches the listener's condition; parallel @start paths
never reach that branch and the race gate keeps protecting them.

Closes #5972
2026-06-01 15:24:58 -07:00
Vini Brasil
1aba9fe415 Split flow.py into DSL, definition, and runtime (#5997)
This commit separates the monolithic `flow.py` into three modules, each
with one job:

- `dsl.py` - the Python DSL for flows (@start/@listen/@router, or_/and_)
- `flow_definition.py` - the structural model extracted from the DSL
- `runtime.py` - the execution engine and state for flows

This phase moves code only and should not have any breaking changes.
2026-06-01 18:37:10 -03:00
Greyson LaLonde
4dafb05735 chore(deps): bump uv to >=0.11.15 and ignore unfixable chromadb CVE
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Build uv cache / build-cache (3.10) (push) Has been cancelled
Build uv cache / build-cache (3.11) (push) Has been cancelled
Build uv cache / build-cache (3.12) (push) Has been cancelled
Build uv cache / build-cache (3.13) (push) Has been cancelled
uv 0.11.7 -> 0.11.17 patches GHSA-4gg8-gxpx-9rph. chromadb has no
patched release for GHSA-f4j7-r4q5-qw2c (server-only pre-auth RCE,
not reachable in our embedded use); ignore until upstream ships a fix.
2026-06-01 00:10:19 -07:00
Jesse Miller
5cdc420c50 docs: add Snowflake integration guide (#5977)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Check Documentation Broken Links / Check broken links (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Nightly Canary Release / Check for new commits (push) Has been cancelled
Nightly Canary Release / Build nightly packages (push) Has been cancelled
Nightly Canary Release / Publish nightly to PyPI (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
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
* docs: add Snowflake integration guide to enterprise integrations

Add documentation for connecting CrewAI agents to Snowflake via the
Snowflake-managed MCP server. Highlights Cortex Analyst, Cortex Search,
and SQL execution, and covers OAuth/PAT setup. Registers the page in
all docs.json navigation blocks.

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

* docs: add Snowflake integration page for ko, ar, pt-BR

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Iris Clawd <iris@crewai.com>
2026-05-29 15:03:55 -04:00
Greyson LaLonde
fca21b155c docs: update changelog and version for v1.14.6
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Check Documentation Broken Links / Check broken links (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Nightly Canary Release / Check for new commits (push) Has been cancelled
Nightly Canary Release / Build nightly packages (push) Has been cancelled
Nightly Canary Release / Publish nightly to PyPI (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
2026-05-28 10:03:50 -07:00
Greyson LaLonde
0486b85aa3 feat: bump versions to 1.14.6 2026-05-28 09:47:19 -07:00
Greyson LaLonde
ed91100a0f refactor(skills): move Skills Repository to experimental + CREWAI_EXPERIMENTAL gate
Moves the registry/cache pieces of PR #5867 under crewai.experimental.skills
and the CLI commands under `crewai experimental skill`. The stable local-file
skills feature (loader, parser, validation, models) stays in crewai.skills.

Both entry points now require CREWAI_EXPERIMENTAL=1:
- resolve_registry_ref() calls require_experimental_skills() before resolving
- The `crewai experimental` CLI group raises UsageError when the flag is unset

SkillDownloadStarted/CompletedEvent move out of crewai.events.types.skill_events
into crewai.experimental.skills.events.

* refactor(skills): move 'version' off SkillFrontmatter into metadata

The skill version is now stored as `metadata.version` rather than a
top-level field on `SkillFrontmatter`. A `before` validator lifts any
top-level YAML `version:` into `metadata['version']` so existing SKILL.md
files keep parsing.
2026-05-28 09:38:10 -07:00
Lucas Gomide
2148c7ed77 docs: add ACP (Beta) docs navigation block to Agent Control Plane pages (#5961)
- Adds an <Info> "ACP (Beta) Docs Navigation" block at the top of every
  Agent Control Plane page so readers can jump between Overview,
  Monitoring, and Rules without scrolling to the bottom-of-page Related
  cards.
2026-05-28 09:56:37 -04:00
iris-clawd
8890e0d645 docs: remove consensual process references from processes page (#5959)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Check Documentation Broken Links / Check broken links (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Nightly Canary Release / Check for new commits (push) Has been cancelled
Nightly Canary Release / Build nightly packages (push) Has been cancelled
Nightly Canary Release / Publish nightly to PyPI (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
The consensual process was never implemented and is not planned.
Removes all mentions across en, ar, ko, and pt-BR locales.

Co-authored-by: Lorenze Jay <lorenzejay@users.noreply.github.com>
Co-authored-by: Lorenze Jay <63378463+lorenzejay@users.noreply.github.com>
2026-05-27 18:01:30 -07:00
Greyson LaLonde
4a6a072fc8 docs: update changelog and version for v1.14.6a2 2026-05-27 16:49:36 -07:00
Greyson LaLonde
d52106b3c7 feat: bump versions to 1.14.6a2 2026-05-27 16:42:40 -07:00
Greyson LaLonde
4b190ae6b4 docs: restructure checkpointing page 2026-05-27 14:51:42 -07:00
Lorenze Jay
2e36f06732 feat: enhance StdioTransport to prevent environment variable leakage (#5506)
* feat: enhance StdioTransport to prevent environment variable leakage

- Replaced os.environ.copy() with get_default_environment() to ensure only allowed environment variables are passed to the MCP server.
- Added tests to verify that ambient environment variables do not leak and that user-supplied environment variables can override defaults.

* feat: add environment variable filtering hook to StdioTransport

- Introduced an optional `_env_filter_hook` to allow extensions to modify the environment variables passed to MCP servers, enabling features like credential stripping.
- Updated tests to ensure the filtering hook is applied correctly after merging user-supplied and default environment variables.
2026-05-27 13:38:25 -07:00
Lorenze Jay
a1033e4bfe Fix structured output leaks in tool-calling loops (#5897)
* Fix structured output leaks in tool-calling loops

* addressing comments

* drop scripts

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

* merge

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

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

* adjusted bedrock cassettes

* adjusting cassettes for bedrock

* fix test

* Update VCR configuration to use 'host' instead of 'bedrock_host' for request matching
2026-05-27 13:20:53 -07:00
iris-clawd
90a37c94c1 docs: remove Skills Repository entry from changelog (#5953)
* docs: remove Skills Repository entry from changelog

* docs: also remove Skills Repository entry from translated changelogs
2026-05-27 13:15:55 -07:00
Greyson LaLonde
c5ea415cda chore(crewai-tools): drop self-explanatory comments
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Check Documentation Broken Links / Check broken links (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Nightly Canary Release / Check for new commits (push) Has been cancelled
Nightly Canary Release / Build nightly packages (push) Has been cancelled
Nightly Canary Release / Publish nightly to PyPI (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
2026-05-26 16:25:07 -07:00
Lucas Gomide
1bac7d3afb document one-time admin package install step (#5941)
* docs: document one-time admin package install step

The previous revision described a manual "install in Salesforce first,
then connect from AMP" flow that nobody actually follows, and linked to
a private repo customers can't access.

* docs: point Integrations link at crewai_plus/unified_tools
2026-05-26 19:06:51 -04:00
Greyson LaLonde
3a52919a35 chore(devtools): drop self-explanatory comments 2026-05-26 15:50:44 -07:00
Greyson LaLonde
07569f04ee chore(crewai-files): drop self-explanatory comments 2026-05-26 15:01:22 -07:00
Lucas Gomide
952c84c195 Add Agent Control Plane docs (#5939)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Check Documentation Broken Links / Check broken links (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
* docs: split Agent Control Plane into Overview/Monitoring/Rules and localize

Mirror the secrets-manager folder convention for ACP: one folder per
locale with overview, monitoring, and rules pages. Replaces the two
flat agent-control-plane.mdx / agent-control-plane-rules.mdx files
with a 3-page layout, adds full translations for pt-BR, ko, and ar,
and rewires docs.json to register the new paths under each locale's
Manage group across the same 4 versions where ACP already lived.

* docs: flag Agent Control Plane as Beta in overview pages

Add a Beta callout right after the lead screenshot on the ACP
overview page across en, pt-BR, ko, and ar, matching the convention
used by Secrets Manager.
2026-05-26 14:42:27 -04:00
Greyson LaLonde
840ba89900 chore(crewai-core): drop self-explanatory comments 2026-05-26 10:33:18 -07:00
Greyson LaLonde
fd10c64148 chore(crewai): drop self-explanatory comments 2026-05-26 10:23:33 -07:00
Lorenze Jay
77a61274dc feat(planning): enhance planning configuration and observation handling (#5913)
* feat(planning): enhance planning configuration and observation handling

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

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

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

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

- And linted

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

Move the missing/empty-file short-circuit above store_lock so the lock is
only acquired when there is actually a file to read. save() and the real
read remain locked.
2026-05-26 12:52:31 -03:00
Greyson LaLonde
bad64b1ee6 chore(cli): drop self-explanatory comments
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
2026-05-26 01:05:25 -07:00
Greyson LaLonde
867df0f633 fix(checkpoint): drop unroundtrippable callbacks and adapter state
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Nightly Canary Release / Check for new commits (push) Has been cancelled
Nightly Canary Release / Build nightly packages (push) Has been cancelled
Nightly Canary Release / Publish nightly to PyPI (push) Has been cancelled
- callable_to_string returns None for lambdas/closures instead of an
  unresolvable dotted path; Crew filters Nones out of restored callback
  lists.
- EventNode.event serializer honors info.mode so mode='json' calls cascade
  properly into nested event payloads.
- RagTool.adapter serializes to None (post-validator rebuilds from
  config); concrete adapters hold runtime state that can't be round-tripped.
2026-05-25 19:24:02 -07:00
Greyson LaLonde
c3e2001d52 fix(checkpoint): serialize type[BaseModel] fields as JSON schema
Some checks failed
Nightly Canary Release / Check for new commits (push) Has been cancelled
Nightly Canary Release / Build nightly packages (push) Has been cancelled
Nightly Canary Release / Publish nightly to PyPI (push) Has been cancelled
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Vulnerability Scan / pip-audit (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
Subclass redeclarations of args_schema/response_format dropped the
parent's Annotated PlainSerializer, causing PydanticSerializationError
on model_dump(mode='json'). Replace with @field_serializer decorators
backed by a shared serialize_model_class helper:

- BaseTool: covers RecallMemoryTool, RememberTool, AskQuestionTool,
  DelegateWorkTool, AddImageTool, ReadFileTool
- BaseLLM (check_fields=False): covers LLM, Anthropic, OpenAI, Gemini,
  Bedrock
- LiteAgent.response_format
- A2AConfig / A2AClientConfig response_model
2026-05-23 03:50:24 +08:00
Greyson LaLonde
306f5989b4 fix(checkpoint): avoid orphan task_started on resume scope restore
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Vulnerability Scan / pip-audit (push) Has been cancelled
Build uv cache / build-cache (3.10) (push) Has been cancelled
Build uv cache / build-cache (3.11) (push) Has been cancelled
Build uv cache / build-cache (3.12) (push) Has been cancelled
Build uv cache / build-cache (3.13) (push) Has been cancelled
Move scope restoration from Crew-level global push to a per-task push
inside Task via resume_task_scope() in event_context. Fixes orphan
task_started warning, hierarchical resume (manager_agent now eligible
for _resuming), and parallel async resume (each contextvars copy owns
its own scope). Tests added.
2026-05-23 01:20:15 +08:00
Greyson LaLonde
4990041ef7 chore(deps): force starlette>=1.0.1 for PYSEC-2026-161
starlette <1.0.1 has PYSEC-2026-161 (missing Host header validation
poisons request.url.path, bypassing path-based auth). Pulled in as a
transitive of fastapi. Override-dependencies forces the patched
version; lock regenerated against starlette 1.0.1.
2026-05-22 23:33:08 +08:00
Greyson LaLonde
88e95befe7 fix(experimental): allow AgentExecutor restore from checkpoint
llm and prompt were declared required with exclude=True, making the
model un-restorable from its own serialized output. Mirror the
CrewAgentExecutor pattern: make them nullable with default None, keep
exclude=True, and re-attach llm on the resume path alongside the other
re-attached fields. Guard the two prompt-deref sites so the runtime
invariant survives the looser type.
2026-05-22 23:24:12 +08:00
Matt Aitchison
179c20b352 ci: pin third-party actions to commit SHAs (#5869)
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
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
Mark stale issues and pull requests / stale (push) Has been cancelled
* ci: pin third-party actions to commit SHAs

Pin third-party GitHub Actions in workflow files to immutable 40-char
commit SHAs per the org security policy. Mutable refs like @v4 can be
silently re-pointed by a compromised upstream; SHAs cannot. Trailing
version comments let Dependabot/Renovate continue to manage updates.

Related to [COR-51](https://linear.app/crewai/issue/COR-51).

* ci: disable persist-credentials in pip-audit checkout

Address CodeRabbit feedback on PR #5869: the pip-audit workflow is
read-only and never needs an authenticated git context, so opt out of
persisting the GITHUB_TOKEN in the local git config per the
actions/checkout security guidance.
2026-05-21 18:08:34 -05:00
656 changed files with 54109 additions and 19638 deletions

View File

@@ -23,7 +23,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
- name: Install uv
uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6
@@ -39,7 +39,7 @@ jobs:
echo "Cache populated successfully"
- name: Save uv caches
uses: actions/cache/save@v4
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: |
~/.cache/uv

View File

@@ -59,7 +59,7 @@ jobs:
# your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
# Add any setup steps before running the `github/codeql-action/init` action.
# This includes steps like installing compilers or runtimes (`actions/setup-node`
@@ -69,7 +69,7 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v4
uses: github/codeql-action/init@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
@@ -98,6 +98,6 @@ jobs:
exit 1
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4
uses: github/codeql-action/analyze@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5
with:
category: "/language:${{matrix.language}}"

View File

@@ -18,10 +18,10 @@ jobs:
name: Check broken links
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
- name: Set up Node
uses: actions/setup-node@v4
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: "22"

View File

@@ -28,7 +28,7 @@ jobs:
private-key: ${{ secrets.CREWAI_TOOL_SPECS_PRIVATE_KEY }}
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
ref: ${{ github.head_ref }}
token: ${{ steps.app-token.outputs.token }}

View File

@@ -12,7 +12,7 @@ jobs:
outputs:
code: ${{ steps.filter.outputs.code }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
- uses: dorny/paths-filter@d1c1ffe0248fe513906c8e24db8ea791d46f8590 # v3
id: filter
with:
@@ -26,11 +26,11 @@ jobs:
if: needs.changes.outputs.code == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
- name: Restore global uv cache
id: cache-restore
uses: actions/cache/restore@v4
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: |
~/.cache/uv
@@ -58,7 +58,7 @@ jobs:
- name: Save uv caches
if: steps.cache-restore.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: |
~/.cache/uv

View File

@@ -18,7 +18,7 @@ jobs:
outputs:
has_changes: ${{ steps.check.outputs.has_changes }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
fetch-depth: 0
@@ -41,7 +41,7 @@ jobs:
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
- name: Install uv
uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6
@@ -87,7 +87,7 @@ jobs:
rm dist/.gitignore
- name: Upload artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: dist
path: dist/
@@ -110,7 +110,7 @@ jobs:
enable-cache: false
- name: Download artifacts
uses: actions/download-artifact@v4
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: dist
path: dist

View File

@@ -24,12 +24,12 @@ jobs:
echo "tag=" >> $GITHUB_OUTPUT
fi
- uses: actions/checkout@v4
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
ref: ${{ steps.release.outputs.tag || github.ref }}
- name: Set up Python
uses: actions/setup-python@v5
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: "3.12"
@@ -42,7 +42,7 @@ jobs:
rm dist/.gitignore
- name: Upload artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: dist
path: dist/
@@ -58,7 +58,7 @@ jobs:
id-token: write
contents: read
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
ref: ${{ inputs.release_tag || github.ref }}
@@ -70,7 +70,7 @@ jobs:
enable-cache: false
- name: Download artifacts
uses: actions/download-artifact@v4
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: dist
path: dist

View File

@@ -14,7 +14,7 @@ jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v9
- uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-label: 'no-issue-activity'

View File

@@ -12,7 +12,7 @@ jobs:
outputs:
code: ${{ steps.filter.outputs.code }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
- uses: dorny/paths-filter@d1c1ffe0248fe513906c8e24db8ea791d46f8590 # v3
id: filter
with:
@@ -34,13 +34,13 @@ jobs:
group: [1, 2, 3, 4, 5, 6, 7, 8]
steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
fetch-depth: 0 # Fetch all history for proper diff
- name: Restore global uv cache
id: cache-restore
uses: actions/cache/restore@v4
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: |
~/.cache/uv
@@ -61,7 +61,7 @@ jobs:
run: uv sync --all-groups --all-extras
- name: Restore test durations
uses: actions/cache/restore@v4
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: .test_durations_py*
key: test-durations-py${{ matrix.python-version }}
@@ -108,7 +108,7 @@ jobs:
- name: Save uv caches
if: steps.cache-restore.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: |
~/.cache/uv

View File

@@ -12,7 +12,7 @@ jobs:
outputs:
code: ${{ steps.filter.outputs.code }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
- uses: dorny/paths-filter@d1c1ffe0248fe513906c8e24db8ea791d46f8590 # v3
id: filter
with:
@@ -33,11 +33,11 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
- name: Restore global uv cache
id: cache-restore
uses: actions/cache/restore@v4
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: |
~/.cache/uv
@@ -62,7 +62,7 @@ jobs:
- name: Save uv caches
if: steps.cache-restore.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: |
~/.cache/uv

View File

@@ -23,11 +23,11 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
- name: Restore global uv cache
id: cache-restore
uses: actions/cache/restore@v4
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: |
~/.cache/uv
@@ -55,14 +55,14 @@ jobs:
- name: Save durations to cache
if: always()
uses: actions/cache/save@v4
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: .test_durations_py*
key: test-durations-py${{ matrix.python-version }}
- name: Save uv caches
if: steps.cache-restore.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: |
~/.cache/uv

View File

@@ -16,11 +16,13 @@ jobs:
name: pip-audit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
persist-credentials: false
- name: Restore global uv cache
id: cache-restore
uses: actions/cache/restore@v4
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: |
~/.cache/uv
@@ -62,6 +64,7 @@ jobs:
--ignore-vuln PYSEC-2025-197 \
--ignore-vuln PYSEC-2025-210 \
--ignore-vuln PYSEC-2026-139 \
--ignore-vuln GHSA-rrmf-rvhw-rf47 \
--ignore-vuln PYSEC-2025-211 \
--ignore-vuln PYSEC-2025-212 \
--ignore-vuln PYSEC-2025-213 \
@@ -69,7 +72,8 @@ jobs:
--ignore-vuln PYSEC-2025-215 \
--ignore-vuln PYSEC-2025-216 \
--ignore-vuln PYSEC-2025-217 \
--ignore-vuln PYSEC-2025-218
--ignore-vuln PYSEC-2025-218 \
--ignore-vuln GHSA-f4j7-r4q5-qw2c
# Ignored CVEs:
# PYSEC-2024-277 - joblib 1.5.3: disputed; NumpyArrayWrapper only used with trusted caches
# PYSEC-2026-89 - markdown 3.10.2: DoS via malformed HTML; fix 3.8.1 — already past, advisory range is stale
@@ -78,7 +82,11 @@ jobs:
# PYSEC-2025-183 - pyjwt 2.12.1: disputed weak-encryption claim; key length is application-chosen
# PYSEC-2025-189..197 - torch 2.11.0: memory-corruption/DoS in functions only reachable via untrusted models; no fix available
# PYSEC-2025-210, PYSEC-2026-139 - torch 2.11.0: profiler/deserialization issues; no fix available
# GHSA-rrmf-rvhw-rf47 - torch 2.11.0 (CVE-2025-3000, alias of PYSEC-2025-194): memory corruption in torch.jit.script, CVSS 1.9, local-only; affected <=2.12.0, no fix available. pip-audit reports it under the GHSA id so the PYSEC ignore above does not catch it.
# PYSEC-2025-211..218 - transformers 5.5.4: deserialization/code injection via malicious model checkpoints; no fix available
# GHSA-f4j7-r4q5-qw2c - chromadb 1.1.1 (CVE-2026-45829): pre-auth RCE via /api/v2/tenants/{tenant}/databases/{db}/collections when trust_remote_code=true.
# Advisory: vulnerable >=1.0.0,<=1.5.9, firstPatchedVersion=none. We only use chromadb.PersistentClient (lib/crewai/src/crewai/rag/chromadb/factory.py)
# and chromadb.utils.embedding_functions; the chromadb HTTP server is never started, so the vulnerable route is not exposed.
continue-on-error: true
- name: Display results
@@ -110,14 +118,14 @@ jobs:
- name: Upload pip-audit report
if: always()
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: pip-audit-report
path: pip-audit-report.json
- name: Save uv caches
if: steps.cache-restore.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: |
~/.cache/uv

2
.gitignore vendored
View File

@@ -31,3 +31,5 @@ chromadb-*.lock
blogs/*
secrets/*
UNKNOWN.egg-info/
demos/*
.crewai/*

View File

@@ -28,7 +28,35 @@ repos:
hooks:
- id: pip-audit
name: pip-audit
entry: bash -c 'source .venv/bin/activate && uv run pip-audit --skip-editable --ignore-vuln CVE-2026-3219' --
# Keep this ignore list in sync with .github/workflows/vulnerability-scan.yml.
entry: >-
bash -c 'source .venv/bin/activate && uv run pip-audit --skip-editable
--ignore-vuln PYSEC-2024-277
--ignore-vuln PYSEC-2026-89
--ignore-vuln PYSEC-2026-97
--ignore-vuln PYSEC-2025-148
--ignore-vuln PYSEC-2025-183
--ignore-vuln PYSEC-2025-189
--ignore-vuln PYSEC-2025-190
--ignore-vuln PYSEC-2025-191
--ignore-vuln PYSEC-2025-192
--ignore-vuln PYSEC-2025-193
--ignore-vuln PYSEC-2025-194
--ignore-vuln PYSEC-2025-195
--ignore-vuln PYSEC-2025-196
--ignore-vuln PYSEC-2025-197
--ignore-vuln PYSEC-2025-210
--ignore-vuln PYSEC-2026-139
--ignore-vuln GHSA-rrmf-rvhw-rf47
--ignore-vuln PYSEC-2025-211
--ignore-vuln PYSEC-2025-212
--ignore-vuln PYSEC-2025-213
--ignore-vuln PYSEC-2025-214
--ignore-vuln PYSEC-2025-215
--ignore-vuln PYSEC-2025-216
--ignore-vuln PYSEC-2025-217
--ignore-vuln PYSEC-2025-218
--ignore-vuln GHSA-f4j7-r4q5-qw2c' --
language: system
pass_filenames: false
stages: [pre-push, manual]

View File

@@ -5,12 +5,105 @@ from collections.abc import Generator
import gzip
import os
from pathlib import Path
import re
import tempfile
from typing import Any
from dotenv import load_dotenv
import pytest
from vcr.request import Request # type: ignore[import-untyped]
def _patch_vcrpy_aiohttp_compat() -> None:
"""Keep vcrpy's aiohttp stub working under aiohttp 3.14.0.
aiohttp 3.14.0 (pulled in to fix GHSA-jg22-mg44-37j8 and GHSA-hg6j-4rv6-33pg):
* removed ``aiohttp.streams.AsyncStreamReaderMixin`` (folded into ``StreamReader``),
which vcrpy's ``MockStream`` still subclasses -- vcr's patch machinery then raises
``AttributeError`` at collection time; and
* added a required ``stream_writer`` keyword-only arg to ``ClientResponse.__init__``,
which vcrpy's ``MockClientResponse`` does not pass -- raising ``TypeError`` at
cassette playback.
Restore the mixin, then rebuild ``MockClientResponse``'s ``super().__init__`` call from
the live ``ClientResponse`` signature (defaulting every required keyword-only arg to
``None``, mirroring vcrpy's original call) so it also survives future aiohttp additions.
"""
import asyncio
import inspect
from aiohttp import streams
from aiohttp.client_reqrep import ClientResponse
if not hasattr(streams, "AsyncStreamReaderMixin"):
class AsyncStreamReaderMixin:
__slots__ = ()
def __aiter__(self) -> streams.AsyncStreamIterator[bytes]:
return streams.AsyncStreamIterator(self.readline) # type: ignore[attr-defined]
def iter_chunked(self, n: int) -> streams.AsyncStreamIterator[bytes]:
return streams.AsyncStreamIterator(lambda: self.read(n)) # type: ignore[attr-defined]
def iter_any(self) -> streams.AsyncStreamIterator[bytes]:
return streams.AsyncStreamIterator(self.readany) # type: ignore[attr-defined]
def iter_chunks(self) -> streams.ChunkTupleAsyncStreamIterator:
return streams.ChunkTupleAsyncStreamIterator(self) # type: ignore[arg-type]
streams.AsyncStreamReaderMixin = AsyncStreamReaderMixin # type: ignore[attr-defined]
# Importing the stub builds MockStream/MockClientResponse, so it must run after the
# mixin is restored above.
import vcr.stubs.aiohttp_stubs as aiohttp_stubs # type: ignore[import-untyped]
if getattr(aiohttp_stubs.MockClientResponse, "_crewai_aiohttp_patched", False):
return
keyword_only = [
name
for name, param in inspect.signature(ClientResponse.__init__).parameters.items()
if param.kind is inspect.Parameter.KEYWORD_ONLY
]
class _NullStreamWriter:
# aiohttp 3.14.0 reads stream_writer.output_size in the "request already
# sent" branch (writer is None), so None is not enough -- supply a stub.
output_size = 0
fallback_loop: list[asyncio.AbstractEventLoop] = []
def _resolve_loop() -> asyncio.AbstractEventLoop:
# MockClientResponse is normally built inside aiohttp's running loop, so
# prefer that. In a sync context there is no running loop; avoid
# asyncio.get_event_loop(), which on 3.12+ emits a DeprecationWarning
# (and can RuntimeError) when no current loop is set. Use one cached
# loop instead -- the mock only stores it and calls loop.get_debug().
try:
return asyncio.get_running_loop()
except RuntimeError:
if not fallback_loop:
fallback_loop.append(asyncio.new_event_loop())
return fallback_loop[0]
def _mock_client_response_init(
self: Any, method: str, url: Any, request_info: Any = None
) -> None:
kwargs: dict[str, Any] = dict.fromkeys(keyword_only)
kwargs["request_info"] = request_info
if "loop" in kwargs:
kwargs["loop"] = _resolve_loop()
if "stream_writer" in kwargs:
kwargs["stream_writer"] = _NullStreamWriter()
ClientResponse.__init__(self, method, url, **kwargs)
aiohttp_stubs.MockClientResponse.__init__ = _mock_client_response_init
aiohttp_stubs.MockClientResponse._crewai_aiohttp_patched = True
_patch_vcrpy_aiohttp_compat()
from vcr.request import Request # type: ignore[import-untyped] # noqa: E402
try:
@@ -20,8 +113,25 @@ except ModuleNotFoundError:
env_test_path = Path(__file__).parent / ".env.test"
load_dotenv(env_test_path, override=True)
load_dotenv(override=True)
load_dotenv(env_test_path, override=False)
load_dotenv(override=False)
BEDROCK_HOST_PLACEHOLDER = "bedrock-runtime.vcr.amazonaws.com"
_BEDROCK_HOST_RE = re.compile(r"^bedrock-runtime\.[a-z0-9-]+\.amazonaws\.com$")
def _normalize_bedrock_host(host: str) -> str:
if _BEDROCK_HOST_RE.match(host):
return BEDROCK_HOST_PLACEHOLDER
return host
def bedrock_host_matcher(r1: Request, r2: Request) -> bool: # type: ignore[no-any-unimported]
"""Match Bedrock requests across AWS regions (CI uses us-east-1, local may use us-west-2)."""
return _normalize_bedrock_host(r1.host or "") == _normalize_bedrock_host(
r2.host or ""
)
def _patched_make_vcr_request(httpx_request: Any, **kwargs: Any) -> Any:
@@ -188,6 +298,7 @@ HEADERS_TO_FILTER = {
"anthropic-ratelimit-tokens-remaining": "ANTHROPIC-RATELIMIT-TOKENS-REMAINING-XXX",
"anthropic-ratelimit-tokens-reset": "ANTHROPIC-RATELIMIT-TOKENS-RESET-XXX",
"x-amz-date": "X-AMZ-DATE-XXX",
"x-amz-security-token": "X-AMZ-SECURITY-TOKEN-XXX",
"amz-sdk-invocation-id": "AMZ-SDK-INVOCATION-ID-XXX",
"accept-encoding": "ACCEPT-ENCODING-XXX",
"x-amzn-requestid": "X-AMZN-REQUESTID-XXX",
@@ -212,6 +323,10 @@ def _filter_request_headers(request: Request) -> Request: # type: ignore[no-any
placeholder_host = "fake-azure-endpoint.openai.azure.com"
request.uri = request.uri.replace(original_host, placeholder_host)
# Normalize Bedrock regional endpoints so cassettes work in any AWS region.
if request.host and _BEDROCK_HOST_RE.match(request.host):
request.uri = request.uri.replace(request.host, BEDROCK_HOST_PLACEHOLDER)
return request
@@ -229,6 +344,11 @@ def _filter_response_headers(response: dict[str, Any]) -> dict[str, Any] | None:
if body == "" or body == b"" or content_length == ["0"]:
return None
status_code = response.get("status", {}).get("code")
if isinstance(status_code, int) and status_code >= 400:
# Avoid persisting auth/model errors when re-recording without valid AWS creds.
return None
for encoding_header in ["Content-Encoding", "content-encoding"]:
if encoding_header in headers:
encoding = headers.pop(encoding_header)
@@ -279,6 +399,11 @@ def vcr_cassette_dir(request: Any) -> str:
return str(cassette_dir)
def pytest_recording_configure(vcr: Any, config: Any) -> None:
"""Register custom VCR matchers for each test cassette session."""
vcr.register_matcher("bedrock_host", bedrock_host_matcher)
@pytest.fixture(scope="module")
def vcr_config(vcr_cassette_dir: str) -> dict[str, Any]:
"""Configure VCR with organized cassette storage."""

View File

@@ -4,6 +4,281 @@ description: "تحديثات المنتج والتحسينات وإصلاحات
icon: "clock"
mode: "wide"
---
<Update label="11 يونيو 2026">
## v1.14.7
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.7)
## ما الذي تغير
### الميزات
- إضافة واجهات خلفية افتراضية قابلة للتوصيل للذاكرة، والمعرفة، وrag، وflow.
- عرض السبب الحقيقي للإنهاء، ومعلمات العينة، وresponse.id في أحداث LLM.
- تصنيف مشغلات DSL كزخارف واعية للمسار.
- إضافة واجهة برمجة تطبيقات الدردشة لتدفقات المحادثة.
- جعل واجهة القفل قابلة للتجاوز.
- بناء FlowDefinition من بيانات التعريف الخاصة بـ Flow DSL.
- إضافة مزود LLM من Snowflake Cortex الأصلي.
- إضافة دعم لملفات الوكلاء المدربين من crew.
### إصلاحات الأخطاء
- إصلاح نقطة التحقق لإعادة بناء BaseLLM مخصص كـ LLM ملموس عند الاستعادة.
- تقييد الاستعادة على علامة لمنع اللقطات الحية من إعادة التشغيل كاستئناف.
- تحديد حالة وقت التشغيل لكل تشغيل للحد من النمو وعزل التشغيل المتزامن.
- إصلاح إعدادات التتبع على crewai-login.
- احترام suppress_flow_events لأحداث تنفيذ الطريقة.
- استعادة [project.scripts] في حزمة crewai لتثبيت أداة uv.
- حل مشكلات CVE الخاصة بـ pip-audit لـ aiohttp وdocling وdocling-core.
- إصلاح إدخال الملفات الذي لا يعمل بشكل موثوق.
- إصلاح تاريخ نتائج أدوات Snowflake Claude غير المكتملة.
### الوثائق
- تحديث سجل التغييرات والإصدار لـ v1.14.7.
- تحديث وثائق جامع OpenTelemetry.
- تحديث دليل NVIDIA Nemotron LLM.
- إضافة دليل تكامل Databricks.
- إضافة دليل تكامل Snowflake.
### الأداء
- تحسين سرعة استيراد crewai من خلال تحميل مستندات docling بشكل كسول.
### إعادة الهيكلة
- تبسيط تقييم شروط التدفق ليكون بلا حالة لكل حدث.
- فصل منطق المحادثة عن وقت التشغيل وإضافة تعريف المحادثة.
- تقسيم `flow.py` إلى DSL، وتعريف، ووقت تشغيل.
## المساهمون
@Luzk, @alex-clawd, @devin-ai-integration[bot], @greysonlalonde, @gvieira, @jessemiller, @lorenzejay, @lucasgomide, @mattatcha, @vinibrsl
</Update>
<Update label="10 يونيو 2026">
## v1.14.7rc2
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.7rc2)
## ما الذي تغير
### إصلاحات الأخطاء
- استعادة البوابة على علامة لمنع اللقطات الحية من إعادة التشغيل كاستئناف
### الوثائق
- تحديث سجل التغييرات والإصدار لـ v1.14.7rc1
## المساهمون
@greysonlalonde
</Update>
<Update label="10 يونيو 2026">
## v1.14.7rc1
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.7rc1)
## ما الذي تغير
### الميزات
- إضافة `reset_runtime_state` لإطلاق حالة الحافلة المتراكمة
- التعامل مع دعم كل من الموجهات المخصصة
- فصل منطق المحادثة عن وقت التشغيل وإضافة `conversational_definition`
### إصلاحات الأخطاء
- إصلاح نطاق حالة وقت التشغيل لكل تشغيل للحد من النمو وعزل التشغيلات المتزامنة
- إصلاح إعدادات القياس عن بُعد على `crewai-login`
- إصلاح احترام `suppress_flow_events` لفعاليات تنفيذ الأساليب
### الوثائق
- تحديث صور OpenTelemetry
- تحديث الوثائق لتعكس الحالة الجديدة لجمع بيانات OpenTelemetry
- تحديث سجل التغييرات والإصدار لـ v1.14.7a4
### إعادة الهيكلة
- تبسيط تقييم شرط التدفق ليكون بلا حالة لكل حدث
- تحسين دورة توجيه المحادثة مع تقليل مسار واحد
## المساهمون
@greysonlalonde, @lorenzejay, @lucasgomide, @vinibrsl
</Update>
<Update label="9 يونيو 2026">
## v1.14.7a4
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.7a4)
## ما الذي تغير
### الميزات
- نقل وقت التشغيل @listen/@router لقراءة من FlowDefinition
- إضافة واجهات خلفية افتراضية قابلة للتوصيل للذاكرة، والمعرفة، وrag، وflow
### الوثائق
- تحديث سجل التغييرات والإصدار لـ v1.14.7a3
## المساهمون
@greysonlalonde, @mattatcha, @vinibrsl
</Update>
<Update label="8 يونيو 2026">
## v1.14.7a3
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.7a3)
## ما الذي تغير
### إصلاحات الأخطاء
- إصلاح تعرض `ask_for_human_input` في `AgentExecutor` التجريبي
- حل مشكلات CVEs الخاصة بـ pip-audit لـ `aiohttp`، `docling`، `docling-core`، و `pip`
### إعادة هيكلة
- نقل `@start` لقراءة من `FlowDefinition`
### الوثائق
- تحديث سجل التغييرات والإصدار لـ v1.14.7a2
## المساهمون
@greysonlalonde، @lorenzejay، @vinibrsl
</Update>
<Update label="5 يونيو 2026">
## v1.14.7a2
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.7a2)
## ما الذي تغير
### الميزات
- إضافة دعم تتبع تدفقات المحادثة.
- تحديث وثائق تدفق المحادثة لاستخدام `handle_turn`.
- عرض السبب الحقيقي لإنهاء المحادثة، ومعلمات العينة، و`response.id` في أحداث LLM.
- تصنيف مشغلات DSL كزخارف واعية بالمسار.
- تنفيذ واجهة برمجة التطبيقات للدردشة لتدفقات المحادثة.
- جعل قفل الخلفية قابلاً للتجاوز في متجر القفل.
- تقسيم أحادي تدفق DSL إلى وحدات زخرفية مركزة.
- تسطيح استخدام ذاكرة التخزين المؤقت LiteLLM/أعداد الأسباب الفرعية في `_usage_to_dict`.
- بناء `FlowDefinition` من بيانات التعريف الخاصة بتدفق DSL.
### الوثائق
- إضافة دليل NVIDIA Nemotron LLM.
- توثيق عمليات نشر المونوريبو.
- تحديث سجل التغييرات والإصدار لـ v1.14.7a1.
## المساهمون
@alex-clawd, @gvieira, @lorenzejay, @lucasgomide, @mattatcha, @vinibrsl
</Update>
<Update label="3 يونيو 2026">
## v1.14.7a1
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.7a1)
## ما الذي تغير
### الميزات
- إضافة دعم ملفات الوكلاء المدربين
- إضافة مزود LLM الأصلي لـ Snowflake Cortex
- إضافة دليل تكامل Databricks
- إضافة دليل تكامل Snowflake
### إصلاحات الأخطاء
- إصلاح CLI عن طريق استعادة `[project.scripts]` في حزمة crewai لتثبيت أداة UV
- حل مشكلات موثوقية إدخال الملفات
- إصلاح تاريخ نتائج الأدوات غير المكتملة في Snowflake Claude
- التعامل مع استدعاءات الأدوات الممثلة كسلاسل لـ Snowflake Claude
- إعادة تفعيل مستمعي `or_` متعدد المصادر عبر دورات مدفوعة بالموجه
### الأداء
- تحسين سرعة استيراد crewai عن طريق تحميل استيرادات docling بشكل كسول
### إعادة هيكلة
- تقسيم `flow.py` إلى DSL، تعريف، وتشغيل
## المساهمون
@Luzk, @alex-clawd, @devin-ai-integration[bot], @greysonlalonde, @jessemiller, @lorenzejay, @vinibrsl
</Update>
<Update label="28 مايو 2026">
## v1.14.6
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.6)
## ما الذي تغير
### الميزات
- تحسين StdioTransport لمنع تسرب متغيرات البيئة
- تعزيز تكوين التخطيط ومعالجة الملاحظات
- إعلان env_vars على DatabricksQueryTool
- إضافة وثائق خطة التحكم في الوكيل
### إصلاحات الأخطاء
- إصلاح تسرب المخرجات المنظمة في حلقات استدعاء الأدوات
- حذف ردود الاستدعاء غير القابلة للعودة وحالة المحول في نقطة التحقق
- تسلسل الحقول من النوع [BaseModel] كـ JSON schema في نقطة التحقق
- تجنب مهمة orphan task_started عند استعادة نطاق الاستئناف
- السماح لـ AgentExecutor بالاستعادة من نقطة التحقق
- تصحيح خطأ الكتابة من mongodb إلى pymongo في package_dependencies
### الوثائق
- إضافة كتلة تنقل وثائق ACP (بيتا) إلى صفحات خطة التحكم في الوكيل
- إزالة المراجع إلى العمليات التوافقية من صفحة العمليات
- إعادة هيكلة صفحة نقاط التحقق
- توثيق خطوة تثبيت حزمة الإدارة لمرة واحدة
- نقل Secrets Manager / Workload Identity من replicated-config
- إزالة تعبيرات `{" "}` JSX التي تكسر عرض `<Steps>`
### إعادة الهيكلة
- نقل مستودع المهارات إلى experimental + CREWAI_EXPERIMENTAL gate
## المساهمون
@akaKuruma, @alex-clawd, @github-actions[bot], @greysonlalonde, @heitorado, @iris-clawd, @lorenzejay, @lucasgomide, @mattatcha, @thiagomoretto, @vinibrsl
</Update>
<Update label="27 مايو 2026">
## v1.14.6a2
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.6a2)
## ما الذي تغير
### الميزات
- تحسين `StdioTransport` لمنع تسرب متغيرات البيئة
- تحسين تكوين التخطيط ومعالجة المراقبة
- إعلان `env_vars` على `DatabricksQueryTool`
- إضافة وثائق خطة التحكم بالوكيل
### إصلاحات الأخطاء
- إصلاح تسرب المخرجات المنظمة في حلقات استدعاء الأدوات
- حذف الاستدعاءات غير القابلة للعودة وحالة المحول في نقاط التحقق
- تسلسل حقول `type[BaseModel]` كـ JSON schema في نقاط التحقق
- تجنب `task_started` اليتيمة عند استعادة نطاق الاستئناف
- السماح لـ `AgentExecutor` بالاستعادة من نقطة تحقق
- تصحيح خطأ مطبعي في MongoDB إلى `pymongo` في تبعيات الحزمة
### الوثائق
- إعادة هيكلة صفحة نقاط التحقق
- توثيق خطوة تثبيت حزمة الإدارة لمرة واحدة
- نقل Secrets Manager / Workload Identity من replicated-config
- إزالة إدخال Skills Repository من سجل التغييرات
## المساهمون
@github-actions[bot], @greysonlalonde, @heitorado, @iris-clawd, @lorenzejay, @lucasgomide, @mattatcha, @thiagomoretto, @vinibrsl
</Update>
<Update label="21 مايو 2026">
## v1.14.6a1
@@ -12,7 +287,6 @@ mode: "wide"
## ما الذي تغير
### الميزات
- إضافة مستودع المهارات مع التسجيل، التخزين المؤقت، واجهة سطر الأوامر، وتكامل SDK
- توليد ملاحظات إصدار مصنفة للمؤسسات
### إصلاحات الأخطاء

View File

@@ -70,13 +70,39 @@ mode: "wide"
## إنشاء الوكلاء
هناك طريقتان لإنشاء الوكلاء في CrewAI: باستخدام **تهيئة YAML (موصى بها)** أو تعريفهم **مباشرة في الكود**.
هناك طريقتان شائعتان لإنشاء الوكلاء في CrewAI: باستخدام **تهيئة JSONC (الموصى بها للـ crews الجديدة)** أو تعريفهم **مباشرة في الكود**.
### تهيئة YAML (موصى بها)
### تهيئة JSONC (موصى بها)
توفر تهيئة YAML طريقة أنظف وأكثر قابلية للصيانة لتعريف الوكلاء. نوصي بشدة باستخدام هذا النهج في مشاريع CrewAI.
المشاريع الجديدة التي تُنشأ عبر `crewai create crew <name>` تستخدم تهيئة JSON-first. يُعرّف كل Agent في `agents/<agent_name>.jsonc`، ويحدد `crew.jsonc` أي Agents تدخل في الـ crew.
بعد إنشاء مشروع CrewAI كما هو موضح في قسم [التثبيت](/ar/installation)، انتقل إلى ملف `src/latest_ai_development/config/agents.yaml` وعدّل القالب ليتوافق مع متطلباتك.
```jsonc agents/researcher.jsonc
{
"role": "{topic} Senior Data Researcher",
"goal": "Uncover cutting-edge developments in {topic}",
"backstory": "You find the most relevant information and present it clearly.",
"llm": "openai/gpt-4o",
"tools": ["SerperDevTool"],
"settings": {
"verbose": true,
"allow_delegation": false
}
}
```
استخدم `{placeholder}` داخل `role` أو `goal` أو `backstory`. ضع القيم الافتراضية في `inputs` داخل `crew.jsonc`؛ وسيطلب `crewai run` أي قيم ناقصة. يمكن وضع حقول السلوك مثل `verbose` و `allow_delegation` و `max_iter` و `memory` و `cache` و `planning_config` في المستوى الأعلى أو داخل `settings`.
<Note>
يدعم JSONC التعليقات والفواصل النهائية. إذا وُجد `agents/<name>.jsonc` و `agents/<name>.json` معًا، يستخدم CrewAI ملف JSONC.
</Note>
### تهيئة YAML الكلاسيكية
المشاريع الكلاسيكية التي تُنشأ عبر `crewai create crew <name> --classic` تستخدم `config/agents.yaml` وفئة `@CrewBase` في `crew.py`.
تظل تهيئة YAML مدعومة للمشاريع الحالية المبنية بـ Python/YAML وللفِرق التي تفضل تعريف الوكلاء من خلال فئة `@CrewBase`.
بعد إنشاء مشروع كلاسيكي، انتقل إلى ملف `src/<project_name>/config/agents.yaml` وعدّل القالب ليتوافق مع متطلباتك.
<Note>
ستُستبدل المتغيرات في ملفات YAML (مثل `{topic}`) بقيم من مدخلاتك عند تشغيل الطاقم:
@@ -88,7 +114,7 @@ crew.kickoff(inputs={'topic': 'AI Agents'})
إليك مثالًا على كيفية تهيئة الوكلاء باستخدام YAML:
```yaml agents.yaml
# src/latest_ai_development/config/agents.yaml
# src/<project_name>/config/agents.yaml
researcher:
role: >
{topic} Senior Data Researcher
@@ -113,7 +139,7 @@ reporting_analyst:
لاستخدام تهيئة YAML في الكود، أنشئ فئة طاقم ترث من `CrewBase`:
```python Code
# src/latest_ai_development/crew.py
# src/<project_name>/crew.py
from crewai import Agent, Crew, Process
from crewai.project import CrewBase, agent, crew
from crewai_tools import SerperDevTool

View File

@@ -5,225 +5,419 @@ icon: floppy-disk
mode: "wide"
---
<Warning>
الـ Checkpointing في اصدار مبكر. قد تتغير واجهات البرمجة في الاصدارات المستقبلية.
</Warning>
الـ Checkpointing يحفظ لقطة من حالة التنفيذ أثناء التشغيل بحيث يمكن لطاقم أو تدفق أو وكيل الاستئناف بعد الفشل أو التفرع إلى فرع بديل.
## نظرة عامة
<CardGroup cols={2}>
<Card title="الشرح" icon="lightbulb" href="#الشرح">
كيف يعمل الـ Checkpointing: الأحداث والتخزين والوراثة.
</Card>
<Card title="درس تطبيقي" icon="graduation-cap" href="#درس-تطبيقي-استئناف-طاقم-فاشل">
دليل 5 دقائق: تشغيل، إيقاف، استئناف.
</Card>
<Card title="ادلة عملية" icon="screwdriver-wrench" href="#ادلة-عملية">
وصفات مركزة على المهام لسير العمل الشائع.
</Card>
<Card title="المرجع" icon="book" href="#المرجع">
`CheckpointConfig` والأحداث والمزودات وسطر الأوامر.
</Card>
</CardGroup>
يقوم الـ Checkpointing بحفظ حالة التنفيذ تلقائيا اثناء التشغيل. اذا فشل طاقم او تدفق او وكيل اثناء التنفيذ، يمكنك الاستعادة من اخر نقطة حفظ والاستئناف دون اعادة تنفيذ العمل المكتمل.
## الشرح
## البداية السريعة
### ما هي نقطة الحفظ
```python
from crewai import Crew, CheckpointConfig
تلتقط نقطة الحفظ كل ما يحتاجه CrewAI لإعادة إنشاء تشغيل أثناء سيره: الحالة الكاملة للطاقم أو التدفق أو الوكيل — التكوين، وذاكرة الوكلاء ومصادر المعرفة، وتقدم المهام، والمخرجات الوسيطة، والحالة الداخلية والسمات — إلى جانب مدخلات الـ kickoff، وسجل الأحداث حتى تلك النقطة، ومعرف نسب يربط نقطة الحفظ بالتشغيل الذي جاءت منه.
crew = Crew(
agents=[...],
tasks=[...],
checkpoint=True, # يستخدم الافتراضيات: ./.checkpoints, عند task_completed
)
result = crew.kickoff()
```
الاستعادة تعيد بناء تلك الحالة وتستمر. تتخطى المهام المكتملة، وتعاد ترطيب الذاكرة والمعرفة، ويعمل العمل التابع على نفس المخرجات التي أنتجها التشغيل الأصلي. التفرع يجري نفس الاستعادة تحت نسب جديد، بحيث يكتب الفرع الجديد والتشغيل الأصلي نقاط الحفظ جنبا إلى جنب دون أن يطمس أحدهما الآخر.
تتم كتابة ملفات نقاط الحفظ في `./.checkpoints/` بعد اكتمال كل مهمة.
### متى تكتب نقاط الحفظ
## التكوين
الـ Checkpointing مدفوع بالأحداث. يشترك وقت التشغيل في الأحداث التي تحددها عبر `on_events` ويكتب نقطة حفظ عند إطلاق أحدها. الافتراضي `task_completed` ينتج نقطة حفظ لكل مهمة منتهية — توازن معقول بين الدقة واستخدام القرص. الأحداث عالية التردد مثل `llm_call_completed` متاحة للاستعادة الدقيقة لكنها تكتب ملفات أكثر بكثير.
استخدم `CheckpointConfig` للتحكم الكامل:
### التخزين
```python
from crewai import Crew, CheckpointConfig
يتضمن CrewAI مزودين:
crew = Crew(
agents=[...],
tasks=[...],
checkpoint=CheckpointConfig(
location="./my_checkpoints",
on_events=["task_completed", "crew_kickoff_completed"],
max_checkpoints=5,
),
)
```
- `JsonProvider` يكتب ملفا لكل نقطة حفظ. قابل للقراءة وسهل التفقد.
- `SqliteProvider` يكتب إلى قاعدة بيانات SQLite واحدة. أفضل لنقاط الحفظ عالية التردد.
### حقول CheckpointConfig
كلاهما يحذف أقدم نقاط الحفظ عند تحديد `max_checkpoints`.
| الحقل | النوع | الافتراضي | الوصف |
|:------|:------|:----------|:------|
| `location` | `str` | `"./.checkpoints"` | مسار ملفات نقاط الحفظ |
| `on_events` | `list[str]` | `["task_completed"]` | انواع الاحداث التي تطلق نقطة حفظ |
| `provider` | `BaseProvider` | `JsonProvider()` | واجهة التخزين |
| `max_checkpoints` | `int \| None` | `None` | الحد الاقصى للملفات؛ يتم حذف الاقدم اولا |
<Note>
كتابة نقاط الحفظ بأفضل جهد. فشل نقطة حفظ يسجل لكنه لا يقاطع التشغيل.
</Note>
### الوراثة والانسحاب
### نموذج الوراثة
يقبل حقل `checkpoint` في Crew و Flow و Agent قيم `CheckpointConfig` او `True` او `False` او `None`:
`Crew` و`Flow` و`Agent` كلها تقبل وسيط `checkpoint`. يرث الأبناء من الأب ما لم يحددوا قيمتهم الخاصة أو يمرروا `False` للانسحاب. فعل الـ Checkpointing مرة واحدة على الطاقم وتشارك كل الوكلاء، أو استبعد وكيلا واحدا بشكل انتقائي.
| القيمة | السلوك |
|:-------|:-------|
| `None` (افتراضي) | يرث من الاصل. الوكيل يرث اعدادات الطاقم. |
| `True` | تفعيل بالاعدادات الافتراضية. |
| `False` | انسحاب صريح. يوقف الوراثة من الاصل. |
| `CheckpointConfig(...)` | اعدادات مخصصة. |
## درس تطبيقي: استئناف طاقم فاشل
```python
crew = Crew(
agents=[
Agent(role="Researcher", ...), # يرث checkpoint من الطاقم
Agent(role="Writer", ..., checkpoint=False), # منسحب، بدون نقاط حفظ
],
tasks=[...],
checkpoint=True,
)
```
هذا الدليل يستغرق حوالي 5 دقائق. ستشغل طاقما بمهمتين، توقفه في المنتصف، ثم تستأنف من نقطة الحفظ المحفوظة.
## الاستئناف من نقطة حفظ
<Steps>
<Step title="أنشئ الطاقم مع تفعيل الـ Checkpointing">
```python
from crewai import Agent, Crew, Task
```python
# استعادة واستئناف
crew = Crew.from_checkpoint("./my_checkpoints/20260407T120000_abc123.json")
result = crew.kickoff() # يستأنف من اخر مهمة مكتملة
```
researcher = Agent(role="Researcher", goal="Research", backstory="Expert")
writer = Agent(role="Writer", goal="Write", backstory="Expert")
يتخطى الطاقم المستعاد المهام المكتملة ويستأنف من اول مهمة غير مكتملة.
crew = Crew(
agents=[researcher, writer],
tasks=[
Task(description="Research AI trends", agent=researcher, expected_output="bullets"),
Task(description="Write a summary", agent=writer, expected_output="paragraph"),
],
checkpoint=True,
)
```
</Step>
<Step title="شغله وأوقفه بعد المهمة الأولى">
```python
result = crew.kickoff()
```
## يعمل على Crew و Flow و Agent
اضغط `Ctrl+C` بعد انتهاء المهمة الأولى. في `./.checkpoints/`، الملف بصيغة `<timestamp>_<uuid>.json` هو نقطة الحفظ.
</Step>
<Step title="استأنف من نقطة الحفظ">
```python
from crewai import CheckpointConfig
### Crew
result = crew.kickoff(
from_checkpoint=CheckpointConfig(
restore_from="./.checkpoints/<timestamp>_<uuid>.json",
),
)
```
```python
crew = Crew(
agents=[researcher, writer],
tasks=[research_task, write_task, review_task],
checkpoint=CheckpointConfig(location="./crew_cp"),
)
```
يتم تخطي مهمة البحث، ويعمل الكاتب على مخرجات البحث المحفوظة، وينتهي الطاقم.
</Step>
</Steps>
المشغل الافتراضي: `task_completed` (نقطة حفظ واحدة لكل مهمة مكتملة).
## ادلة عملية
### Flow
<AccordionGroup>
<Accordion title="تفعيل الـ Checkpointing بالإعدادات الافتراضية" icon="play">
```python
crew = Crew(agents=[...], tasks=[...], checkpoint=True)
```
```python
from crewai.flow.flow import Flow, start, listen
from crewai import CheckpointConfig
يكتب إلى `./.checkpoints/` عند كل `task_completed`.
</Accordion>
class MyFlow(Flow):
@start()
def step_one(self):
return "data"
<Accordion title="تخصيص التخزين والتردد" icon="sliders">
```python
from crewai import Crew, CheckpointConfig
@listen(step_one)
def step_two(self, data):
return process(data)
crew = Crew(
agents=[...],
tasks=[...],
checkpoint=CheckpointConfig(
location="./my_checkpoints",
on_events=["task_completed", "crew_kickoff_completed"],
max_checkpoints=5,
),
)
```
</Accordion>
flow = MyFlow(
checkpoint=CheckpointConfig(
location="./flow_cp",
on_events=["method_execution_finished"],
),
)
result = flow.kickoff()
<Accordion title="اختيار مزود التخزين" icon="database">
<CodeGroup>
```python JsonProvider
from crewai import Crew, CheckpointConfig
from crewai.state import JsonProvider
# استئناف
flow = MyFlow.from_checkpoint("./flow_cp/20260407T120000_abc123.json")
result = flow.kickoff()
```
crew = Crew(
agents=[...],
tasks=[...],
checkpoint=CheckpointConfig(
location="./my_checkpoints",
provider=JsonProvider(),
max_checkpoints=5,
),
)
```
```python SqliteProvider
from crewai import Crew, CheckpointConfig
from crewai.state import SqliteProvider
### Agent
crew = Crew(
agents=[...],
tasks=[...],
checkpoint=CheckpointConfig(
location="./.checkpoints.db",
provider=SqliteProvider(),
max_checkpoints=50,
),
)
```
</CodeGroup>
```python
agent = Agent(
role="Researcher",
goal="Research topics",
backstory="Expert researcher",
checkpoint=CheckpointConfig(
location="./agent_cp",
on_events=["lite_agent_execution_completed"],
),
)
result = agent.kickoff(messages=[{"role": "user", "content": "Research AI trends"}])
```
<Tip>
SQLite يفعل وضع journal WAL للقراءات المتزامنة. يفضل لنقاط الحفظ عالية التردد.
</Tip>
</Accordion>
## مزودات التخزين
<Accordion title="استبعاد وكيل واحد" icon="user-slash">
```python
crew = Crew(
agents=[
Agent(role="Researcher", ...),
Agent(role="Writer", ..., checkpoint=False),
],
tasks=[...],
checkpoint=True,
)
```
</Accordion>
يتضمن CrewAI مزودي تخزين لنقاط الحفظ.
<Accordion title="التفرع إلى فرع جديد" icon="code-branch">
`fork()` يستعيد نقطة حفظ تحت نسب جديد بحيث لا يتصادم التشغيل الجديد مع الأصلي.
### JsonProvider (افتراضي)
```python
config = CheckpointConfig(restore_from="./my_checkpoints/<file>.json")
crew = Crew.fork(config, branch="experiment-a")
result = crew.kickoff(inputs={"strategy": "aggressive"})
```
يكتب كل نقطة حفظ كملف JSON منفصل.
تسمية `branch` اختيارية؛ يتم إنشاء واحدة إذا أغفلت.
</Accordion>
```python
from crewai import Crew, CheckpointConfig
from crewai.state import JsonProvider
<Accordion title="Checkpointing لـ Crew أو Flow أو Agent" icon="cubes">
<Tabs>
<Tab title="Crew">
```python
crew = Crew(
agents=[researcher, writer],
tasks=[research_task, write_task, review_task],
checkpoint=CheckpointConfig(location="./crew_cp"),
)
```
crew = Crew(
agents=[...],
tasks=[...],
checkpoint=CheckpointConfig(
location="./my_checkpoints",
provider=JsonProvider(),
max_checkpoints=5,
),
)
```
المشغل الافتراضي: `task_completed`.
</Tab>
<Tab title="Flow">
```python
from crewai.flow.flow import Flow, start, listen
from crewai import CheckpointConfig
### SqliteProvider
class MyFlow(Flow):
@start()
def step_one(self):
return "data"
يخزن جميع نقاط الحفظ في ملف قاعدة بيانات SQLite واحد.
@listen(step_one)
def step_two(self, data):
return process(data)
```python
from crewai import Crew, CheckpointConfig
from crewai.state import SqliteProvider
flow = MyFlow(
checkpoint=CheckpointConfig(
location="./flow_cp",
on_events=["method_execution_finished"],
),
)
result = flow.kickoff()
```
</Tab>
<Tab title="Agent">
```python
agent = Agent(
role="Researcher",
goal="Research topics",
backstory="Expert researcher",
checkpoint=CheckpointConfig(
location="./agent_cp",
on_events=["lite_agent_execution_completed"],
),
)
result = agent.kickoff(messages=[{"role": "user", "content": "Research AI trends"}])
```
</Tab>
</Tabs>
</Accordion>
crew = Crew(
agents=[...],
tasks=[...],
checkpoint=CheckpointConfig(
location="./.checkpoints.db",
provider=SqliteProvider(),
),
)
```
<Accordion title="كتابة نقطة حفظ يدويا" icon="code">
سجل معالجا على أي حدث واستدع `state.checkpoint()`.
<CodeGroup>
```python Sync
from __future__ import annotations
from typing import TYPE_CHECKING, Any
from crewai.events.event_bus import crewai_event_bus
from crewai.events.types.llm_events import LLMCallCompletedEvent
if TYPE_CHECKING:
from crewai.state.runtime import RuntimeState
## انواع الاحداث
@crewai_event_bus.on(LLMCallCompletedEvent)
def on_llm_done(source: Any, event: LLMCallCompletedEvent, state: RuntimeState) -> None:
path = state.checkpoint("./my_checkpoints")
print(f"تم حفظ نقطة الحفظ: {path}")
```
```python Async
from __future__ import annotations
يقبل حقل `on_events` اي مجموعة من سلاسل انواع الاحداث. الخيارات الشائعة:
from typing import TYPE_CHECKING, Any
| حالة الاستخدام | الاحداث |
|:---------------|:--------|
| بعد كل مهمة (Crew) | `["task_completed"]` |
| بعد كل طريقة في التدفق | `["method_execution_finished"]` |
| بعد تنفيذ الوكيل | `["agent_execution_completed"]`, `["lite_agent_execution_completed"]` |
| عند اكتمال الطاقم فقط | `["crew_kickoff_completed"]` |
| بعد كل استدعاء LLM | `["llm_call_completed"]` |
| على كل شيء | `["*"]` |
from crewai.events.event_bus import crewai_event_bus
from crewai.events.types.llm_events import LLMCallCompletedEvent
if TYPE_CHECKING:
from crewai.state.runtime import RuntimeState
@crewai_event_bus.on(LLMCallCompletedEvent)
async def on_llm_done_async(source: Any, event: LLMCallCompletedEvent, state: RuntimeState) -> None:
path = await state.acheckpoint("./my_checkpoints")
print(f"تم حفظ نقطة الحفظ: {path}")
```
</CodeGroup>
يتم تمرير وسيط `state` تلقائيا عندما يقبل المعالج ثلاثة معاملات. راجع [Event Listeners](/ar/concepts/event-listener) لقائمة الأحداث الكاملة.
</Accordion>
<Accordion title="التصفح والاستئناف والتفرع من سطر الأوامر" icon="terminal">
```bash
crewai checkpoint
crewai checkpoint --location ./my_checkpoints
crewai checkpoint --location ./.checkpoints.db
```
<Frame caption="شجرة نقاط الحفظ — الفروع والتفرعات تتداخل تحت أبيها.">
<img src="/images/checkpoint-tui-tree.png" alt="Checkpoint TUI tree view" />
</Frame>
اللوحة اليسرى تجمع نقاط الحفظ حسب الفرع؛ التفرعات تتداخل تحت أبيها. اختيار نقطة حفظ يفتح لوحة التفاصيل مع بياناتها الوصفية وحالة الكيان وتقدم المهام. **Resume** يكمل التشغيل؛ **Fork** يبدأ فرعا جديدا.
<Frame caption="تبويب النظرة العامة — البيانات الوصفية وحالة الكيان وملخص التشغيل.">
<img src="/images/checkpoint-tui-detail-overview.png" alt="Checkpoint detail overview tab" />
</Frame>
لوحة التفاصيل تعرض منطقتين قابلتين للتحرير:
- **Inputs** — مدخلات الـ kickoff الأصلية، معبأة مسبقا وقابلة للتحرير.
<Frame>
<img src="/images/checkpoint-tui-detail-inputs.png" alt="Editable kickoff inputs" />
</Frame>
- **مخرجات المهام** — مخرجات المهام المكتملة. تحرير مخرج والضغط على **Fork** يبطل المهام التابعة لتعاد بالسياق المعدل.
<Frame>
<img src="/images/checkpoint-tui-detail-tasks.png" alt="Editable task outputs" />
</Frame>
<Frame caption="عرض التفرع — تأكيد فرع جديد من نقطة الحفظ المختارة.">
<img src="/images/checkpoint-tui-details-fork.png" alt="Fork confirmation panel" />
</Frame>
<Tip>
مفيد لاستكشاف "ماذا لو": تفرع، عدل، راقب.
</Tip>
</Accordion>
<Accordion title="تفقد نقاط الحفظ بدون TUI" icon="magnifying-glass">
```bash
crewai checkpoint list ./my_checkpoints
crewai checkpoint info ./my_checkpoints/<file>.json
crewai checkpoint info ./.checkpoints.db
```
</Accordion>
</AccordionGroup>
## المرجع
### `CheckpointConfig`
<ParamField path="location" type="str" default='"./.checkpoints"'>
وجهة التخزين. مجلد لـ `JsonProvider`، مسار ملف قاعدة بيانات لـ `SqliteProvider`.
</ParamField>
<ParamField path="on_events" type='list[CheckpointEventType | Literal["*"]]' default='["task_completed"]'>
أنواع الأحداث التي تطلق نقطة حفظ. `CheckpointEventType` هو `Literal` — مدقق الأنواع يكمل تلقائيا ويرفض القيم غير المدعومة. راجع [أنواع الأحداث](#أنواع-الأحداث) للقائمة الكاملة.
</ParamField>
<ParamField path="provider" type="BaseProvider" default="JsonProvider()">
واجهة التخزين. `JsonProvider` أو `SqliteProvider`.
</ParamField>
<ParamField path="max_checkpoints" type="int | None" default="None">
الحد الاقصى لنقاط الحفظ المحتفظ بها. الأقدم تحذف بعد كل كتابة.
</ParamField>
<ParamField path="restore_from" type="Path | str | None" default="None">
نقطة الحفظ المراد استعادتها عند تمريرها عبر `from_checkpoint`.
</ParamField>
### قيم حقل `checkpoint`
مقبولة في `Crew` و`Flow` و`Agent`.
<ParamField path="None" type="افتراضي">
يرث من الأب.
</ParamField>
<ParamField path="True" type="bool">
تفعيل بالإعدادات الافتراضية.
</ParamField>
<ParamField path="False" type="bool">
انسحاب صريح. يوقف الوراثة.
</ParamField>
<ParamField path="CheckpointConfig(...)" type="CheckpointConfig">
إعدادات مخصصة.
</ParamField>
### أنواع الأحداث
يقبل `on_events` أي مجموعة من قيم `CheckpointEventType`. الافتراضي `["task_completed"]` يكتب نقطة حفظ لكل مهمة منتهية، و`["*"]` يطابق جميع الأحداث.
<Warning>
استخدام `["*"]` او احداث عالية التردد مثل `llm_call_completed` سيكتب العديد من ملفات نقاط الحفظ وقد يؤثر على الاداء. استخدم `max_checkpoints` للحد من استخدام المساحة.
`["*"]` والأحداث عالية التردد مثل `llm_call_completed` تكتب نقاط حفظ كثيرة وقد تضر بالاداء. استخدمها مع `max_checkpoints`.
</Warning>
## نقاط الحفظ اليدوية
<Expandable title="جميع الأحداث المدعومة">
للتحكم الكامل، سجل معالج الاحداث الخاص بك واستدع `state.checkpoint()` مباشرة:
- **Task** — `task_started`, `task_completed`, `task_failed`, `task_evaluation`
- **Crew** — `crew_kickoff_started`, `crew_kickoff_completed`, `crew_kickoff_failed`, `crew_train_started`, `crew_train_completed`, `crew_train_failed`, `crew_test_started`, `crew_test_completed`, `crew_test_failed`, `crew_test_result`
- **Agent** — `agent_execution_started`, `agent_execution_completed`, `agent_execution_error`, `lite_agent_execution_started`, `lite_agent_execution_completed`, `lite_agent_execution_error`, `agent_evaluation_started`, `agent_evaluation_completed`, `agent_evaluation_failed`
- **Flow** — `flow_created`, `flow_started`, `flow_finished`, `flow_paused`, `method_execution_started`, `method_execution_finished`, `method_execution_failed`, `method_execution_paused`, `human_feedback_requested`, `human_feedback_received`, `flow_input_requested`, `flow_input_received`
- **LLM** — `llm_call_started`, `llm_call_completed`, `llm_call_failed`, `llm_stream_chunk`, `llm_thinking_chunk`
- **LLM Guardrail** — `llm_guardrail_started`, `llm_guardrail_completed`, `llm_guardrail_failed`
- **Tool** — `tool_usage_started`, `tool_usage_finished`, `tool_usage_error`, `tool_validate_input_error`, `tool_selection_error`, `tool_execution_error`
- **Memory** — `memory_save_started`, `memory_save_completed`, `memory_save_failed`, `memory_query_started`, `memory_query_completed`, `memory_query_failed`, `memory_retrieval_started`, `memory_retrieval_completed`, `memory_retrieval_failed`
- **Knowledge** — `knowledge_search_query_started`, `knowledge_search_query_completed`, `knowledge_query_started`, `knowledge_query_completed`, `knowledge_query_failed`, `knowledge_search_query_failed`
- **Reasoning** — `agent_reasoning_started`, `agent_reasoning_completed`, `agent_reasoning_failed`
- **MCP** — `mcp_connection_started`, `mcp_connection_completed`, `mcp_connection_failed`, `mcp_tool_execution_started`, `mcp_tool_execution_completed`, `mcp_tool_execution_failed`, `mcp_config_fetch_failed`
- **Observation** — `step_observation_started`, `step_observation_completed`, `step_observation_failed`, `plan_refinement`, `plan_replan_triggered`, `goal_achieved_early`
- **Skill** — `skill_discovery_started`, `skill_discovery_completed`, `skill_loaded`, `skill_activated`, `skill_load_failed`
- **Logging** — `agent_logs_started`, `agent_logs_execution`
- **A2A** — `a2a_delegation_started`, `a2a_delegation_completed`, `a2a_conversation_started`, `a2a_conversation_completed`, `a2a_message_sent`, `a2a_response_received`, `a2a_polling_started`, `a2a_polling_status`, `a2a_push_notification_registered`, `a2a_push_notification_received`, `a2a_push_notification_sent`, `a2a_push_notification_timeout`, `a2a_streaming_started`, `a2a_streaming_chunk`, `a2a_agent_card_fetched`, `a2a_authentication_failed`, `a2a_artifact_received`, `a2a_connection_error`, `a2a_server_task_started`, `a2a_server_task_completed`, `a2a_server_task_canceled`, `a2a_server_task_failed`, `a2a_parallel_delegation_started`, `a2a_parallel_delegation_completed`, `a2a_transport_negotiated`, `a2a_content_type_negotiated`, `a2a_context_created`, `a2a_context_expired`, `a2a_context_idle`, `a2a_context_completed`, `a2a_context_pruned`
- **إشارات النظام** — `SIGTERM`, `SIGINT`, `SIGHUP`, `SIGTSTP`, `SIGCONT`
- **حرف بدل** — `"*"` يطابق جميع الأحداث.
```python
from crewai.events.event_bus import crewai_event_bus
from crewai.events.types.llm_events import LLMCallCompletedEvent
</Expandable>
# معالج متزامن
@crewai_event_bus.on(LLMCallCompletedEvent)
def on_llm_done(source, event, state):
path = state.checkpoint("./my_checkpoints")
print(f"تم حفظ نقطة الحفظ: {path}")
### مزودات التخزين
# معالج غير متزامن
@crewai_event_bus.on(LLMCallCompletedEvent)
async def on_llm_done_async(source, event, state):
path = await state.acheckpoint("./my_checkpoints")
print(f"تم حفظ نقطة الحفظ: {path}")
```
<ParamField path="JsonProvider" type="provider">
ملف واحد لكل نقطة حفظ بصيغة `<timestamp>_<uuid>.json` داخل `location`.
</ParamField>
وسيط `state` هو `RuntimeState` الذي يتم تمريره تلقائيا بواسطة ناقل الاحداث عندما يقبل المعالج 3 معاملات. يمكنك تسجيل معالجات على اي نوع حدث مدرج في وثائق [Event Listeners](/ar/concepts/event-listener).
<ParamField path="SqliteProvider" type="provider">
ملف قاعدة بيانات واحد في `location` مع journaling WAL.
</ParamField>
الـ Checkpointing يعمل بافضل جهد: اذا فشلت كتابة نقطة حفظ، يتم تسجيل الخطأ ولكن التنفيذ يستمر دون انقطاع.
### سطر الأوامر
| الامر | الغرض |
|:------|:------|
| `crewai checkpoint` | تشغيل TUI؛ كشف التخزين تلقائيا. |
| `crewai checkpoint --location <path>` | تشغيل TUI على موقع محدد. |
| `crewai checkpoint list <path>` | سرد نقاط الحفظ. |
| `crewai checkpoint info <path>` | تفقد ملف نقطة حفظ أو آخر مدخل في قاعدة بيانات SQLite. |

View File

@@ -52,6 +52,8 @@ crewai create crew my_new_crew
crewai create flow my_new_flow
```
افتراضيًا، ينشئ `crewai create crew` مشروعًا JSON-first يحتوي على `crew.jsonc` و `agents/*.jsonc`. استخدم `crewai create crew my_new_crew --classic` فقط إذا أردت البنية القديمة Python/YAML مع `crew.py` و `config/agents.yaml` و `config/tasks.yaml`.
### 2. الإصدار
عرض الإصدار المثبت من CrewAI.
@@ -142,7 +144,20 @@ crewai chat
```
<Note>
مهم: عيّن خاصية `chat_llm` في ملف `crew.py` لتفعيل هذا الأمر.
مهم: عيّن خاصية `chat_llm` في تعريف الـ crew لتفعيل هذا الأمر.
للـ crews بنمط JSON-first، أضفها إلى `crew.jsonc`:
```jsonc
{
"name": "My Crew",
"agents": ["researcher"],
"tasks": [],
"chat_llm": "openai/gpt-4o"
}
```
للـ crews الكلاسيكية Python/YAML، عيّنها في `crew.py`:
```python
@crew

View File

@@ -40,11 +40,52 @@ mode: "wide"
## إنشاء الأطقم
هناك طريقتان لإنشاء الأطقم في CrewAI: باستخدام **تهيئة YAML (موصى بها)** أو تعريفها **مباشرة في الكود**.
هناك طريقتان رئيسيتان لإنشاء الأطقم في CrewAI: باستخدام **تهيئة JSONC (الموصى بها للـ crews الجديدة)** أو تعريفها **مباشرة في الكود** للمشاريع الكلاسيكية والحالات المتقدمة.
### تهيئة YAML (موصى بها)
### تهيئة JSONC (موصى بها)
توفر تهيئة YAML طريقة أنظف وأكثر قابلية للصيانة لتعريف الأطقم وتتسق مع كيفية تعريف الوكلاء والمهام في مشاريع CrewAI.
المشاريع الجديدة التي تُنشأ عبر `crewai create crew <name>` تستخدم `crew.jsonc` لإعدادات الـ crew والمهام، وملفًا منفصلًا لكل Agent داخل `agents/`. يكتشف `crewai run` ملف `crew.jsonc` أو `crew.json`، ويحمّل الـ Agents المشار إليها، ويطلب قيم placeholders الناقصة، ثم يبدأ الـ crew.
```jsonc crew.jsonc
{
"name": "Market Research Crew",
"agents": ["researcher", "analyst"],
"tasks": [
{
"name": "research",
"description": "Research {topic} and collect the most relevant facts.",
"expected_output": "Structured research notes about {topic}.",
"agent": "researcher"
},
{
"name": "analysis",
"description": "Analyze the research and write a concise report.",
"expected_output": "A markdown report with findings and recommendations.",
"agent": "analyst",
"context": ["research"],
"output_file": "output/report.md"
}
],
"process": "sequential",
"verbose": true,
"memory": true,
"inputs": {
"topic": "AI Agents"
}
}
```
كل عنصر في `agents` يُحل أولًا إلى `agents/<name>.jsonc` ثم إلى `agents/<name>.json`. للـ crews الهرمية، استخدم `"process": "hierarchical"` مع `manager_llm` أو `manager_agent`.
<Warning>
شغّل مشاريع JSON crew من مصادر تثق بها فقط. أدوات `custom:<name>` ومراجع `{"python": "module.attribute"}` تنفذ كود Python محليًا عند تحميل الـ crew.
</Warning>
### تهيئة YAML الكلاسيكية
المشاريع الكلاسيكية التي تُنشأ عبر `crewai create crew <name> --classic` تستخدم `crew.py` و `config/agents.yaml` و `config/tasks.yaml` والمزيّنات `@CrewBase` و `@agent` و `@task` و `@crew`.
تظل هذه الطريقة مدعومة للمشاريع الحالية المبنية بـ Python/YAML وللفِرق التي تحتاج تحكمًا صريحًا عبر decorators.
```python code
from crewai import Agent, Crew, Task, Process

View File

@@ -226,6 +226,48 @@ counter=2 message='Hello from first_method - updated by second_method'
من خلال ضمان إعادة مخرجات الدالة الأخيرة وتوفير الوصول إلى الحالة، تجعل تدفقات CrewAI من السهل دمج نتائج سير عمل الذكاء الاصطناعي في التطبيقات أو الأنظمة الأكبر،
مع الحفاظ على الوصول إلى الحالة طوال تنفيذ التدفق.
## مقاييس استخدام التدفق
بعد اكتمال تنفيذ التدفق، يمكنك الوصول إلى الخاصية `usage_metrics` لعرض إجمالي استخدام التوكنات عبر **كل استدعاء لنموذج اللغة** يتم خلال التشغيل — بما في ذلك الاستدعاءات من كل فريق (Crew) ينظمه التدفق، والاستدعاءات داخل أدوات الـ Agents، والاستدعاءات المباشرة لـ `LLM.call(...)` من دوال التدفق. هذا هو المكافئ على جانب الـ SDK للإجماليات المعروضة في واجهة CrewAI Enterprise.
```python Code
from crewai import LLM
from crewai.flow.flow import Flow, listen, start
class UsageMetricsFlow(Flow):
@start()
def run_first_crew(self):
self.state.first_result = FirstCrew().crew().kickoff()
@listen(run_first_crew)
def call_llm_directly(self):
# استدعاء مباشر لنموذج اللغة — يُحسب أيضًا ضمن flow.usage_metrics
llm = LLM(model="openai/gpt-4o-mini")
self.state.summary = llm.call("لخّص النقاط الرئيسية.")
@listen(call_llm_directly)
def run_second_crew(self):
self.state.second_result = SecondCrew().crew().kickoff()
flow = UsageMetricsFlow()
flow.kickoff()
print(flow.usage_metrics)
# UsageMetrics(total_tokens=8579, prompt_tokens=6210, completion_tokens=2369,
# cached_prompt_tokens=0, reasoning_tokens=0,
# cache_creation_tokens=0, successful_requests=5)
```
<Note>
`flow.usage_metrics` **ليست** نفس `flow.kickoff().token_usage`. هذه الأخيرة
ترجع فقط `CrewOutput.token_usage` لـ **آخر** دالة `@listen` أعادت
`CrewOutput`، مما يعني أنها تعكس فقط الفريق الأخير وتتجاهل الفرق السابقة
وكذلك أي استدعاءات مباشرة لـ `LLM.call(...)`. استخدم `flow.usage_metrics`
كلما احتجت إلى الإجمالي **الكامل** للتوكنات لتنفيذ التدفق.
</Note>
كل حقل في [`UsageMetrics`](https://github.com/crewAIInc/crewAI/blob/main/lib/crewai/src/crewai/types/usage_metrics.py) المُعاد هو مجموع جميع استدعاءات نموذج اللغة التي حدثت خلال استدعاء واحد لـ `flow.kickoff()`. تتم إعادة تعيين العدادات عند الاستدعاء التالي لـ `kickoff()` (وفي كل تكرار من `kickoff_for_each`)، لذلك لن تتكرر العدّات عبر التشغيلات المتتالية. يمكن قراءة هذه الخاصية بأمان في أي وقت بعد اكتمال `kickoff()`؛ قراءتها أثناء التنفيذ تُرجع المجموع الجزئي المتراكم حتى تلك اللحظة.
## إدارة حالة التدفق
إدارة الحالة بفعالية أمر بالغ الأهمية لبناء سير عمل ذكاء اصطناعي موثوق وقابل للصيانة. توفر تدفقات CrewAI آليات قوية لإدارة الحالة غير المهيكلة والمهيكلة،
@@ -788,7 +830,7 @@ if __name__ == "__main__":
crewai create flow name_of_flow
```
سيولّد هذا الأمر مشروع CrewAI جديد مع هيكل المجلدات اللازم. يتضمن المشروع المولّد فريق Crew مُعد مسبقًا يُسمى `poem_crew` ويعمل بالفعل. يمكنك استخدام هذا الفريق كقالب بنسخه ولصقه وتعديله لإنشاء فرق أخرى.
سيولّد هذا الأمر مشروع CrewAI جديد مع هيكل المجلدات اللازم. يتضمن المشروع المولّد فريق Crew مُعد مسبقًا يُسمى `poem_crew` ويعمل بالفعل. يستخدم الـ embedded crew الابتدائي بنية Python/YAML الكلاسيكية؛ أما crews المستقلة الجديدة التي تُنشأ عبر `crewai create crew` فتستخدم بنية JSON-first.
### هيكل المجلدات
@@ -818,7 +860,29 @@ crewai create flow name_of_flow
- `config/tasks.yaml`: يحدد المهام للفريق.
- `poem_crew.py`: يحتوي على تعريف الفريق، بما في ذلك الـ Agents والمهام والفريق نفسه.
يمكنك نسخ ولصق وتعديل `poem_crew` لإنشاء فرق أخرى.
يمكنك نسخ ولصق وتعديل `poem_crew` لإنشاء crews كلاسيكية مضمّنة أخرى.
للـ crews المضمّنة بنمط JSON-first، استخدم مجلدًا يحتوي على `crew.jsonc` و `agents/*.jsonc`:
```text
crews/
└── research_crew/
├── agents/
│ └── researcher.jsonc
└── crew.jsonc
```
ثم حمّلها من خطوة في Flow:
```python
from pathlib import Path
from crewai.project import load_crew
crew, default_inputs = load_crew(
Path(__file__).parent / "crews" / "research_crew" / "crew.jsonc"
)
result = crew.kickoff(inputs={**default_inputs, "topic": "AI Agents"})
```
### ربط فرق Crew في `main.py`

View File

@@ -107,7 +107,7 @@ mode: "wide"
</Tabs>
<Info>
يوفر CrewAI تكاملات SDK أصلية لـ OpenAI و Anthropic و Google (Gemini API) و Azure و AWS Bedrock -- لا حاجة لتثبيت إضافي بخلاف الملحقات الخاصة بالمزود (مثل `uv add "crewai[openai]"`).
يوفر CrewAI تكاملات SDK أصلية لـ OpenAI و Anthropic و Google (Gemini API) و Azure و AWS Bedrock و Snowflake Cortex -- لا حاجة لتثبيت إضافي بخلاف الملحقات الخاصة بالمزود (مثل `uv add "crewai[openai]"`).
جميع المزودين الآخرين مدعومون بواسطة **LiteLLM**. إذا كنت تخطط لاستخدام أي منهم، أضفه كتبعية لمشروعك:
```bash
@@ -291,6 +291,55 @@ mode: "wide"
```
</Accordion>
<Accordion title="Snowflake Cortex">
يوفر CrewAI تكاملًا أصليًا مع Snowflake Cortex REST API عبر endpoint Chat Completions المتوافق مع OpenAI. تستخدم نماذج `snowflake/...` هذا المسار بدون fallback إلى LiteLLM. يدعم Snowflake Cortex في CrewAI حاليًا Chat Completions فقط، لذلك استخدم وضع `api` الافتراضي ولا تضبط `api="responses"`.
```toml Code
# Required
SNOWFLAKE_PAT=<your-programmatic-access-token>
SNOWFLAKE_ACCOUNT_URL=https://<account-identifier>.snowflakecomputing.com
# Alternative account configuration
SNOWFLAKE_ACCOUNT=<account-identifier>
```
**الاستخدام الأساسي:**
```python Code
from crewai import LLM
llm = LLM(
model="snowflake/openai-gpt-4.1",
temperature=0.7,
max_completion_tokens=1024,
)
```
**نماذج Claude على Cortex:**
```python Code
from crewai import LLM
llm = LLM(
model="snowflake/claude-sonnet-4-5",
max_completion_tokens=1024,
stream=True,
)
```
**متغيرات البيئة المدعومة:**
- `SNOWFLAKE_PAT` أو `SNOWFLAKE_TOKEN` أو `SNOWFLAKE_JWT`: الرمز المستخدم كاعتماد Bearer
- `SNOWFLAKE_ACCOUNT_URL`: عنوان URL الكامل لحساب Snowflake
- `SNOWFLAKE_ACCOUNT` أو `SNOWFLAKE_ACCOUNT_ID` أو `SNOWFLAKE_ACCOUNT_IDENTIFIER`: معرف الحساب المستخدم لبناء URL
تستخدم طلبات Snowflake REST الدور الافتراضي للمستخدم. تأكد من أن هذا الدور لديه `SNOWFLAKE.CORTEX_USER` أو `SNOWFLAKE.CORTEX_REST_API_USER`. لا يتطلب endpoint Cortex REST Chat Completions معاملات database أو schema أو warehouse أو role صريح.
**الميزات:**
- اختيار provider أصلي باستخدام `model="snowflake/<model-name>"`
- Chat Completions مع streaming وبدونه فقط؛ `api="responses"` غير مدعوم
- تتبع استخدام الرموز
- استدعاء الدوال لنماذج OpenAI و Claude المستضافة في Snowflake
- إزالة assistant prefill النهائي غير الصالح تلقائيًا لنماذج Claude في Snowflake
</Accordion>
<Accordion title="Anthropic">
يوفر CrewAI تكاملًا أصليًا مع Anthropic من خلال Anthropic Python SDK.

View File

@@ -16,7 +16,6 @@ mode: "wide"
- **تسلسلي**: ينفذ المهام بالتتابع، مما يضمن إكمال المهام بتقدم منظم.
- **هرمي**: ينظم المهام في تسلسل إداري هرمي، حيث يتم تفويض المهام وتنفيذها بناءً على سلسلة أوامر منظمة. يجب تحديد نموذج لغة المدير (`manager_llm`) أو وكيل مدير مخصص (`manager_agent`) في الطاقم لتفعيل العملية الهرمية، مما يسهّل إنشاء وإدارة المهام من قبل المدير.
- **العملية التوافقية (مخطط لها)**: تهدف إلى اتخاذ القرارات بشكل تعاوني بين الوكلاء حول تنفيذ المهام، وتقدم هذه العملية نهجًا ديمقراطيًا لإدارة المهام داخل CrewAI. وهي مخطط لها للتطوير المستقبلي وغير مطبقة حاليًا في قاعدة الكود.
## دور العمليات في العمل الجماعي
تُمكّن العمليات الوكلاء الأفراد من العمل كوحدة متماسكة، مما يبسّط جهودهم لتحقيق أهداف مشتركة بكفاءة وتناسق.
@@ -59,9 +58,9 @@ crew = Crew(
## فئة Process: نظرة عامة مفصلة
تم تنفيذ فئة `Process` كتعداد (`Enum`)، مما يضمن أمان الأنواع ويقيّد قيم العملية على الأنواع المحددة (`sequential`، `hierarchical`). العملية التوافقية مخطط لإدراجها مستقبلاً، مما يؤكد التزامنا بالتطوير والابتكار المستمر.
تم تنفيذ فئة `Process` كتعداد (`Enum`)، مما يضمن أمان الأنواع ويقيّد قيم العملية على الأنواع المحددة (`sequential`، `hierarchical`).
## الخلاصة
التعاون المنظم الذي تسهّله العمليات داخل CrewAI ضروري لتمكين العمل الجماعي المنهجي بين الوكلاء.
تم تحديث هذه الوثائق لتعكس أحدث الميزات والتحسينات والتكامل المخطط للعملية التوافقية، مما يضمن وصول المستخدمين إلى أحدث المعلومات وأكثرها شمولاً.
تم تحديث هذه الوثائق لتعكس أحدث الميزات والتحسينات، مما يضمن وصول المستخدمين إلى أحدث المعلومات وأكثرها شمولاً.

View File

@@ -73,13 +73,48 @@ crew = Crew(
## إنشاء المهام
هناك طريقتان لإنشاء المهام في CrewAI: باستخدام **إعداد YAML (موصى به)** أو تعريفها **مباشرة في الكود**.
هناك طريقتان شائعتان لإنشاء المهام في CrewAI: باستخدام **تهيئة JSONC (الموصى بها للـ crews الجديدة)** أو تعريفها **مباشرة في الكود**.
### إعداد YAML (موصى به)
### تهيئة JSONC (موصى بها)
يوفر استخدام إعداد YAML طريقة أنظف وأكثر قابلية للصيانة لتعريف المهام. نوصي بشدة باستخدام هذا النهج لتعريف المهام في مشاريع CrewAI.
المشاريع الجديدة التي تُنشأ عبر `crewai create crew <name>` تعرّف المهام في `crew.jsonc`.
بعد إنشاء مشروع CrewAI كما هو موضح في قسم [التثبيت](/ar/installation)، انتقل إلى ملف `src/latest_ai_development/config/tasks.yaml` وعدّل القالب ليتوافق مع متطلبات مهامك المحددة.
````jsonc crew.jsonc
{
"name": "Research Crew",
"agents": ["researcher", "reporting_analyst"],
"tasks": [
{
"name": "research_task",
"description": "Conduct thorough research about {topic}.",
"expected_output": "A list of the most relevant information about {topic}.",
"agent": "researcher"
},
{
"name": "reporting_task",
"description": "Review the research and expand it into a detailed report.",
"expected_output": "A polished markdown report.",
"agent": "reporting_analyst",
"context": ["research_task"],
"markdown": true,
"output_file": "report.md"
}
],
"inputs": {
"topic": "AI Agents"
}
}
````
كل مهمة تحتاج إلى `description` و `expected_output`. يجب أن يطابق `agent` اسم Agent مذكورًا في `agents`. يشير `context` إلى أسماء مهام سابقة فقط؛ وترفض الإشارات إلى مهام لاحقة.
### إعداد YAML الكلاسيكي
المشاريع الكلاسيكية التي تُنشأ عبر `crewai create crew <name> --classic` تستخدم `config/tasks.yaml` وفئة `@CrewBase` في `crew.py`.
يظل إعداد YAML مدعومًا للمشاريع الحالية المبنية بـ Python/YAML وللفِرق التي تفضل تعريف المهام من خلال فئة `@CrewBase`.
بعد إنشاء مشروع كلاسيكي، انتقل إلى ملف `src/<project_name>/config/tasks.yaml` وعدّل القالب ليتوافق مع متطلبات مهامك المحددة.
<Note>
المتغيرات في ملفات YAML (مثل `{topic}`) سيتم استبدالها بالقيم من مدخلاتك عند تشغيل الفريق:
@@ -115,7 +150,7 @@ reporting_task:
لاستخدام إعداد YAML هذا في كودك، أنشئ فئة فريق ترث من `CrewBase`:
```python crew.py
# src/latest_ai_development/crew.py
# src/<project_name>/crew.py
from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task

View File

@@ -0,0 +1,112 @@
---
title: "راقب أتمتاتك"
description: "راقب صحة الأسطول واستهلاك LLM وسلوك كل أتمتة من تبويب Automations."
sidebarTitle: "المراقبة"
icon: "gauge"
mode: "wide"
---
<Info>
**تنقل وثائق ACP (إصدار تجريبي)**
- [نظرة عامة](/ar/enterprise/features/agent-control-plane/overview)
- **المراقبة** *(أنت هنا)*
- [القواعد](/ar/enterprise/features/agent-control-plane/rules)
</Info>
## نظرة عامة
تبويب **Automations** هو عرض العمليات للقراءة فقط في [Agent Control Plane](/ar/enterprise/features/agent-control-plane/overview). يجمع بين بطاقتَي مقاييس و sankey تفاعلي وجدولين فرعيين — **Automations** و **Consumption** — يمكنك البحث والتصفية والفرز فيهما.
<Frame>
![نظرة عامة على Agent Control Plane](/images/enterprise/acp-overview-automations-sankey.png)
</Frame>
تحترم جميع المخططات والجداول مُحدّد **آخر 24 ساعة / الأسبوع الماضي / آخر 30 يوماً** في أعلى اليمين. تقارن قيم الفرق النافذة المختارة بالنافذة السابقة بنفس الطول.
<Note>
تعرض الصفوف بيانات فقط لعمليات النشر على **crewAI v1.13 أو أحدث** — تظهر عمليات النشر الأقدم في لافتة *"We've detected N other automations that we can't display"* أسفل sankey ولا تساهم بأي مقاييس حتى يتم تحديثها وإعادة نشرها. راجع [نظرة عامة — المتطلبات](/ar/enterprise/features/agent-control-plane/overview#المتطلبات).
</Note>
## لوحة المعلومات
يحتوي رأس الصفحة على بطاقتَي مقاييس و sankey تفاعلي. النقر على أي من البطاقتين يبدّل sankey بين وضعَين:
- **وضع الصحة** — `إجمالي الأتمتات → حِزم الحالة (Critical / Warning / Healthy)`. انقر على حِزمة لتصفية جدول Automations إلى عمليات النشر تلك فقط.
- **وضع الاستهلاك** — `مزودو النماذج → الأتمتات → التكلفة الإجمالية`. انقر على مزود لتصفية جدول Consumption إلى ذلك المزود.
| البطاقة | ما تعرضه |
|------|---------------|
| **Automations** | الأتمتات `active` (والعدد الإجمالي)، إجمالي `errors` في النافذة، `active executions` الحالية (والإجمالي في النافذة)، مع الفرق مقابل الفترة السابقة. |
| **Consumption** | إجمالي `cost` و `tokens used`، مع فرق التكلفة مقابل الفترة السابقة. |
<Frame>
![نظرة عامة مع sankey الاستهلاك](/images/enterprise/acp-overview-consumption-sankey.png)
</Frame>
## جدول Automations
التبويب الفرعي **Automations** هو تفصيل صحة الأسطول لكل deployment. كل صف هو crew أو flow منشور.
<Frame>
![جدول الأتمتات مع تفصيل حالة الصحة](/images/enterprise/acp-automations-table.png)
</Frame>
| العمود | ما يعرضه |
|--------|---------------|
| **Automation** | اسم الـ deployment وأي وسوم مُسنَدة إليه (مثل `production`، `financial`). |
| **Last execution** | الوقت المنقضي منذ آخر تنفيذ. |
| **Health Status Breakdown** | شريط مكدّس بنسب `Critical` / `Warning` / `Healthy` لعمليات التنفيذ في النافذة. |
| **Executions with Errors** | إجمالي عمليات التنفيذ الفاشلة في النافذة. |
| **PII detection applied** | `Yes` إذا كان هناك تكوين PII لكل deployment أو [قاعدة PII](/ar/enterprise/features/agent-control-plane/rules) مطابِقة نشطة. |
| **Executions** | إجمالي عمليات التنفيذ في النافذة. |
| **Last updated** | متى أُعيد نشر الـ deployment آخر مرة. |
| **Crew Version** | إصدار `crewai` الذي يُبلِّغ عنه الـ deployment. يشير أيقونة المعلومات بجانب الإصدارات الأقل من `1.13` إلى صفوف لا يمكنها المساهمة بالمقاييس. |
ابحث بالاسم، صفِّ حسب `Status` (`Healthy` / `Warning` / `Critical`)، وافرز بأي رأس عمود. انقر على اسم الـ deployment لفتح **لوحة الأتمتة**.
## جدول Consumption
التبويب الفرعي **Consumption** هو تفصيل إنفاق LLM واستخدام الرموز لكل deployment.
<Frame>
![جدول الاستهلاك مُفصَّل حسب مزود LLM](/images/enterprise/acp-consumption-table.png)
</Frame>
| العمود | ما يعرضه |
|--------|---------------|
| **Automation** | اسم الـ deployment. |
| **Last execution** | الوقت المنقضي منذ آخر تنفيذ. |
| **Tokens used** | صف واحد لكل مزود LLM تستخدمه هذه الأتمتة، مع الفرق مقابل الفترة السابقة. |
| **Cost** | التكلفة لكل مزود LLM، مع الفرق مقابل الفترة السابقة. |
| **Total cost** | المجموع عبر جميع المزودين، مع الفرق. |
| **Executions** | إجمالي عمليات التنفيذ في النافذة. |
| **Last updated** | متى أُعيد نشر الـ deployment آخر مرة. |
| **Crew Version** | إصدار `crewai` الذي يُبلِّغ عنه الـ deployment. |
صفِّ حسب **LLM provider** وافرز حسب `Cost` أو `Executions` أو `Last run`.
<Info>
**عادة ما تعني الخلايا الفارغة (`—` أو `$0.00`) أن الـ deployment أدنى من crewAI v1.13.** في اللقطة أعلاه، تظهر *Automation F* (`1.7.0`) و *Automation I* (`1.12.2`) فارغة في الرموز والتكلفة — لا تزال عمليات التنفيذ تعمل، لكنها لا تُصدِر التليمتري على مستوى المزود الذي يُغذِّي هذا الجدول. حدّث هذه الـ crews وأعد نشرها لبدء جمع بيانات الاستهلاك.
</Info>
## ذو صلة
<CardGroup cols={2}>
<Card title="Agent Control Plane — نظرة عامة" icon="book-open" href="/ar/enterprise/features/agent-control-plane/overview">
ما هو ACP، المتطلبات، مستويات الخطط، و RBAC.
</Card>
<Card title="Agent Control Plane — القواعد" icon="shield-check" href="/ar/enterprise/features/agent-control-plane/rules">
طبّق قواعد PII Redaction على مستوى المؤسسة عبر العديد من الأتمتات.
</Card>
<Card title="Traces" icon="timeline" href="/ar/enterprise/features/traces">
تعمّق في تنفيذ واحد لرؤية تفكير الوكيل واستدعاءات الأدوات واستخدام الرموز.
</Card>
<Card title="النشر إلى AMP" icon="rocket" href="/ar/enterprise/guides/deploy-to-amp">
انشر crew على إصدار crewAI يدعم Agent Control Plane.
</Card>
</CardGroup>
<Card title="تحتاج مساعدة؟" icon="headset" href="mailto:support@crewai.com">
تواصل مع فريق الدعم للمساعدة في تفسير المقاييس داخل Agent Control Plane.
</Card>

View File

@@ -0,0 +1,82 @@
---
title: نظرة عامة على Agent Control Plane
description: "مركز عمليات موحّد للأتمتات الجارية — صحة الأسطول واستهلاك LLM والسياسات على مستوى المؤسسة في مكان واحد."
sidebarTitle: نظرة عامة
icon: "book-open"
---
<Info>
**تنقل وثائق ACP (إصدار تجريبي)**
- **نظرة عامة** *(أنت هنا)*
- [المراقبة](/ar/enterprise/features/agent-control-plane/monitoring)
- [القواعد](/ar/enterprise/features/agent-control-plane/rules)
</Info>
## نظرة عامة
**Agent Control Plane** (ACP) هو مركز العمليات لكل ما يعمل لديك على CrewAI AMP. إنها شاشة واحدة — مقسّمة إلى تبويبَي **Automations** و **Rules** — تمنح فريقك القدرة على:
- مراقبة **حالة (الصحة)** كل أتمتة حيّة (crew أو flow) بتفصيل `Critical` / `Warning` / `Healthy` وعدد عمليات التنفيذ.
- تتبع **استهلاك LLM** — الرموز (tokens) والتكلفة — لكل أتمتة ولكل مزود ولكل نموذج، مع الفرق مقابل الفترة السابقة.
- التعمّق في أي أتمتة منفردة أو مزود نماذج لرؤية المخططات الزمنية وتفصيل البيانات لكل مزود.
- تطبيق **قواعد (Rules)** على مستوى المؤسسة (اليوم: PII Redaction) عبر العديد من الأتمتات دفعة واحدة بدلاً من تعديل كل deployment على حدة.
<Frame>
![نظرة عامة على Agent Control Plane](/images/enterprise/acp-overview-automations-sankey.png)
</Frame>
<Note>
Agent Control Plane مُوسوم حالياً بـ **Beta** في CrewAI Platform.
</Note>
يجيب التبويبان عن سؤالَين مختلفَين:
- **Automations** — *"كيف يتصرف أسطولي الآن، وكم يكلّفني؟"* راجع [المراقبة](/ar/enterprise/features/agent-control-plane/monitoring).
- **Rules** — *"كيف أفرض سياسة (مثل PII redaction) عبر العديد من عمليات النشر دون إعادة نشر كل واحدة؟"* راجع [القواعد](/ar/enterprise/features/agent-control-plane/rules).
## المتطلبات
<Warning>
يُشترط **crewAI v1.13 أو أحدث** ليتمكن أي أتمتة من تعبئة أي بيانات على هذه الصفحة — تمر بيانات الصحة وعمليات التنفيذ والأخطاء والرموز والتكلفة عبر التليمتري الذي تم تفعيله في `crewai==1.13`. تظهر عمليات النشر الأقدم في لافتة *"We've detected N other automations that we can't display"* ولا تساهم بأي صفوف حتى يتم تحديثها وإعادة نشرها.
</Warning>
<Warning>
يُشترط **خطة Enterprise أو Ultra** لإنشاء أو تعديل [القواعد](/ar/enterprise/features/agent-control-plane/rules). يمكن للمؤسسات على الخطط الأدنى فتح تبويب Rules وعرض القواعد الموجودة، ولكن يُعرض المحرر للقراءة فقط مع شارة قفل "Enterprise" والتنبيه *"PII Redaction rules require an Enterprise plan."*. المراقبة (تبويب Automations) متاحة في جميع الخطط حيث يكون هذا الميزة مفعّلة.
</Warning>
- يجب أن تكون ميزة **Agent Control Plane** مفعّلة لمؤسستك. إن لم ترها في الشريط الجانبي، اطلب من مالك الحساب تفعيلها.
- داخل ACP، يحكم [RBAC](/ar/enterprise/features/rbac) الوصول: `read` للعرض في لوحة المعلومات والقواعد، و`manage` لإنشاء وتعديل وتشغيل/إيقاف وحذف القواعد.
- يمكن ضبط نطاق جميع المخططات والجداول إلى **آخر 24 ساعة** أو **الأسبوع الماضي** أو **آخر 30 يوماً** عبر مُحدّد الوقت في أعلى اليمين. تقارن قيم الفرق (`↑ 8 vs yesterday`, `↓ $20.57 vs yesterday` وغيرها) النافذة المختارة بالنافذة السابقة بنفس الطول.
## ما يمكنك فعله هنا
<CardGroup cols={2}>
<Card title="المراقبة" icon="gauge" href="/ar/enterprise/features/agent-control-plane/monitoring">
راقب صحة الأسطول وإنفاق LLM عبر بطاقات المقاييس و sankey التفاعلي وجداول لكل أتمتة ولوحات جانبية للتعمق في أي أتمتة أو مزود.
</Card>
<Card title="القواعد" icon="shield-check" href="/ar/enterprise/features/agent-control-plane/rules">
طبّق سياسات PII Redaction على مستوى المؤسسة بنطاق محدد بالأدوات والوسوم. تسري التغييرات في التنفيذ التالي — دون الحاجة لإعادة نشر.
</Card>
</CardGroup>
## ذو صلة
<CardGroup cols={2}>
<Card title="Traces" icon="timeline" href="/ar/enterprise/features/traces">
تعمّق في تنفيذ واحد لرؤية تفكير الوكيل واستدعاءات الأدوات واستخدام الرموز.
</Card>
<Card title="RBAC" icon="users" href="/ar/enterprise/features/rbac">
أدِر من يمكنه قراءة Agent Control Plane ومن يمكنه تعديل القواعد.
</Card>
<Card title="PII Redaction للـ Traces" icon="lock" href="/ar/enterprise/features/pii-trace-redactions">
كتالوج الكيانات وضبط PII لكل deployment التي تستند إليها القواعد.
</Card>
<Card title="النشر إلى AMP" icon="rocket" href="/ar/enterprise/guides/deploy-to-amp">
انشر crew على إصدار crewAI يدعم Agent Control Plane.
</Card>
</CardGroup>
<Card title="تحتاج مساعدة؟" icon="headset" href="mailto:support@crewai.com">
تواصل مع فريق الدعم للمساعدة في تفسير المقاييس أو تصميم القواعد.
</Card>

View File

@@ -0,0 +1,122 @@
---
title: "إعداد القواعد"
description: "طبّق سياسات على مستوى المؤسسة عبر العديد من الأتمتات من مكان واحد."
sidebarTitle: "القواعد"
icon: "shield-check"
mode: "wide"
---
<Info>
**تنقل وثائق ACP (إصدار تجريبي)**
- [نظرة عامة](/ar/enterprise/features/agent-control-plane/overview)
- [المراقبة](/ar/enterprise/features/agent-control-plane/monitoring)
- **القواعد** *(أنت هنا)*
</Info>
## نظرة عامة
تتيح لك القواعد تطبيق سياسات — اليوم: **PII Redaction** — عبر العديد من الأتمتات دفعة واحدة، بدلاً من ضبط كل deployment على حدة. افتح تبويب **Rules** في [Agent Control Plane](/ar/enterprise/features/agent-control-plane/overview) لإدارتها.
<Frame>
![قائمة القواعد](/images/enterprise/acp-rules-list.png)
</Frame>
تعرض كل بطاقة قاعدة الاسم والوصف و**النطاق (scope)** الذي تنطبق عليه القاعدة (الأدوات والوسوم المختارة) وعدد **الأتمتات المُفعَّلة** — عمليات النشر التي تطابق النطاق حالياً. يقوم المُفتاح على اليمين بتشغيل القاعدة أو إيقافها دون حذفها.
## المتطلبات
<Warning>
يُشترط **خطة Enterprise أو Ultra** لإنشاء أو تعديل قواعد PII Redaction. يمكن للمؤسسات على الخطط الأدنى فتح تبويب Rules وعرض القواعد الموجودة، ولكن يُعرض المحرر للقراءة فقط مع شارة قفل "Enterprise" والتنبيه *"PII Redaction rules require an Enterprise plan."* — تواصل مع مالك حسابك أو المبيعات للترقية.
</Warning>
- يجب أن تكون ميزة **Agent Control Plane** مفعّلة لمؤسستك. راجع [نظرة عامة — المتطلبات](/ar/enterprise/features/agent-control-plane/overview#المتطلبات).
- تحتاج إلى صلاحية `manage` ضمن [RBAC](/ar/enterprise/features/rbac) على Agent Control Plane لإنشاء وتعديل وتشغيل/إيقاف وحذف القواعد. صلاحية `read` كافية لعرضها.
- تُسجَّل جميع تغييرات القواعد بإصدارات للتدقيق.
## أنواع القواعد المتاحة
| النوع | ما تفعله |
|------|---------------|
| **PII Redaction** | تطبّق PII redaction على عمليات التنفيذ لكل أتمتة مطابِقة، باستخدام نفس كتالوج الكيانات و recognizers المخصصة الموثَّقة في [PII Redaction للـ Traces](/ar/enterprise/features/pii-trace-redactions). |
سيتم إضافة أنواع قواعد أخرى مع الوقت.
## إنشاء قاعدة
<Frame>
<img src="/images/enterprise/acp-rules-edit-side-panel.png" alt="لوحة تعديل قاعدة جانبية بالشروط ونوع قناع PII" width="450" />
</Frame>
<Steps>
<Step title="افتح المحرر">
انقر على **+ Create new** في أعلى يمين تبويب Rules، أو على **View Details** في بطاقة قاعدة موجودة.
</Step>
<Step title="سَمِّ القاعدة وصِفها">
أعطِ القاعدة اسماً واضحاً (مثل *Mask PII (CC)*) ووصفاً يشرح متى تنطبق. يظهر كلاهما على بطاقة القاعدة وفي مودال Engaged Automations.
</Step>
<Step title="اختر النوع">
اليوم **PII Redaction** فقط متاحة.
</Step>
<Step title="حدّد الشروط">
تحدد الشروط الأتمتات التي تنخرط معها القاعدة. كلاهما اختياري ويستخدم دلالات **مساواة المجموعات (set-equality)**:
- **Tools** — تنخرط فقط الأتمتات التي تتطابق مجموعة أدواتها **تطابقاً تامّاً** مع الأدوات المختارة. اختر من تطبيقات Studio و MCPs والأدوات مفتوحة المصدر وأدوات سجل Tool Repository.
- **Automations** — تنخرط فقط الأتمتات التي تتطابق مجموعة وسومها **تطابقاً تامّاً** مع الوسوم المختارة.
ترك مُحدِّد فارغ يعني "بدون تصفية على هذا البعد". ترك كليهما فارغَين يعني أن القاعدة تنطبق على **كل** أتمتة في المؤسسة.
</Step>
<Step title="اضبط جدول PII Mask Type">
حدّد كل نوع كيان تريد تغطيته واختر **Mask** (يستبدل بتسمية الكيان مثل `<CREDIT_CARD>`) أو **Redact** (يحذف النص المطابِق بالكامل). راجع [PII Redaction للـ Traces](/ar/enterprise/features/pii-trace-redactions) للاطلاع على كتالوج الكيانات الكامل وكيفية إضافة recognizers مخصصة على مستوى المؤسسة.
</Step>
<Step title="احفظ">
تنطبق القاعدة على عمليات التنفيذ **المستقبلية** لكل أتمتة مُفعَّلة بمجرد الحفظ. لا حاجة لإعادة النشر.
</Step>
</Steps>
## الأتمتات المُفعَّلة
انقر على **Engaged N automations** في أي بطاقة قاعدة لرؤية أي عمليات النشر تطابقها القاعدة حالياً بالضبط، إلى جانب آخر تنفيذ لكل منها.
<Frame>
![مودال الأتمتات المُفعَّلة](/images/enterprise/acp-rules-engaged-modal.png)
</Frame>
هذه هي أسرع طريقة للتحقق من نطاق قاعدة قبل تمكينها — على سبيل المثال، للتأكد من أن قاعدة محدَّدة بنطاق وسم `production` لا تطابق عن طريق الخطأ deployment تجريبي.
## قواعد على مستوى المؤسسة مقابل إعدادات لكل deployment
يمكن ضبط PII Redaction في مكانين:
- **لكل deployment** — ضمن **Settings → PII Protection** على كل deployment على حدة ([الدليل](/ar/enterprise/features/pii-trace-redactions))
- **على مستوى المؤسسة** — كقاعدة في هذه الصفحة
عندما يتطابق نطاق قاعدة مُفعَّلة على مستوى المؤسسة مع deployment، يُجاوز تكوين الكيانات الخاص بالقاعدة **إعدادات PII المملوكة من قبل الـ deployment** لعمليات تنفيذ ذلك الـ deployment — تصبح القاعدة المصدر الوحيد للحقيقة طالما هي مرتبطة. عطّل القاعدة أو فُكَّ ارتباطها (أو غيِّر نطاقها بحيث لا تتطابق بعد الآن) ويعود الـ deployment إلى إعدادات PII Protection الخاصة به.
فضّل القواعد على مستوى المؤسسة عندما تريد فرض سياسة متسقة عبر العديد من عمليات النشر؛ احتفظ بالضبط لكل deployment للاستثناءات الفردية.
## ذو صلة
<CardGroup cols={2}>
<Card title="Agent Control Plane — نظرة عامة" icon="book-open" href="/ar/enterprise/features/agent-control-plane/overview">
ما هو ACP، المتطلبات، مستويات الخطط، و RBAC.
</Card>
<Card title="Agent Control Plane — المراقبة" icon="gauge" href="/ar/enterprise/features/agent-control-plane/monitoring">
راقب الأتمتات واستهلاك LLM عبر أسطولك.
</Card>
<Card title="PII Redaction للـ Traces" icon="lock" href="/ar/enterprise/features/pii-trace-redactions">
كتالوج الكيانات، recognizers المخصصة، والضبط لكل deployment.
</Card>
<Card title="RBAC" icon="users" href="/ar/enterprise/features/rbac">
أدِر من يمكنه إنشاء أو تعديل القواعد.
</Card>
</CardGroup>
<Card title="تحتاج مساعدة؟" icon="headset" href="mailto:support@crewai.com">
تواصل مع فريق الدعم للمساعدة في تصميم قواعد لمؤسستك.
</Card>

View File

@@ -26,10 +26,10 @@ icon: "arrows-rotate"
## الخطوة 1 — هيكلة طاقم التحقق
أنشئ مشروع طاقم جديد. يُهيكل CrewAI CLI البنية:
أنشئ مشروع crew كلاسيكيًا لأن هذا المثال يربط أداة Python عبر `crew.py`:
```bash
crewai create crew rotation_verifier --skip_provider
crewai create crew rotation_verifier --classic --skip_provider
cd rotation_verifier
```

View File

@@ -24,15 +24,39 @@ mode: "wide"
1. في CrewAI AMP، انتقل إلى **Settings** > **OpenTelemetry Collectors**.
2. انقر على **Add Collector**.
3. اختر نوع التكامل — **OpenTelemetry Traces** أو **OpenTelemetry Logs**.
4. هيّئ الاتصال:
- **Endpoint** — نقطة نهاية OTLP لمجمّعك (مثل `https://otel-collector.example.com:4317`).
- **Service Name** — اسم لتعريف هذه الخدمة في منصة المراقبة.
- **Custom Headers** *(اختياري)* — أضف رؤوس المصادقة أو التوجيه كأزواج مفتاح-قيمة.
- **Certificate** *(اختياري)* — قدم شهادة TLS إذا كان مجمّعك يتطلبها.
5. انقر على **Save**.
3. اختر تكاملاً:
- **OpenTelemetry Traces** و**OpenTelemetry Logs** — صدّر إلى أي مجمّع أو واجهة خلفية متوافقة مع OTLP.
- **Datadog** — أرسل التتبعات مباشرة إلى استقبال OTLP الخاص بـ Datadog، دون الحاجة إلى مجمّع منفصل أو Datadog Agent.
4. هيّئ الاتصال. تعتمد الحقول على التكامل الذي اخترته:
<Frame>![تهيئة مجمّع OpenTelemetry](/images/crewai-otel-collector-config.png)</Frame>
<Tabs>
<Tab title="OpenTelemetry Traces / Logs">
إن **OpenTelemetry Traces** و**OpenTelemetry Logs** تكاملان منفصلان يتشاركان نفس الحقول — اختر التكامل المطابق للإشارة التي تريد تصديرها.
- **Endpoint** — نقطة نهاية OTLP لمجمّعك (مثل `https://otel-collector.example.com:4317`).
- **Service Name** — اسم لتعريف هذه الخدمة في منصة المراقبة.
- **Custom Headers** *(اختياري)* — أضف رؤوس المصادقة أو التوجيه كأزواج مفتاح-قيمة.
- **Certificate** *(اختياري)* — قدم شهادة TLS إذا كان مجمّعك يتطلبها.
<Frame>![تهيئة مجمّع OpenTelemetry](/images/crewai-otel-collector-opentelemetry.png)</Frame>
</Tab>
<Tab title="Datadog">
- **Datadog Site Domain** — مضيف OTLP لموقع Datadog الخاص بك فقط، دون بروتوكول أو مسار. يقوم CrewAI ببناء نقطة نهاية HTTPS OTLP الكاملة نيابةً عنك. استخدم المضيف المطابق لـ [موقع Datadog](https://docs.datadoghq.com/getting_started/site/) الخاص بك:
- `otlp.datadoghq.com` (US1)
- `otlp.us3.datadoghq.com` (US3)
- `otlp.us5.datadoghq.com` (US5)
- `otlp.datadoghq.eu` (EU1)
- `otlp.ap1.datadoghq.com` (AP1)
- **API Key** — مفتاح واجهة برمجة تطبيقات Datadog الخاص بك. راجع [كيفية إنشاء واحد](https://docs.datadoghq.com/account_management/api-app-keys/#api-keys).
يصدّر تكامل Datadog **التتبعات**.
<Frame>![تهيئة مجمّع Datadog](/images/crewai-otel-collector-datadog.png)</Frame>
</Tab>
</Tabs>
5. *(اختياري)* انقر على **Test Connection** للتحقق من قدرة CrewAI على الوصول إلى نقطة النهاية باستخدام بيانات الاعتماد التي قدمتها.
6. انقر على **Save**.
<Tip>
يمكنك إضافة مجمّعات متعددة — على سبيل المثال، واحد للتتبعات وآخر للسجلات، أو الإرسال إلى واجهات خلفية مختلفة لأغراض مختلفة.

View File

@@ -164,6 +164,12 @@ crewai deploy remove <deployment_id>
![اختيار المستودع](/images/enterprise/select-repo.png)
</Frame>
<Tip>
إذا كان Crew أو Flow داخل مجلد فرعي في monorepo، فوسّع **Advanced**
وعيّن دليل عمل قبل النشر. راجع
[النشر من Monorepo](/ar/enterprise/guides/monorepo-deployments).
</Tip>
</Step>
<Step title="تعيين متغيرات البيئة">
@@ -368,17 +374,17 @@ git push
**الحل**: تحقق من أن مشروعك يتطابق مع البنية المتوقعة:
- **كل من الطواقم والتدفقات**: يجب أن تكون نقطة الدخول في `src/project_name/main.py`
- **الطواقم**: تستخدم دالة `run()` كنقطة دخول
- **التدفقات**: تستخدم دالة `kickoff()` كنقطة دخول
- **JSON-first Crews**: أبقِ `crew.jsonc` أو `crew.json` و `agents/` في جذر المشروع
- **Crews كلاسيكية**: استخدم `src/project_name/main.py` مع دالة دخول `run()`
- **Flows**: استخدم `src/project_name/main.py` مع دالة دخول `kickoff()`
راجع [التحضير للنشر](/ar/enterprise/guides/prepare-for-deployment) لمخططات البنية المفصلة.
#### مُزخرف CrewBase مفقود
#### مُزخرف CrewBase مفقود في crew كلاسيكية
**العرض**: أخطاء "Crew not found" أو "Config not found" أو أخطاء تهيئة الوكيل/المهمة
**الحل**: تأكد من أن **جميع** فئات الطاقم تستخدم مُزخرف `@CrewBase`:
**الحل**: في crews الكلاسيكية Python/YAML، تأكد من أن جميع فئات الـ crew تستخدم مُزخرف `@CrewBase`. لا تحتاج crews بنمط JSON-first إلى هذا المزخرف.
```python
from crewai.project import CrewBase, agent, crew, task
@@ -398,8 +404,8 @@ class YourCrew():
```
<Info>
ينطبق هذا على الطواقم المستقلة والطواقم المضمنة داخل مشاريع التدفق.
كل فئة طاقم تحتاج المُزخرف.
ينطبق هذا على فئات crew الكلاسيكية المكتوبة في Python، بما في ذلك crews الكلاسيكية المضمنة داخل مشاريع Flow.
يتم التحقق من crews بنمط JSON-first من `crew.jsonc` و `agents/` بدلاً من ذلك.
</Info>
#### نوع pyproject.toml غير صحيح
@@ -436,8 +442,8 @@ type = "flow"
**الحل**:
1. تحقق من سجلات التنفيذ في لوحة تحكم AMP (علامة تبويب Traces)
2. تحقق من أن جميع الأدوات لديها مفاتيح API المطلوبة مُهيأة
3. تأكد من صحة تهيئات الوكلاء في `agents.yaml`
4. تحقق من تهيئات المهام في `tasks.yaml` بحثاً عن أخطاء الصياغة
3. في crews بنمط JSON-first، تحقق من `crew.jsonc` والملفات المشار إليها داخل `agents/`
4. في crews الكلاسيكية، تأكد من صحة `agents.yaml` و `tasks.yaml`
<Card title="تحتاج مساعدة؟" icon="headset" href="mailto:support@crewai.com">
تواصل مع فريق الدعم للمساعدة في مشاكل النشر أو أسئلة حول

View File

@@ -0,0 +1,224 @@
---
title: "النشر من Monorepo"
description: "انشر Crew أو Flow من مجلد فرعي داخل مستودع أكبر"
icon: "folder-tree"
mode: "wide"
---
<Note>
استخدم دليل عمل عندما يكون Crew أو Flow داخل مستودع أكبر. يتحقق CrewAI AMP
من الأتمتة ويبنيها ويشغلها من ذلك المجلد الفرعي بدلاً من جذر المستودع.
</Note>
## متى تستخدم ذلك
يكون النشر من monorepo مفيداً عندما يحتوي مستودع واحد على عدة أتمتات أو حزم
مشتركة أو كود تطبيقات آخر:
```text
company-ai/
|-- uv.lock
|-- packages/
| `-- shared_tools/
`-- crews/
|-- support_agent/
| |-- pyproject.toml
| |-- crew.jsonc
| `-- agents/
| `-- support_agent.jsonc
`-- research_flow/
|-- pyproject.toml
`-- src/
`-- research_flow/
`-- main.py
```
لنشر `support_agent`، اضبط دليل العمل على:
```text
crews/support_agent
```
لا يزال AMP يجلب المستودع كاملاً أو يرفعه، لكنه يتعامل مع المجلد المحدد كجذر
مشروع الأتمتة.
## ما الذي يتحكم به دليل العمل
عند تعيين دليل عمل، يستخدم AMP ذلك المجلد من أجل:
- التحقق من المشروع، بما في ذلك `pyproject.toml` وملفات crew JSON وأي نقطة دخول كلاسيكية لـ Crew أو Flow
- تثبيت الاعتماديات باستخدام `uv`
- دليل العمل للعملية قيد التشغيل
- متغير البيئة `CREW_ROOT_DIR`
ترك الحقل فارغاً يحافظ على السلوك الحالي ويستخدم جذر المستودع.
## المصادر المدعومة
يمكنك تعيين دليل عمل عند إنشاء نشر من:
- مستودع GitHub متصل
- مستودع Git مكوّن في AMP
- رفع ملف ZIP
<Info>
اضبط أدلة العمل من واجهة AMP على الويب. لا يطلب تدفق CLI
`crewai deploy create` هذا الحقل.
</Info>
يمكنك أيضاً إضافة دليل العمل أو تغييره في نشر موجود من صفحة **Settings** الخاصة
بالنشر. يسري التغيير في النشر التالي.
<Warning>
لا يمكن استخدام أدلة العمل وauto-deploy معاً. إذا كان للنشر دليل عمل، يتم
تعطيل auto-deploy لذلك النشر. أوقف auto-deploy قبل تعيين دليل عمل.
</Warning>
## إعداد نشر جديد
<Steps>
<Step title="افتح Deploy from Code">
في CrewAI AMP، أنشئ نشراً جديداً واختر المصدر: GitHub أو Git Repository أو
رفع ZIP.
</Step>
<Step title="اختر المستودع أو الفرع أو ملف ZIP">
اختر المستودع والفرع اللذين يحتويان على monorepo، أو ارفع ملف ZIP يحتوي
جذره على محتويات monorepo.
</Step>
<Step title="افتح الإعدادات المتقدمة">
وسّع قسم **Advanced** في نموذج النشر.
</Step>
<Step title="أدخل دليل العمل">
أدخل المسار من جذر المستودع إلى مشروع Crew أو Flow:
```text
crews/support_agent
```
لا تضف شرطة مائلة في البداية.
</Step>
<Step title="انشر">
أضف أي متغيرات بيئة مطلوبة، ثم ابدأ النشر.
</Step>
</Steps>
## إعداد نشر موجود
<Steps>
<Step title="افتح إعدادات النشر">
انتقل إلى الأتمتة في AMP وافتح **Settings**.
</Step>
<Step title="أوقف auto-deploy إذا لزم الأمر">
إذا كان auto-deploy مفعلاً، أوقفه أولاً. لا يكون حقل دليل العمل متاحاً
أثناء تشغيل auto-deploy.
</Step>
<Step title="عيّن دليل العمل">
في **Basic settings**، أدخل مسار المجلد الفرعي، مثل:
```text
crews/support_agent
```
</Step>
<Step title="أعد النشر">
احفظ الإعداد وأعد نشر الأتمتة. سيتم استخدام دليل العمل الجديد في النشر
التالي.
</Step>
</Steps>
## قواعد المسار
يجب أن يكون دليل العمل مساراً نسبياً داخل جذر المستودع أو ZIP.
| القاعدة | المثال |
|---------|--------|
| استخدم مساراً نسبياً | `crews/support_agent` |
| لا تبدأ بـ `/` | `/crews/support_agent` غير صالح |
| لا تستخدم مقاطع المسار `.` أو `..` | `crews/../support_agent` غير صالح |
| استخدم الأحرف والأرقام والشرطات والشرطات السفلية والنقاط والشرطات المائلة فقط | `crews/support agent` غير صالح |
| اجعل المسار 255 حرفاً أو أقل | يتم رفض المسارات الأطول |
يزيل AMP المسافات البيضاء في البداية والنهاية، ويضغط الشرطات المائلة المتكررة،
ويزيل الشرطة المائلة النهائية. تستخدم القيمة الفارغة جذر المستودع.
## ملفات القفل وUV Workspaces
يجب أن يحتوي المجلد المحدد على `pyproject.toml` وملفات المشروع المناسبة لنوع
الأتمتة:
- crew بنمط JSON-first: ملف `crew.jsonc` أو `crew.json` مع مجلد `agents/`
- Crew كلاسيكي أو Flow: مجلد `src/` مع نقطة دخول Python المتوقعة
يمكن أن يوجد ملف `uv.lock` أو `poetry.lock` إما في المجلد المحدد أو في جذر
المستودع.
يدعم هذا تخطيطي ملفات القفل الشائعين:
<Tabs>
<Tab title="ملف قفل المشروع">
```text
company-ai/
`-- crews/
`-- support_agent/
|-- pyproject.toml
|-- uv.lock
|-- crew.jsonc
`-- agents/
`-- support_agent.jsonc
```
</Tab>
<Tab title="ملف قفل workspace">
```text
company-ai/
|-- uv.lock
|-- packages/
| `-- shared_tools/
`-- crews/
`-- support_agent/
|-- pyproject.toml
|-- crew.jsonc
`-- agents/
`-- support_agent.jsonc
```
</Tab>
</Tabs>
<Tip>
إذا كانت الأتمتة تستورد حزماً مشتركة من مكان آخر في monorepo، فصرّح بهذه
الحزم في `pyproject.toml` باستخدام إعدادات UV workspace أو path أو source.
يشغل AMP الأتمتة من المجلد المحدد، لذلك يجب تثبيت الكود المشترك كاعتمادية
بدلاً من الاعتماد على وجود جذر المستودع في Python path.
</Tip>
## استكشاف الأخطاء وإصلاحها
### لم يتم العثور على دليل العمل
تحقق من أن المسار نسبي إلى جذر المستودع أو ZIP. بالنسبة لرفع ZIP، يجب أن
تتضمن محتويات ZIP مسار دليل العمل تماماً كما أدخلته.
### pyproject.toml مفقود
يجب أن يشير دليل العمل إلى مجلد مشروع Crew أو Flow، وليس فقط إلى مجلد أب
يحتوي على عدة مشاريع.
### uv.lock أو poetry.lock مفقود
اعمل commit لملف قفل إما في مجلد المشروع المحدد أو في جذر المستودع. بالنسبة
إلى UV workspaces، يتم دعم إبقاء `uv.lock` في جذر workspace.
### Auto-Deploy غير متاح
يتم تعطيل auto-deploy أثناء تعيين دليل عمل. استخدم إعادة النشر اليدوية أو شغّل
إعادة النشر من CI/CD باستخدام AMP API.
<Card title="النشر على AMP" icon="rocket" href="/ar/enterprise/guides/deploy-to-amp">
تابع دليل النشر بعد اختيار دليل عمل monorepo.
</Card>

View File

@@ -24,7 +24,7 @@ mode: "wide"
<CardGroup cols={2}>
<Card title="مشاريع الطاقم" icon="users">
فرق وكلاء ذكاء اصطناعي مستقلة مع `crew.py` يحدد الوكلاء والمهام. الأفضل للمهام المركزة والتعاونية.
فرق وكلاء ذكاء اصطناعي مستقلة. الـ crews الجديدة تستخدم بنية JSON-first مع `crew.jsonc` و `agents/`؛ ويمكن للـ crews الكلاسيكية الاستمرار في استخدام `crew.py`.
</Card>
<Card title="مشاريع التدفق" icon="diagram-project">
سير عمل مُنسّق مع طواقم مضمنة في مجلد `crews/`. الأفضل للعمليات المعقدة متعددة المراحل.
@@ -33,19 +33,19 @@ mode: "wide"
| الجانب | الطاقم | التدفق |
|--------|--------|--------|
| **بنية المشروع** | `src/project_name/` مع `crew.py` | `src/project_name/` مع مجلد `crews/` |
| **موقع المنطق الرئيسي** | `src/project_name/crew.py` | `src/project_name/main.py` (فئة Flow) |
| **دالة نقطة الدخول** | `run()` في `main.py` | `kickoff()` في `main.py` |
| **بنية المشروع** | جذر المشروع مع `crew.jsonc` و `agents/` | `src/project_name/` مع مجلد `crews/` |
| **موقع المنطق الرئيسي** | `crew.jsonc` (كلاسيكي: `src/project_name/crew.py`) | `src/project_name/main.py` (فئة Flow) |
| **دالة نقطة الدخول** | تُحمّل من `crew.jsonc` (كلاسيكي: `run()` في `main.py`) | `kickoff()` في `main.py` |
| **نوع pyproject.toml** | `type = "crew"` | `type = "flow"` |
| **أمر CLI للإنشاء** | `crewai create crew name` | `crewai create flow name` |
| **موقع التهيئة** | `src/project_name/config/` | `src/project_name/crews/crew_name/config/` |
| **موقع التهيئة** | `crew.jsonc` و `agents/` و `tools/` اختياريًا | `src/project_name/crews/crew_name/config/` أو مجلدات crew JSON مضمنة |
| **يمكن أن يحتوي طواقم أخرى** | لا | نعم (في مجلد `crews/`) |
## مرجع بنية المشروع
### بنية مشروع الطاقم
عند تشغيل `crewai create crew my_crew`، تحصل على هذه البنية:
عند تشغيل `crewai create crew my_crew`، تحصل على بنية JSON-first:
```
my_crew/
@@ -54,24 +54,25 @@ my_crew/
├── README.md
├── .env
├── uv.lock # REQUIRED for deployment
── src/
└── my_crew/
├── __init__.py
├── main.py # Entry point with run() function
├── crew.py # Crew class with @CrewBase decorator
├── tools/
│ ├── custom_tool.py
│ └── __init__.py
└── config/
├── agents.yaml # Agent definitions
└── tasks.yaml # Task definitions
── crew.jsonc # إعدادات الـ crew والمهام والعملية والمدخلات
├── agents/
└── researcher.jsonc # تعريفات الـ Agents
├── tools/ # أدوات custom:<name> اختيارية
├── knowledge/
└── skills/
```
<Warning>
بنية `src/project_name/` المتداخلة ضرورية للطواقم.
وضع الملفات في المستوى الخاطئ سيسبب فشل النشر.
في crews بنمط JSON-first، أبقِ `crew.jsonc` و `agents/` و `tools/` و `knowledge/` و `skills/`
في جذر المشروع. وضعها داخل `src/` يمنع `crewai run` والتحقق قبل النشر من العثور على تعريف الـ crew.
</Warning>
<Info>
المشاريع الكلاسيكية التي تُنشأ عبر `crewai create crew my_crew --classic` تستخدم البنية القديمة
`src/project_name/crew.py` و `src/project_name/config/agents.yaml` و
`src/project_name/config/tasks.yaml`. تظل هذه البنية مدعومة للـ crews المكتوبة في Python مع decorators.
</Info>
### بنية مشروع التدفق
عند تشغيل `crewai create flow my_flow`، تحصل على هذه البنية:
@@ -100,9 +101,9 @@ my_flow/
```
<Info>
كلا الطواقم والتدفقات تستخدم بنية `src/project_name/`.
الفرق الرئيسي أن التدفقات لها مجلد `crews/` للطواقم المضمنة،
بينما الطواقم لها `crew.py` مباشرة في مجلد المشروع.
الـ crews المستقلة بنمط JSON-first تستخدم ملفات JSON في جذر المشروع. أما Flows فتظل تستخدم
`src/project_name/` ويمكن أن تحتوي crews مضمنة كلاسيكية أو مجلدات crew JSON يتم تحميلها عبر
`crewai.project.load_crew`.
</Info>
## قائمة فحص ما قبل النشر
@@ -154,60 +155,89 @@ git commit -m "Add uv.lock for deployment"
git push
```
### 3. التحقق من استخدام مُزخرف CrewBase
### 3. التحقق من تعريف الـ Crew
**يجب أن تستخدم كل فئة طاقم مُزخرف `@CrewBase`.** ينطبق هذا على:
<Tabs>
<Tab title="JSON-first Crews">
يجب أن تحتوي crews بنمط JSON-first على `crew.jsonc` أو `crew.json` في جذر المشروع.
يجب أن يشير مصفوفة `agents` إلى ملفات داخل `agents/`، ويجب أن تشير كل task إلى اسم Agent صحيح.
- مشاريع الطاقم المستقلة
- الطواقم المضمنة داخل مشاريع التدفق
```jsonc crew.jsonc
{
"name": "Research Crew",
"agents": ["researcher"],
"tasks": [
{
"name": "research_task",
"description": "Research {topic}.",
"expected_output": "A concise report.",
"agent": "researcher"
}
],
"inputs": {
"topic": "AI Agents"
}
}
```
```python
from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task
from crewai.agents.agent_builder.base_agent import BaseAgent
from typing import List
تُشار الأدوات المخصصة بصيغة `"custom:<name>"` ويجب تنفيذها في
`tools/<name>.py` كصنف يرث من `BaseTool`.
</Tab>
<Tab title="Crews كلاسيكية Python/YAML">
يجب أن تستخدم الـ crews الكلاسيكية وPython crews المضمنة داخل Flows مزخرف `@CrewBase`.
@CrewBase # This decorator is REQUIRED
class MyCrew():
"""My crew description"""
```python
from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task
from crewai.agents.agent_builder.base_agent import BaseAgent
from typing import List
agents: List[BaseAgent]
tasks: List[Task]
@CrewBase
class MyCrew():
"""My crew description"""
@agent
def my_agent(self) -> Agent:
return Agent(
config=self.agents_config['my_agent'], # type: ignore[index]
verbose=True
)
agents: List[BaseAgent]
tasks: List[Task]
@task
def my_task(self) -> Task:
return Task(
config=self.tasks_config['my_task'] # type: ignore[index]
)
@agent
def my_agent(self) -> Agent:
return Agent(
config=self.agents_config['my_agent'], # type: ignore[index]
verbose=True
)
@crew
def crew(self) -> Crew:
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True,
)
```
@task
def my_task(self) -> Task:
return Task(
config=self.tasks_config['my_task'] # type: ignore[index]
)
<Warning>
إذا نسيت مُزخرف `@CrewBase`، سيفشل النشر بأخطاء حول
تهيئات الوكلاء أو المهام المفقودة.
</Warning>
@crew
def crew(self) -> Crew:
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True,
)
```
</Tab>
</Tabs>
### 4. التحقق من نقاط دخول المشروع
كل من الطواقم والتدفقات لها نقطة دخول في `src/project_name/main.py`:
لا تحتاج crews المستقلة بنمط JSON-first إلى ملف `src/project_name/main.py` مكتوب يدويًا؛
يقوم `crewai run` وتغليف النشر بتحميل `crew.jsonc` مباشرة. تستخدم crews الكلاسيكية وFlows نقاط دخول Python:
<Tabs>
<Tab title="للطواقم">
<Tab title="JSON-first Crews">
شغّل محليًا من جذر المشروع:
```bash
crewai run
```
</Tab>
<Tab title="Crews كلاسيكية">
تستخدم نقطة الدخول دالة `run()`:
```python
@@ -278,16 +308,17 @@ grep -A2 "\[tool.crewai\]" pyproject.toml
# 2. Verify uv.lock exists
ls -la uv.lock || echo "ERROR: uv.lock missing! Run 'uv lock'"
# 3. Verify src/ structure exists
ls -la src/*/main.py 2>/dev/null || echo "No main.py found in src/"
# 3. For JSON-first crews, verify crew.jsonc and agents/
([ -f crew.jsonc ] || [ -f crew.json ]) || echo "No crew.jsonc or crew.json found"
test -d agents || echo "No agents/ directory found"
# 4. For Crews - verify crew.py exists
# 4. For classic Crews - verify crew.py exists
ls -la src/*/crew.py 2>/dev/null || echo "No crew.py (expected for Crews)"
# 5. For Flows - verify crews/ folder exists
ls -la src/*/crews/ 2>/dev/null || echo "No crews/ folder (expected for Flows)"
# 6. Check for CrewBase usage
# 6. For classic Python crews - check for CrewBase usage
grep -r "@CrewBase" . --include="*.py"
```
@@ -297,8 +328,9 @@ grep -r "@CrewBase" . --include="*.py"
|-------|-------|---------|
| `uv.lock` مفقود | فشل البناء أثناء حل الاعتماديات | شغّل `uv lock` وارفعه |
| `type` خاطئ في pyproject.toml | نجاح البناء لكن فشل وقت التشغيل | غيّر إلى النوع الصحيح |
| مُزخرف `@CrewBase` مفقود | أخطاء "Config not found" | أضف المُزخرف لجميع فئات الطاقم |
| ملفات في الجذر بدل `src/` | نقطة الدخول غير موجودة | انقلها إلى `src/project_name/` |
| `crew.jsonc` أو `agents/` مفقود في crew بنمط JSON-first | لا يمكن العثور على تعريف الـ crew | أبقِ `crew.jsonc` و `agents/` في جذر المشروع |
| مُزخرف `@CrewBase` مفقود في crew كلاسيكية | أخطاء "Config not found" | أضف المُزخرف لجميع فئات الـ crew الكلاسيكية |
| ملفات كلاسيكية في الجذر بدل `src/` | نقطة الدخول غير موجودة | انقل ملفات Python الكلاسيكية إلى `src/project_name/` |
| `run()` أو `kickoff()` مفقودة | لا يمكن بدء الأتمتة | أضف دالة الدخول الصحيحة |
## الخطوات التالية

View File

@@ -0,0 +1,123 @@
---
title: تكامل Databricks
description: "اربط وكلاء CrewAI بـ Databricks Genie وSQL وUnity Catalog Functions وVector Search عبر خوادم MCP المُدارة من Databricks."
icon: "layer-group"
mode: "wide"
---
## نظرة عامة
اربط وكلاء CrewAI مباشرةً بمساحة عمل Databricks الخاصة بك عبر [خوادم MCP المُدارة من Databricks](https://docs.databricks.com/aws/en/generative-ai/mcp/managed-mcp). يتيح تكامل Databricks لوكلائك طرح أسئلة بلغة طبيعية باستخدام **Genie**، وتنفيذ **SQL** خاضع للحوكمة، واستدعاء **Unity Catalog Functions**، واسترجاع المستندات باستخدام **Vector Search** — كل ذلك دون كتابة أو استضافة أي كود موصِّل، مع تطبيق أذونات Unity Catalog في كل استدعاء.
في الخلفية، يُعدّ تكامل Databricks غلافًا مُدارًا حول دعم [خوادم MCP المخصصة](/ar/enterprise/guides/custom-mcp-server) في CrewAI. تكشف Databricks عن كل قدرة كنقطة نهاية [Model Context Protocol](https://modelcontextprotocol.io/) خاصة بها، ويتصل بها CrewAI بأمان نيابةً عنك. ولأن كل خادم يُضاف بشكل منفصل، يمكنك تفعيل القدرات التي تحتاجها فرقك (crews) بالضبط.
## القدرات الرئيسية
<CardGroup cols={2}>
<Card title="Genie" icon="comments">
اطرح أسئلة بلغة طبيعية واحصل على إجابات مستندة إلى بياناتك باستخدام [Genie](https://docs.databricks.com/aws/en/genie/)، الذي يستعلم من Genie Spaces وUnity Catalog ويوفّر روابط تعود إلى واجهة Databricks.
</Card>
<Card title="Databricks SQL" icon="database">
نفّذ SQL خاضعًا للحوكمة على مستودعات Databricks لديك للاستعلام عن البيانات وتحويلها وإنشاء خطوط أنابيب البيانات مباشرةً من وكلائك.
</Card>
<Card title="Unity Catalog Functions" icon="function">
استدعِ [دوال Unity Catalog](https://docs.databricks.com/aws/en/udf/unity-catalog) لتنفيذ SQL مُعرّف مسبقًا ومنطق أعمال مخصّص كأدوات قابلة لإعادة الاستخدام وخاضعة للحوكمة.
</Card>
<Card title="Vector Search" icon="magnifying-glass">
استرجع المستندات ذات الصلة لسير عمل RAG والمعرفة من فهارس [Mosaic AI Vector Search](https://docs.databricks.com/aws/en/generative-ai/vector-search) باستخدام التشابه الدلالي.
</Card>
</CardGroup>
تعمل جميع الخوادم خلف Unity AI Gateway وتطبّق ضوابط الوصول في Unity Catalog، بحيث لا يرى وكلاؤك سوى البيانات والأدوات المصرَّح لهم باستخدامها.
## المتطلبات المسبقة
قبل استخدام تكامل Databricks، تأكّد من توفّر ما يلي:
- حساب [CrewAI AMP](https://app.crewai.com) باشتراك نشط
- مساحة عمل Databricks تحتوي على القدرات التي تريد كشفها (Genie Spaces، مستودعات SQL، دوال Unity Catalog، أو فهارس Vector Search)
- [امتيازات Unity Catalog](https://docs.databricks.com/aws/en/data-governance/unity-catalog) المناسبة على الكائنات الأساسية
- اسم مضيف مساحة عمل Databricks الخاص بك (مثال: `your-workspace.cloud.databricks.com`)
## خوادم MCP المُدارة من Databricks
تنشر Databricks خادم MCP مُدارًا منفصلًا لكل قدرة. يكشف CrewAI عنها كاتصالات فردية، يُهيَّأ كل منها باستخدام مضيف مساحة العمل ومعرّفات Unity Catalog ذات الصلة. تتبع نقاط النهاية الأنماط التالية:
| الخادم | الوظيفة | نمط عنوان MCP |
|--------|---------|---------------|
| **Genie** | أسئلة وأجوبة بلغة طبيعية على Genie Space | `https://<workspace-hostname>/api/2.0/mcp/genie/{genie_space_id}` |
| **Databricks SQL** | تنفيذ SQL على مستودعاتك | `https://<workspace-hostname>/api/2.0/mcp/sql` |
| **Unity Catalog Functions** | تشغيل دوال UC المسجّلة | `https://<workspace-hostname>/api/2.0/mcp/functions/{catalog}/{schema}` |
| **Vector Search** | الاستعلام من فهرس Vector Search | `https://<workspace-hostname>/api/2.0/mcp/vector-search/{catalog}/{schema}` |
<Note>
لا حاجة لإنشاء عناوين URL هذه يدويًا — يُنشئ CrewAI كل نقطة نهاية من مضيف مساحة العمل والمعرّفات (Genie Space ID، أو catalog/schema) التي تقدّمها عند تهيئة الاتصال. للاطّلاع على المواصفات الكاملة وأحدث تفاصيل نقاط النهاية، راجع [وثائق MCP المُدارة من Databricks](https://docs.databricks.com/aws/en/generative-ai/mcp/managed-mcp).
</Note>
## ربط Databricks في CrewAI AMP
<Frame>
<img src="/images/enterprise/databricks-configure.png" alt="تهيئة خادم MCP مُدار من Databricks في CrewAI AMP" />
</Frame>
تظهر كل قدرة من قدرات Databricks — **Databricks Genie** و**Databricks SQL** و**Databricks Unity Catalog Functions** و**Databricks Vector Search** — كخادم MCP خاص بها ضمن مجموعة Databricks في صفحة **Tools & Integrations**. هيّئ ما تحتاجه:
<Steps>
<Step title="افتح Tools & Integrations">
انتقل إلى **Tools & Integrations** في الشريط الجانبي الأيسر في CrewAI AMP وحدِّد مجموعة **Databricks** في قائمة Connections. سترى خوادم Genie وSQL وUnity Catalog Functions وVector Search مُدرجة أسفلها.
</Step>
<Step title="هيّئ خادمًا">
انقر على **Configure** بجوار القدرة التي تريد تفعيلها وقدّم تفاصيل الاتصال الخاصة بها:
- **Workspace Host** — اسم مضيف مساحة عمل Databricks الخاص بك (مثال: `my-workspace.cloud.databricks.com`).
- **Genie** — **Genie Space ID** المراد الاستعلام عنه.
- **Unity Catalog Functions** — الـ **catalog** والـ **schema** اللذان يحتويان على دوالك.
- **Vector Search** — الـ **catalog** والـ **schema** اللذان يحتويان على الفهرس.
- **Databricks SQL** — لا توجد معرّفات إضافية؛ تُنفَّذ الاستعلامات على مستودعات SQL في مساحة عملك.
</Step>
<Step title="اختر طريقة المصادقة">
اختر كيف يصادق CrewAI على Databricks. يُوصى باستخدام **OAuth**.
- **Use OAuth** — اتصل بأمان باستخدام OAuth 2.0. يصادق كل مستخدم على حدة، وتُصدر Databricks رموزًا (tokens) محدّدة النطاق للقدرة (`genie` أو `sql` أو `unity-catalog` أو `vector-search`). يتولّى CrewAI تدفّق التفويض ويُجدّد الرموز تلقائيًا.
- **Use personal access token** — صادِق باستخدام [رمز وصول شخصي من Databricks](https://docs.databricks.com/aws/en/dev-tools/auth/pat). استخدم هوية بأقل الامتيازات للحدّ من التعرّض.
</Step>
<Step title="صادِق">
أكمل المصادقة. بمجرد الاتصال، تصبح أدوات الخادم متاحة لفرقك. كرّر العملية لأي قدرات Databricks أخرى تريد تفعيلها.
</Step>
</Steps>
<Tip>
لأن كل قدرة هي اتصال منفصل، يمكنك المزج والمطابقة — على سبيل المثال، فعّل Genie وVector Search لفريق بحث، مع حجز SQL وUnity Catalog Functions لفريق هندسة البيانات. تتيح لك إعدادات الرؤية (Visibility) التحكّم في أعضاء الفريق الذين يمكنهم استخدام كل منها.
</Tip>
## استخدام أدوات Databricks في فرقك
بمجرد الاتصال، تظهر الأدوات التي يكشفها كل خادم MCP جنبًا إلى جنب مع الاتصالات المدمجة في صفحة **Tools & Integrations**. يمكنك:
- **إسناد الأدوات إلى الوكلاء** في فرقك تمامًا مثل أي أداة أخرى في CrewAI.
- **إدارة الرؤية** للتحكّم في أعضاء الفريق الذين يمكنهم استخدام كل اتصال.
- **تعديل أو إزالة** أي اتصال في أي وقت من قائمة Connections.
يمكن لوكلائك الآن طلب إجابات مستندة من Genie، وتنفيذ SQL على مستودعاتك، واستدعاء دوال Unity Catalog، والبحث في فهارس Vector Search — مع تدفّق النتائج تلقائيًا إلى استدلالهم.
<Warning>
تطبّق Databricks الحوكمة عبر Unity Catalog وUnity AI Gateway: لا يمكن للمستخدم اكتشاف الأدوات واستدعاؤها إلا تلك المصرَّح بها لهوية مساحة عمله. إذا فشل استدعاء أداة، فتأكّد من أن المستخدم المتصل (أو هوية الرمز) يمتلك امتيازات Unity Catalog المطلوبة على Genie Space أو المستودع أو الدالة أو الفهرس. تُنفَّذ بعض استعلامات Genie وSQL بشكل غير متزامن وقد تستغرق لحظة لإرجاع النتائج.
</Warning>
## مزيد من المعلومات
<CardGroup cols={2}>
<Card title="خوادم MCP المُدارة من Databricks" icon="layer-group" href="https://docs.databricks.com/aws/en/generative-ai/mcp/managed-mcp">
وثائق Databricks الرسمية لخوادم MCP المُدارة Genie وSQL وUnity Catalog Functions وVector Search.
</Card>
<Card title="خوادم MCP المخصصة في CrewAI" icon="plug" href="/ar/enterprise/guides/custom-mcp-server">
تعرّف على كيفية اتصال CrewAI بأي خادم MCP، وهو الأساس الذي يُبنى عليه تكامل Databricks.
</Card>
</CardGroup>
<Card title="بحاجة إلى مساعدة؟" icon="headset" href="mailto:support@crewai.com">
تواصل مع فريق الدعم للحصول على المساعدة في تهيئة تكامل Databricks أو في حل المشكلات.
</Card>

View File

@@ -17,15 +17,62 @@ mode: "wide"
- حساب Salesforce بالصلاحيات المناسبة
- ربط حساب Salesforce الخاص بك عبر [صفحة التكاملات](https://app.crewai.com/integrations)
<Note>
يتطلب Salesforce **تثبيتًا واحدًا يقوم به مسؤول النظام (admin)** لحزمة
CrewAI في مؤسستك قبل أن يتمكن أي مستخدم من الاتصال. هذا متطلب من منصة
Salesforce لجميع التكاملات المعتمدة على ExternalClientApp اعتبارًا من
إصدار Spring '26 — وليس خطوة خاصة بـ CrewAI. تدليلك خطوة Connect
Salesforce في CrewAI AMP خلال هذه العملية عند المحاولة الأولى.
</Note>
## إعداد تكامل Salesforce
### 1. ربط حساب Salesforce الخاص بك
1. انتقل إلى [تكاملات CrewAI AMP](https://app.crewai.com/crewai_plus/connectors)
2. ابحث عن **Salesforce** في قسم تكاملات المصادقة
3. انقر على **Connect** وأكمل عملية OAuth
4. امنح الصلاحيات اللازمة لإدارة CRM والمبيعات
5. انسخ رمز المؤسسة من [إعدادات التكامل](https://app.crewai.com/crewai_plus/settings/integrations)
1. انتقل إلى [تكاملات CrewAI AMP](https://app.crewai.com/crewai_plus/unified_tools).
2. ابحث عن **Salesforce** في قسم تكاملات المصادقة.
3. انقر على **Connect**.
ما يحدث بعد ذلك يعتمد على ما إذا كان مسؤول Salesforce في مؤسستك قد ثبّت
حزمة CrewAI بالفعل:
- **الحزمة مثبتة بالفعل:** سيتم نقلك مباشرة إلى شاشة موافقة OAuth في
Salesforce — اعتمدها وسيكتمل الاتصال.
- **الحزمة غير مثبتة بعد:** سترى صفحة **Install CrewAI in Salesforce**.
اتبع خطوات التثبيت لمرة واحدة أدناه، ثم عُد إلى CrewAI AMP وانقر على
**Connect** مرة أخرى.
4. امنح الصلاحيات اللازمة لإدارة CRM والمبيعات.
5. انسخ رمز المؤسسة من [إعدادات التكامل](https://app.crewai.com/crewai_plus/settings/integrations).
#### تثبيت لمرة واحدة بواسطة المسؤول (مسؤول Salesforce فقط)
عند أول نقرة على **Connect Salesforce** من أي مستخدم في مؤسستك، تقوم CrewAI
بإعادة توجيهك إلى صفحة تثبيت تُشير إلى حزمة CrewAI المُدارة. يحتاج مسؤول
Salesforce إلى تثبيتها مرة واحدة فقط لكامل المؤسسة.
1. في صفحة التثبيت داخل CrewAI، انقر على **Install in Salesforce**. (يمكنك
أيضًا مشاركة عنوان URL لتلك الصفحة مع المسؤول — رابط التثبيت يعمل لأي
شخص يفتحه.)
2. سجّل الدخول إلى Salesforce بصلاحيات مسؤول. لبيئات Sandbox، استبدل
`login.salesforce.com` بـ `test.salesforce.com` في الرابط قبل فتحه.
3. اختر **Install for All Users**، ووافق على إشعار تطبيقات الجهات
الخارجية، ثم انقر **Install**.
4. من Setup في Salesforce، ابحث عن **External Client App Manager** ←
**CrewAI App** ← افتح علامة التبويب **Policies** ← **Edit**، واضبط
القيم التالية:
- **Permitted Users:** All users may self-authorize
- **IP Relaxation:** Relax IP restrictions
- **Refresh Token Policy:** Refresh token is valid until revoked
5. احفظ التغييرات.
6. عُد إلى CrewAI AMP وانقر على **Connect Salesforce** مرة أخرى. سيكتمل
OAuth هذه المرة.
<Note>
**لست مسؤول Salesforce؟** أعِد توجيه عنوان URL لصفحة التثبيت (أو رابط
التثبيت نفسه) إلى مسؤول Salesforce لديكم واطلب منه إكمال الخطوات أعلاه.
بمجرد انتهائه، عُد إلى CrewAI AMP وانقر على **Connect** مرة أخرى.
</Note>
### 2. تثبيت الحزمة المطلوبة

View File

@@ -0,0 +1,134 @@
---
title: تكامل Snowflake
description: "ربط وكلاء CrewAI بـ Snowflake Cortex Analyst و Cortex Search وتنفيذ SQL من خلال خادم MCP المُدار من Snowflake."
icon: "snowflake"
mode: "wide"
---
## نظرة عامة
اربط وكلاء CrewAI مباشرة ببيانات Snowflake الخاصة بك من خلال [خادم MCP المُدار من Snowflake](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp). يتيح تكامل Snowflake لوكلائك الاستعلام عن البيانات المنظمة باستخدام **Cortex Analyst**، والبحث في البيانات غير المنظمة باستخدام **Cortex Search**، وتنفيذ SQL مُدار على مستودعات البيانات الخاصة بك — كل ذلك دون كتابة أو استضافة أي كود للموصّل.
داخلياً، تكامل Snowflake هو غلاف مُدار حول دعم [Custom MCP Server](/ar/enterprise/guides/custom-mcp-server) في CrewAI. يكشف Snowflake عن قدرات Cortex AI الخاصة به من خلال نقطة نهاية [Model Context Protocol](https://modelcontextprotocol.io/)، ويتصل CrewAI بها بشكل آمن نيابةً عنك. أي أداة تكشفها على جانب Snowflake — Cortex Analyst أو Cortex Search أو تنفيذ SQL أو Cortex Agents أو أدواتك المخصصة — تصبح متاحة لطواقمك.
## القدرات الرئيسية
<CardGroup cols={3}>
<Card title="Cortex Analyst" icon="chart-bar">
اطرح أسئلة بلغة طبيعية ودع [Cortex Analyst](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-analyst) يولّد وينفذ SQL على بياناتك **المنظمة** باستخدام نماذج دلالية غنية.
</Card>
<Card title="Cortex Search" icon="magnifying-glass">
استرجع البيانات **غير المنظمة** ذات الصلة لسير عمل RAG والمعرفة باستخدام [Cortex Search](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-search/cortex-search-overview)، خدمة البحث المُدارة بالكامل من Snowflake.
</Card>
<Card title="تنفيذ SQL" icon="database">
نفّذ استعلامات SQL مُدارة مباشرة على مستودعات Snowflake الخاصة بك، مع وضع القراءة فقط القابل للتكوين، والمهلات الزمنية، واختيار المستودع.
</Card>
</CardGroup>
نظراً لأن التكامل يكشف عن أي أدوات ينشرها خادم MCP الخاص بك، يمكنك أيضاً كشف **Cortex Agents** و**الأدوات المخصصة** (الدوال المعرّفة من المستخدم والإجراءات المخزّنة) لوكلاء CrewAI.
## المتطلبات الأساسية
قبل استخدام تكامل Snowflake، تأكد من توفر ما يلي:
- حساب [CrewAI AMP](https://app.crewai.com) مع اشتراك فعّال
- حساب Snowflake مع إمكانية الوصول إلى ميزات Cortex AI
- [خادم MCP مُدار من Snowflake](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp) مُكوّن بالأدوات التي تريد كشفها
- صلاحيات Snowflake المناسبة (USAGE/SELECT) على خادم MCP والكائنات الأساسية
## إعداد خادم Snowflake MCP
يعمل خادم MCP المُدار من Snowflake داخل حساب Snowflake الخاص بك ويحدد الأدوات المتاحة للعملاء الخارجيين مثل CrewAI. أنشئ واحداً باستخدام أمر [`CREATE MCP SERVER`](https://docs.snowflake.com/en/sql-reference/sql/create-mcp-server)، مع سرد خدمات Cortex Search وعروض Cortex Analyst الدلالية وأدوات SQL التي تريد كشفها.
```sql
CREATE MCP SERVER my_mcp_server
FROM SPECIFICATION $$
tools:
- name: "sales_analyst"
type: "CORTEX_ANALYST"
identifier: "MY_DATABASE.MY_SCHEMA.sales_semantic_view"
description: "Answer questions about sales metrics"
- name: "docs_search"
type: "CORTEX_SEARCH_SERVICE_QUERY"
identifier: "MY_DATABASE.MY_SCHEMA.support_docs_search"
description: "Search internal support documentation"
- name: "run_sql"
type: "SQL_EXECUTION"
description: "Execute read-only SQL queries"
$$;
```
<Note>
تتبع نقطة نهاية MCP التنسيق `https://<account_URL>/api/v2/databases/{database}/schemas/{schema}/mcp-servers/{name}`. يبني CrewAI هذا العنوان تلقائياً من **عنوان URL للحساب** و**قاعدة البيانات** و**المخطط** و**اسم خادم MCP** الذي تقدمه عند تكوين التكامل.
</Note>
للمواصفات الكاملة — بما في ذلك Cortex Agents والأدوات المخصصة وحدود حجم الاستجابة وخيارات الحوكمة — راجع [وثائق خادم MCP المُدار من Snowflake](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp).
## ربط Snowflake في CrewAI AMP
<Frame>
<img src="/images/enterprise/snowflake-configure.png" alt="تكوين تكامل Snowflake في CrewAI AMP" />
</Frame>
<Steps>
<Step title="فتح الأدوات والتكاملات">
انتقل إلى **الأدوات والتكاملات** في الشريط الجانبي الأيسر لـ CrewAI AMP، وابحث عن **Snowflake** في قائمة التطبيقات، وافتح لوحة التكوين الخاصة به.
</Step>
<Step title="تقديم تفاصيل الاتصال">
املأ حقول الاتصال التي يستخدمها CrewAI للوصول إلى خادم Snowflake MCP الخاص بك:
| الحقل | مطلوب | الوصف |
|-------|-------|-------|
| **الاسم** | نعم | اسم وصفي لهذا الاتصال (القيمة الافتراضية `Snowflake`). |
| **الوصف** | لا | ملخص اختياري لما يوفره هذا الاتصال. |
| **عنوان URL للحساب** | نعم | عنوان URL لحساب Snowflake الخاص بك، مثل `xy12345.us-east-1.snowflakecomputing.com`. |
| **قاعدة البيانات** | نعم | قاعدة البيانات التي تحتوي على خادم MCP الخاص بك (مثل `MY_DATABASE`). |
| **المخطط** | نعم | المخطط الذي يحتوي على خادم MCP الخاص بك (مثل `MY_SCHEMA`). |
| **اسم خادم MCP** | نعم | اسم كائن خادم MCP الذي أنشأته في Snowflake (مثل `MY_MCP_SERVER`). |
</Step>
<Step title="اختيار طريقة المصادقة">
اختر كيفية مصادقة CrewAI مع Snowflake. يُوصى باستخدام **OAuth**.
- **استخدام OAuth** — اتصل بشكل آمن باستخدام OAuth 2.0 للمصادقة القائمة على الرموز دون مشاركة بيانات الاعتماد الخاصة بك. يتعامل CrewAI مع تدفق التفويض الكامل ويجدد الرموز تلقائياً. انسخ **عنوان URI لإعادة التوجيه** المعروض في النموذج (`https://oauth.crewai.com/oauth/add`) وسجّله كعنوان URI لإعادة التوجيه المعتمد في [تكامل أمان OAuth](https://docs.snowflake.com/en/user-guide/oauth-custom) في Snowflake.
- **استخدام رمز وصول شخصي** — المصادقة باستخدام [رمز وصول برمجي](https://docs.snowflake.com/en/user-guide/programmatic-access-tokens) مُنشأ من إعدادات حساب Snowflake الخاص بك. قم بتعيين دور بأقل صلاحيات للرمز للحد من التعرض.
</Step>
<Step title="المصادقة">
انقر على **المصادقة**. بالنسبة لـ OAuth، ستتم إعادة توجيهك إلى Snowflake لتفويض الوصول. بمجرد المصادقة، يظهر خادم Snowflake في قائمة الاتصالات وتصبح أدواته متاحة لطواقمك.
</Step>
</Steps>
<Tip>
مع OAuth، يتم مصادقة كل مستخدم بشكل فردي وتُنفّذ الاستعلامات بدور `DEFAULT_ROLE` الخاص به في Snowflake. تأكد من أن المستخدمين المتصلين لديهم دور ومستودع افتراضي محدد (`ALTER USER <username> SET DEFAULT_ROLE = '<role>' DEFAULT_WAREHOUSE = '<warehouse>'`) حتى تتوفر موارد الحوسبة لأدوات Cortex Analyst و SQL.
</Tip>
## استخدام أدوات Snowflake في طواقمك
بمجرد الاتصال، تظهر الأدوات التي يكشفها خادم MCP الخاص بك إلى جانب الاتصالات المدمجة في صفحة **الأدوات والتكاملات**. يمكنك:
- **تعيين الأدوات للوكلاء** في طواقمك تماماً مثل أي أداة CrewAI أخرى.
- **إدارة الرؤية** للتحكم في أعضاء الفريق الذين يمكنهم استخدام الاتصال.
- **تعديل أو إزالة** الاتصال في أي وقت من قائمة الاتصالات.
يمكن لوكلائك الآن سؤال Cortex Analyst عن المقاييس، وتشغيل Cortex Search على مستنداتك، وتنفيذ SQL — مع تدفق النتائج تلقائياً إلى استدلالهم.
<Warning>
يفرض Snowflake الحوكمة على خادم MCP: يحدد التحكم في الوصول القائم على الأدوار الأدوات التي يمكن للمستخدم اكتشافها واستدعاؤها، وتنطبق حدود على حجم الاستجابة وعدد الأدوات (بحد أقصى 50 لكل خادم) وعمق التكرار. إذا فشل استدعاء أداة، تأكد من أن دور المستخدم المتصل لديه الصلاحيات المطلوبة على خادم MCP والكائنات الأساسية.
</Warning>
## معرفة المزيد
<CardGroup cols={2}>
<Card title="خادم MCP المُدار من Snowflake" icon="snowflake" href="https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp">
الوثائق الرسمية من Snowflake لإنشاء وإدارة خادم MCP.
</Card>
<Card title="خوادم Custom MCP في CrewAI" icon="plug" href="/ar/enterprise/guides/custom-mcp-server">
تعرّف على كيفية اتصال CrewAI بأي خادم MCP، الأساس الذي يبني عليه تكامل Snowflake.
</Card>
</CardGroup>
<Card title="تحتاج مساعدة؟" icon="headset" href="mailto:support@crewai.com">
تواصل مع فريق الدعم للحصول على المساعدة في تكامل Snowflake أو استكشاف الأخطاء وإصلاحها.
</Card>

View File

@@ -161,6 +161,18 @@ crew = Crew(
)
```
<Note>
يُحتفظ بـ `agent.i18n` للتوافق مع الإصدارات السابقة فقط، وقد تم إهماله. لتخصيص المطالبات أثناء التشغيل، مرّر `prompt_file` إلى `Crew`. وللوصول البرمجي المباشر إلى شرائح المطالبات، استخدم أداة i18n مباشرة:
</Note>
```python
from crewai.utilities.i18n import get_i18n
i18n = get_i18n("custom_prompts.json")
format_slice = i18n.slice("format")
tool_prompt = i18n.tools("ask_question")
```
#### الخيار 3: تعطيل مطالبات النظام لنماذج o1
```python
agent = Agent(
@@ -208,6 +220,8 @@ agent = Agent(
يدمج CrewAI بعد ذلك تخصيصاتك مع الإعدادات الافتراضية، فلا تحتاج لإعادة تعريف كل مطالبة. إليك الطريقة:
بالنسبة للكود الذي يحتاج إلى قراءة شرائح المطالبات مباشرة، استخدم `crewai.utilities.i18n.get_i18n()` مع ملف المطالبات نفسه بدلًا من قراءة `agent.i18n`.
### مثال: تخصيص أساسي للمطالبات
أنشئ ملف `custom_prompts.json` بالمطالبات التي تريد تعديلها. تأكد من إدراج جميع المطالبات عالية المستوى التي يجب أن يحتويها، وليس فقط تغييراتك:

View File

@@ -43,7 +43,7 @@ CrewAI مُصمَّم أصلاً للعمل مع الذكاء الاصطناعي
| المهارة | متى تُستخدم |
|---------|-------------|
| `getting-started` | مشاريع جديدة، الاختيار بين `LLM.call()` / `Agent` / `Crew` / `Flow`، ربط `crew.py` / `main.py` |
| `getting-started` | مشاريع جديدة، الاختيار بين `LLM.call()` / `Agent` / `Crew` / `Flow`، ربط `crew.jsonc` / `main.py` |
| `design-agent` | ضبط الوكلاء — الدور، الهدف، الخلفية، الأدوات، نماذج اللغة، الذاكرة، الحدود الآمنة |
| `design-task` | وصف المهام، التبعيات، المخرجات المنظمة (`output_pydantic`، `output_json`)، المراجعة البشرية |
| `ask-docs` | الاستعلام من [خادم CrewAI docs MCP](https://docs.crewai.com/mcp) للحصول على تفاصيل واجهة البرمجة الحالية |
@@ -64,7 +64,7 @@ CrewAI مُصمَّم أصلاً للعمل مع الذكاء الاصطناعي
<Step title="يحصل وكيلك فوراً على خبرة CrewAI">
تعلّم الحزمة وكيلك:
- **Flows** — تطبيقات ذات حالة، خطوات، وتشغيل crews
- **Crews والوكلاء** — أنماط YAML أولاً، الأدوار، المهام، التفويض
- **Crews والوكلاء** — أنماط JSON-first (`crew.jsonc` و `agents/*.jsonc`)، الأدوار، المهام، التفويض
- **الأدوات والتكاملات** — البحث، واجهات API، خوادم MCP، وأدوات CrewAI الشائعة
- **هيكل المشروع** — هياكل CLI واتفاقيات المستودع
- **أنماط محدثة** — يتماشى مع وثائق CrewAI الحالية وأفضل الممارسات

View File

@@ -1,321 +1,140 @@
---
title: ابنِ أول Crew لك
description: دليل تفصيلي لإنشاء فريق AI تعاوني يعمل معًا لحل المشكلات المعقدة.
title: ابنِ أول Crew
description: دليل خطوة بخطوة لإنشاء فريق AI تعاوني باستخدام تهيئة JSON-first.
icon: users-gear
mode: "wide"
---
## إطلاق قوة الذكاء الاصطناعي التعاوني
## بناء Crew للبحث
تخيل أن لديك فريقًا من Agents الذكاء الاصطناعي المتخصصة تعمل معًا بسلاسة لحل مشكلات معقدة، كل منها يساهم بمهاراته الفريدة لتحقيق هدف مشترك. هذه هي قوة CrewAI - إطار عمل يمكّنك من إنشاء أنظمة ذكاء اصطناعي تعاونية يمكنها إنجاز مهام تفوق بكثير ما يمكن لـ AI واحد تحقيقه بمفرده.
في هذا الدليل ستنشئ crew من Agentين: واحد للبحث وآخر لكتابة تقرير markdown. مشاريع الـ crew الجديدة هي JSON-first: تُعرّف الـ Agents في `agents/*.jsonc`، وتُعرّف المهام وإعدادات الـ crew في `crew.jsonc`، ويحمّل `crewai run` هذا التعريف مباشرة.
في هذا الدليل، سنمشي عبر إنشاء Crew بحث يساعدنا في البحث والتحليل حول موضوع ما، ثم إنشاء تقرير شامل. يوضح هذا المثال العملي كيف يمكن لـ Agents الذكاء الاصطناعي التعاون لإنجاز مهام معقدة، لكنه مجرد البداية لما هو ممكن مع CrewAI.
### المتطلبات
### ما ستبنيه وتتعلمه
1. تثبيت CrewAI من [دليل التثبيت](/ar/installation)
2. إعداد مفتاح LLM من [دليل LLMs](/ar/concepts/llms#setting-up-your-llm)
3. مفتاح [Serper.dev](https://serper.dev/) إذا أردت استخدام البحث على الويب
بنهاية هذا الدليل، ستكون قد:
1. **أنشأت فريق بحث AI متخصص** بأدوار ومسؤوليات مميزة
2. **نسّقت التعاون** بين عدة Agents ذكاء اصطناعي
3. **أتممت سير عمل معقد** يتضمن جمع المعلومات والتحليل وإنشاء التقارير
4. **بنيت مهارات أساسية** يمكنك تطبيقها على مشاريع أكثر طموحًا
### المتطلبات المسبقة
قبل البدء، تأكد من:
1. تثبيت CrewAI باتباع [دليل التثبيت](/ar/installation)
2. إعداد مفتاح API لنموذج LLM في بيئتك، باتباع [دليل إعداد LLM](/ar/concepts/llms#setting-up-your-llm)
3. فهم أساسي لـ Python
## الخطوة 1: إنشاء مشروع CrewAI جديد
أولاً، لننشئ مشروع CrewAI جديد باستخدام CLI. سينشئ هذا الأمر هيكل مشروع كامل بجميع الملفات الضرورية.
## الخطوة 1: إنشاء Crew جديدة
```bash
crewai create crew research_crew
cd research_crew
```
سينتج هيكل مشروع بالبنية الأساسية المطلوبة لـ Crew. ينشئ CLI تلقائيًا:
البنية الناتجة:
- مجلد مشروع بالملفات اللازمة
- ملفات تهيئة للـ Agents والمهام
- تطبيق Crew أساسي
- سكريبت رئيسي لتشغيل الـ Crew
<Frame caption="نظرة عامة على إطار عمل CrewAI">
<img src="/images/crews.png" alt="نظرة عامة على إطار عمل CrewAI" />
</Frame>
## الخطوة 2: استكشاف هيكل المشروع
لنخصص لحظة لفهم هيكل المشروع الذي أنشأه CLI.
```
```text
research_crew/
├── .gitignore
├── .env
├── agents/
│ └── researcher.jsonc
├── crew.jsonc
├── knowledge/
├── pyproject.toml
├── README.md
├── .env
└── src/
└── research_crew/
├── __init__.py
├── main.py
├── crew.py
├── tools/
│ ├── custom_tool.py
│ └── __init__.py
└── config/
├── agents.yaml
└── tasks.yaml
├── skills/
└── tools/
```
يتبع هذا الهيكل أفضل الممارسات لمشاريع Python ويسهّل تنظيم الكود. فصل ملفات التهيئة (YAML) عن كود التنفيذ (Python) يسهّل تعديل سلوك Crew دون تغيير الكود الأساسي.
<Tip>
إذا احتجت إلى البنية القديمة التي تحتوي على `crew.py` و `config/agents.yaml` و `config/tasks.yaml`، استخدم `crewai create crew research_crew --classic`.
</Tip>
## الخطوة 3: تهيئة الـ Agents
## الخطوة 2: تعريف الـ Agents
الآن يأتي الجزء الممتع - تعريف Agents الذكاء الاصطناعي! في CrewAI، الـ Agents هي كيانات متخصصة بأدوار وأهداف وخلفيات محددة تشكّل سلوكها.
عدّل ملف `agents/researcher.jsonc` الذي أنشأه القالب، ثم أضف `agents/analyst.jsonc`. يجب أن تطابق أسماء الملفات الأسماء المشار إليها في `crew.jsonc`.
لـ Crew البحث لدينا، سننشئ Agent اثنين:
1. **باحث** يتفوق في إيجاد وتنظيم المعلومات
2. **محلل** يمكنه تفسير نتائج البحث وإنشاء تقارير ثاقبة
لنعدّل ملف `agents.yaml`. تأكد من تعيين `llm` للمزود الذي تستخدمه.
```yaml
# src/research_crew/config/agents.yaml
researcher:
role: >
Senior Research Specialist for {topic}
goal: >
Find comprehensive and accurate information about {topic}
with a focus on recent developments and key insights
backstory: >
You are an experienced research specialist with a talent for
finding relevant information from various sources. You excel at
organizing information in a clear and structured manner, making
complex topics accessible to others.
llm: provider/model-id # e.g. openai/gpt-4o, google/gemini-2.0-flash, anthropic/claude...
analyst:
role: >
Data Analyst and Report Writer for {topic}
goal: >
Analyze research findings and create a comprehensive, well-structured
report that presents insights in a clear and engaging way
backstory: >
You are a skilled analyst with a background in data interpretation
and technical writing. You have a talent for identifying patterns
and extracting meaningful insights from research data, then
communicating those insights effectively through well-crafted reports.
llm: provider/model-id # e.g. openai/gpt-4o, google/gemini-2.0-flash, anthropic/claude...
```jsonc agents/researcher.jsonc
{
"role": "Senior Research Specialist for {topic}",
"goal": "Find comprehensive and accurate information about {topic}, with a focus on recent developments and key insights.",
"backstory": "You are an experienced research specialist who organizes complex information into clear, useful notes.",
// استبدله بالنموذج الذي تستخدمه، مثل "openai/gpt-4o".
"llm": "provider/model-id",
"tools": ["SerperDevTool"],
"settings": {
"verbose": true,
"allow_delegation": false
}
}
```
لاحظ كيف أن لكل Agent دور وهدف وخلفية مميزة. هذه العناصر ليست وصفية فحسب - بل تشكّل بنشاط كيف يتعامل الـ Agent مع مهامه.
## الخطوة 4: تعريف المهام
مع تعريف الـ Agents، نحتاج الآن لمنحهم مهام محددة. لنعدّل ملف `tasks.yaml`:
```yaml
# src/research_crew/config/tasks.yaml
research_task:
description: >
Conduct thorough research on {topic}. Focus on:
1. Key concepts and definitions
2. Historical development and recent trends
3. Major challenges and opportunities
4. Notable applications or case studies
5. Future outlook and potential developments
Make sure to organize your findings in a structured format with clear sections.
expected_output: >
A comprehensive research document with well-organized sections covering
all the requested aspects of {topic}. Include specific facts, figures,
and examples where relevant.
agent: researcher
analysis_task:
description: >
Analyze the research findings and create a comprehensive report on {topic}.
Your report should:
1. Begin with an executive summary
2. Include all key information from the research
3. Provide insightful analysis of trends and patterns
4. Offer recommendations or future considerations
5. Be formatted in a professional, easy-to-read style with clear headings
expected_output: >
A polished, professional report on {topic} that presents the research
findings with added analysis and insights. The report should be well-structured
with an executive summary, main sections, and conclusion.
agent: analyst
context:
- research_task
output_file: output/report.md
```jsonc agents/analyst.jsonc
{
"role": "Report Analyst for {topic}",
"goal": "Turn research findings into a clear, well-structured report.",
"backstory": "You are a careful analyst with strong technical writing skills and a talent for extracting useful insights.",
// استبدله بالنموذج الذي تستخدمه، مثل "openai/gpt-4o".
"llm": "provider/model-id",
"settings": {
"verbose": true,
"allow_delegation": false
}
}
```
لاحظ حقل `context` في مهمة التحليل - هذه ميزة قوية تتيح للمحلل الوصول إلى مخرجات مهمة البحث.
استبدل `provider/model-id` بالنموذج الذي تستخدمه، مثل `openai/gpt-4o` أو `anthropic/claude-sonnet-4-6` أو `gemini/gemini-2.0-flash-001`.
## الخطوة 5: تهيئة الـ Crew
## الخطوة 3: تعريف المهام وإعدادات الـ Crew
الآن حان الوقت لجمع كل شيء معًا. لنعدّل ملف `crew.py`:
استبدل `crew.jsonc` بما يلي:
```python
# src/research_crew/crew.py
from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task
from crewai_tools import SerperDevTool
from crewai.agents.agent_builder.base_agent import BaseAgent
from typing import List
@CrewBase
class ResearchCrew():
"""Research crew for comprehensive topic analysis and reporting"""
agents: List[BaseAgent]
tasks: List[Task]
@agent
def researcher(self) -> Agent:
return Agent(
config=self.agents_config['researcher'], # type: ignore[index]
verbose=True,
tools=[SerperDevTool()]
)
@agent
def analyst(self) -> Agent:
return Agent(
config=self.agents_config['analyst'], # type: ignore[index]
verbose=True
)
@task
def research_task(self) -> Task:
return Task(
config=self.tasks_config['research_task'] # type: ignore[index]
)
@task
def analysis_task(self) -> Task:
return Task(
config=self.tasks_config['analysis_task'], # type: ignore[index]
output_file='output/report.md'
)
@crew
def crew(self) -> Crew:
"""Creates the research crew"""
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True,
)
```
## الخطوة 6: إعداد السكريبت الرئيسي
```python
#!/usr/bin/env python
# src/research_crew/main.py
import os
from research_crew.crew import ResearchCrew
# Create output directory if it doesn't exist
os.makedirs('output', exist_ok=True)
def run():
"""
Run the research crew.
"""
inputs = {
'topic': 'Artificial Intelligence in Healthcare'
```jsonc crew.jsonc
{
"name": "Research Crew",
"agents": ["researcher", "analyst"],
"tasks": [
{
"name": "research_task",
"description": "Conduct thorough research on {topic}. Focus on key concepts, recent developments, major challenges, notable applications, and future outlook.",
"expected_output": "A comprehensive research document with organized sections, specific facts, and useful examples about {topic}.",
"agent": "researcher"
},
{
"name": "analysis_task",
"description": "Analyze the research findings and create a polished report on {topic}. Include an executive summary, key insights, trend analysis, and recommendations.",
"expected_output": "A professional markdown report with clear headings, a concise summary, main findings, and recommendations.",
"agent": "analyst",
"context": ["research_task"],
"output_file": "output/report.md",
"markdown": true
}
# Create and run the crew
result = ResearchCrew().crew().kickoff(inputs=inputs)
# Print the result
print("\n\n=== FINAL REPORT ===\n\n")
print(result.raw)
print("\n\nReport has been saved to output/report.md")
if __name__ == "__main__":
run()
],
"process": "sequential",
"verbose": true,
"memory": true,
"inputs": {
"topic": "Artificial Intelligence in Healthcare"
}
}
```
## الخطوة 7: إعداد متغيرات البيئة
يشير `context` إلى أسماء مهام سابقة، لذلك يحصل analyst على مخرجات مهمة البحث. يوفر `inputs` قيمة افتراضية لـ `{topic}`. إذا حذفت القيمة الافتراضية، سيطلبها `crewai run`.
أنشئ ملف `.env` في جذر مشروعك بمفاتيح API:
## الخطوة 4: متغيرات البيئة
عدّل `.env`:
```sh
SERPER_API_KEY=your_serper_api_key
# Add your provider's API key here too.
# أضف مفتاح مزود النموذج أيضًا.
```
راجع [دليل إعداد LLM](/ar/concepts/llms#setting-up-your-llm) لتفاصيل تهيئة المزود المفضل لديك. يمكنك الحصول على مفتاح Serper API من [Serper.dev](https://serper.dev/).
## الخطوة 8: تثبيت التبعيات
## الخطوة 5: التثبيت والتشغيل
```bash
crewai install
```
## الخطوة 9: تشغيل الـ Crew
الآن اللحظة المثيرة - حان وقت تشغيل Crew ومشاهدة التعاون بين الـ AI!
```bash
crewai run
```
عند تشغيل هذا الأمر، سترى Crew يعمل. سيجمع الباحث معلومات حول الموضوع المحدد، ثم سينشئ المحلل تقريرًا شاملاً بناءً على ذلك البحث.
بعد انتهاء التشغيل، افتح `output/report.md`.
## الخطوة 10: مراجعة المخرجات
بمجرد إتمام Crew عمله، ستجد التقرير النهائي في ملف `output/report.md`. سيتضمن التقرير:
1. ملخص تنفيذي
2. معلومات مفصلة عن الموضوع
3. تحليل ورؤى
4. توصيات أو اعتبارات مستقبلية
## استكشاف أوامر CLI الأخرى
يوفر CrewAI عدة أوامر CLI مفيدة للعمل مع Crews:
```bash
# View all available commands
crewai --help
# Run the crew
crewai run
# Test the crew
crewai test
# Reset crew memories
crewai reset-memories
# Replay from a specific task
crewai replay -t <task_id>
```
## ما بعد أول Crew: فن الممكن
ما بنيته في هذا الدليل مجرد البداية. يمكنك توسيع Crew البحث الأساسي بإضافة Agents متخصصة أخرى وأدوات وقدرات إضافية وسير عمل أكثر تعقيدًا. يمكن تطبيق نفس الأنماط لإنشاء Crews لإنشاء المحتوى وخدمة العملاء وتطوير المنتجات وتحليل البيانات.
## الخطوات التالية
1. جرّب تهيئات وشخصيات Agent مختلفة
2. جرب هياكل مهام وسير عمل أكثر تعقيدًا
3. طبّق أدوات مخصصة لمنح الـ Agents قدرات جديدة
4. طبّق Crew على مواضيع أو مجالات مشكلات مختلفة
5. استكشف [CrewAI Flows](/ar/guides/flows/first-flow) لسير عمل أكثر تقدمًا مع البرمجة الإجرائية
<Warning>
شغّل مشاريع JSON crew من مصادر تثق بها فقط. أدوات `custom:<name>` ومراجع `{"python": "module.attribute"}` تنفذ Python محليًا عند تحميل الـ crew.
</Warning>
<Check>
تهانينا! لقد بنيت بنجاح أول CrewAI Crew يمكنه البحث والتحليل في أي موضوع تقدمه. هذه التجربة الأساسية أهّلتك بالمهارات لإنشاء أنظمة AI متطورة بشكل متزايد يمكنها معالجة مشكلات معقدة متعددة المراحل من خلال الذكاء التعاوني.
أصبحت لديك crew تعمل بأسلوب JSON-first تبحث في موضوع وتكتب تقريرًا.
</Check>

View File

@@ -0,0 +1,473 @@
---
title: تدفقات المحادثة
description: أنشئ تطبيقات دردشة متعددة الجولات مع kickoff لكل جولة وسجل الرسائل وتوجيه النية والتتبع وجسور WebSocket.
icon: comments
mode: "wide"
---
## نظرة عامة
تعامل التطبيقات المحادثية مع كل سطر من المستخدم كـ **تشغيل flow جديد** بنفس **معرّف الجلسة**. توفر CrewAI مساعدات لسجل الرسائل وتصنيف النية الاختياري وتأجيل التتبع وجسور الواجهة، إضافة إلى REPL محلي `flow.chat()` للتدفقات المحادثية.
| المفهوم | التنفيذ |
|---------|---------|
| معرّف الجلسة | `handle_turn(..., session_id=...)` → `kickoff(inputs={"id": ...})` → `state.id` |
| سطر المستخدم | `handle_turn(message)` يضيف الرسالة إلى `state.messages` قبل تشغيل الرسم |
| اكتمال الجولة | `FlowFinished` لهذا **التشغيل** فقط؛ تستمر المحادثة في `handle_turn` التالي |
| تتبع الجلسة | `ConversationConfig(defer_trace_finalization=True)` + `finalize_session_traces()` |
## واجهات الجولات
استخدم **`flow.handle_turn(message, session_id=...)`** لكل رسالة مستخدم من REST أو WebSocket أو الاختبارات أو الواجهات المخصصة. استخدم **`flow.chat()`** عندما تريد حلقة دردشة محلية في الطرفية لـ `Flow` محادثي.
لا يقبل `Flow.kickoff()` الوسيطين `user_message=` أو `session_id=`. في التدفقات المحادثية، يخزن `handle_turn()` الرسالة المعلقة ويستدعي داخلياً `kickoff(inputs={"id": session_id})`.
| API | الاستخدام |
|-----|-----------|
| `handle_turn(message, session_id=...)` | غلاف مريح لجولة واحدة في `Flow` محادثي |
| `chat()` | REPL محلي في الطرفية لـ `Flow` محادثي |
| `kickoff(inputs={...})` | تشغيل متقدم للـ flow بدون معالجة جولة محادثية |
| `ask()` | مطالبة حاجزة **داخل** خطوة واحدة |
| `@human_feedback` | الموافقة/الرفض على **مخرجات خطوة** — وليس السطر التالي |
| `ChatSession.handle_turn(...)` | طبقة نقل فوق `handle_turn` |
## بداية سريعة
```python
from uuid import uuid4
from crewai import Flow
from crewai.flow import listen
from crewai.experimental.conversational import (
ConversationConfig,
ConversationState,
)
@ConversationConfig(defer_trace_finalization=True)
class SupportFlow(Flow[ConversationState]):
conversational = True
def route_turn(self, context):
message = (self.state.current_user_message or "").lower()
if "طلب" in message or "order" in message:
return "order"
if "وداع" in message or "goodbye" in message:
return "goodbye"
return "help"
@listen("order")
def handle_order(self):
reply = "طلبك في الطريق."
self.append_assistant_message(reply)
return reply
@listen("help")
def handle_help(self):
reply = "كيف يمكنني المساعدة؟"
self.append_assistant_message(reply)
return reply
@listen("goodbye")
def handle_goodbye(self):
reply = "وداعاً!"
self.append_assistant_message(reply)
return reply
session_id = str(uuid4())
flow = SupportFlow()
try:
flow.handle_turn("أين طلبي؟", session_id=session_id)
flow.handle_turn("وماذا عن الإرجاع؟", session_id=session_id)
finally:
flow.finalize_session_traces()
```
## دورة حياة الجولة
كل `handle_turn` يشغّل:
1. **`_configure_conversational_kickoff`** — دمج `session_id` / `user_message` في `inputs` وتطبيق `ConversationalConfig`.
2. **استعادة الحالة** — عند وجود `inputs["id"]` و`@persist`.
3. **`FlowStarted`** — في أول جولة للجلسة المؤجلة فقط.
4. **`prepare_conversational_turn`** — إضافة رسالة المستخدم و`last_user_message` وتصنيف اختياري.
5. **تنفيذ الرسم** — `@start` → `@router` → معالجات `@listen`.
6. **نهاية التشغيل** — يُتخطى `flow_finished` والتتبع لكل جولة عند التأجيل؛ `Agent.kickoff()` / crews لا تغلق دفعة الأب.
استدعِ **`append_assistant_message(reply)`** في المعالجات. سطر المستخدم محفوظ عبر `handle_turn` — لا تُضفه مرة أخرى.
## `ConversationalConfig` (افتراضيات على مستوى الصنف)
عيّن على صنف `Flow` كـ `conversational_config: ClassVar[ConversationalConfig | None]`.
| الحقل | الافتراضي | الغرض |
|-------|-----------|--------|
| `default_intents` | `None` | تسميات outcome للتصنيف التلقائي قبل kickoff |
| `intent_llm` | `None` | نموذج التصنيف (مطلوب عند وجود intents) |
| `interactive_prompt` | `"You: "` | مطالبة `kickoff(interactive=True)` |
| `interactive_timeout` | `None` | مهلة لكل سطر في الوضع التفاعلي |
| `exit_commands` | `exit`, `quit` | كلمات إنهاء الوضع التفاعلي |
| `defer_trace_finalization` | `True` | إبقاء دفعة trace واحدة مفتوحة بين الجولات |
يمكن التجاوز لكل kickoff عبر `intents=` و`intent_llm=`.
## `ChatState` (شكل الحالة الموصى به للحفظ)
```python
from crewai.flow import ChatState
class MyChatState(ChatState):
# موروث: id, messages, last_user_message, last_intent, session_ready
research_turn_count: int = 0
custom_flag: bool = False
```
| الحقل | الدور |
|-------|------|
| `id` | UUID الجلسة (مثل `session_id` / `inputs["id"]`) |
| `messages` | قائمة `{role, content}` لسجل LLM |
| `last_user_message` | آخر سطر مستخدم في هذه الجولة |
| `last_intent` | تسمية المسار بعد التصنيف (إن وُجد) |
| `session_ready` | علم bootstrap لمرة واحدة |
`ConversationalInputs` هو `TypedDict` لـ `kickoff(inputs={...})`: `id`, `user_message`, `last_intent`.
## API المحادثة على `Flow`
### معاملات `kickoff` / `kickoff_async`
| المعامل | الغرض |
|---------|--------|
| `user_message` | نص هذه الجولة (أو `{"role": "user", "content": "..."}`) |
| `session_id` | UUID المحادثة → `inputs["id"]` / `state.id` |
| `intents` | تسميات outcome لـ `classify_intent` قبل kickoff |
| `intent_llm` | LLM للتصنيف (مطلوب مع `intents`) |
| `interactive` | حلقة CLI عبر `ask()` (للعروض المحلية فقط) |
| `interactive_prompt` | مطالبة الوضع التفاعلي |
| `interactive_timeout` | مهلة `ask()` لكل سطر |
| `exit_commands` | كلمات إنهاء الوضع التفاعلي |
| `inputs` | حقول حالة إضافية |
| `restore_from_state_id` | استنساخ من flow محفوظ آخر |
### سمات المثيل
| السمة | الغرض |
|-------|--------|
| `conversational_config` | افتراضيات `ConversationalConfig` على مستوى الصنف |
| `defer_trace_finalization` | علم المثيل؛ يُضبط تلقائياً من config عند kickoff |
| `suppress_flow_events` | يخفي لوحات console؛ **التتبع يُسجّل** |
| `stream` | بث؛ مع `ChatSession.handle_turn(..., stream=True)` |
### طرق وخصائص
| الاسم | الوصف |
|------|--------|
| `append_message(role, content, **extra)` | إضافة إلى `state.messages` |
| `conversation_messages` | سجل للقراءة فقط لاستدعاءات LLM |
| `classify_intent(text, outcomes, *, llm, context=None)` | تعيين outcome |
| `receive_user_message(text, *, outcomes=None, llm=None)` | إضافة رسالة مستخدم؛ `last_intent` اختياري |
| `finalize_session_traces()` | إصدار `flow_finished` المؤجل وإنهاء دفعة trace |
| `_should_defer_trace_finalization()` | هل يُؤجل إنهاء trace لكل جولة |
| `input_history` | سجل تدقيق مطالبات وردود `ask()` |
### مساعدات الوحدة (`crewai.flow.conversation`)
| الدالة | الوصف |
|--------|--------|
| `normalize_kickoff_inputs(...)` | دمج kwargs المحادثة في `inputs` |
| `get_conversation_messages(flow)` | قراءة الرسائل من الحالة أو المخزن |
| `append_message(flow, ...)` | مثل طريقة المثيل |
| `prepare_conversational_turn(flow, ...)` | تهيئة الجولة (عادةً kickoff يستدعيها) |
| `receive_user_message(flow, ...)` | مثل طريقة المثيل |
| `set_state_field(flow, name, value)` | تعيين حقل dict أو Pydantic |
| `get_conversational_config(flow)` | قراءة `conversational_config` |
| `input_history_to_messages(entries)` | تحويل `input_history` لصيغة رسائل LLM |
## أنماط توجيه النية
### أ. تصنيف مسبق عبر `ConversationalConfig` (الأبسط)
عيّن `default_intents` و`intent_llm`. كل kickoff يصنّف قبل `@router`؛ اقرأ `self.state.last_intent` في `route()`.
### ب. تصنيف داخل `@router` (مطالبات أغنى)
عيّن `default_intents=None` ليضيف kickoff الرسالة فقط. في `route()` استدعِ `classify_intent`:
```python
@router(bootstrap)
def route(self):
intent = self.classify_intent(
self._routing_prompt(self.state.last_user_message),
("GREETING", "ORDER", "RESEARCH", "GOODBYE"),
llm=self.conversational_config.intent_llm or "gpt-4o-mini",
)
self.state.last_intent = intent
return intent
```
للبحث على الويب أو أدوات متعددة الخطوات استخدم **`@listen("RESEARCH")`** مع `Agent.kickoff()` وأدوات — وليس `LLM.call()` فقط.
## عندما ينتهي الـ flow ويستمر المستخدم
`FlowFinished` يعني أن **تنفيذ الرسم هذا** اكتمل. تستمر المحادثة بـ `kickoff` آخر ونفس `session_id`. `@persist` يستعيد `messages` والأعلام والسياق.
**نمط الحفظ:** يُفضّل `@persist` على **خطوة نهائية واحدة** (مثل `finalize`) وليس على صنف `Flow` بالكامل. الحفظ على مستوى الصنف بعد كل method قد يفقد تحديثات المعالجات في نفس الجولة.
لا تستخدم `@human_feedback` لأسطر المتابعة في الدردشة إلا عند الحاجة لموافقة بشرية على مخرجات خطوة محددة.
## `Flow` المحادثاتي (تجريبي)
<Warning>
**ميزة تجريبية.** سطح `Flow` المحادثاتي (`conversational = True`،
`handle_turn`، `ConversationConfig`، `RouterConfig`،
`ConversationState`، الرسم البياني المدمج والمساعدات) يقع تحت
`crewai.experimental` وقد يتغير شكله قبل التخرج. ثبّت إصدار CrewAI إذا
كنت تعتمد على سلوك محدد، وراقب changelog للتحديثات الكاسرة. الملاحظات
والمشاكل مرحب بها.
</Warning>
فعّل الرسم المحادثاتي بتعيين `conversational = True` على صنف فرعي من `Flow`. عندئذٍ يُظهر `Flow` الأساسي رسم `@start` / `@router` / `converse_turn` / `end_conversation` مدمجاً، ويدير `state.messages`، ويُشغّل LLM التوجيه، ويبقي دفعة trace مفتوحة عبر الجولات. أنت تكتب **المسارات المخصصة** فقط؛ والإطار يتولى الباقي.
استخدمه عندما تريد دردشة متعددة الجولات مع موجّه قائم على LLM ومعالجات لكل مسار دون توصيل دورة الحياة يدوياً. استخدم `Flow[ChatState]` (النمط الأدنى مستوى في الأعلى) عندما تحتاج تحكماً كاملاً.
### مثال سريع
```python
from crewai import LLM, Flow
from crewai.flow import listen
from crewai.experimental.conversational import (
ConversationConfig,
ConversationState,
RouterConfig,
)
ROUTER_LLM = LLM(model="gpt-4o-mini")
@ConversationConfig(
system_prompt="A multi-agent assistant for ordinary chat and tool-backed tasks.",
llm=ROUTER_LLM,
router=RouterConfig(), # المسارات + الأوصاف تُكتشف تلقائياً من معالجات @listen
)
class SupportFlow(Flow[ConversationState]):
conversational = True
@listen("INTERNET_SEARCH")
def handle_internet_search(self) -> str:
"""Fresh web research, current news, real-time lookups."""
...
self.append_assistant_message(reply)
return reply
@listen("CREWAI_DOCS")
def handle_crewai_docs(self) -> str:
"""Look up the CrewAI documentation for framework/API questions."""
...
self.append_assistant_message(reply)
return reply
flow = SupportFlow()
try:
flow.handle_turn("ماذا يمكنك أن تفعل؟") # يوجَّه إلى converse (مدمج)
flow.handle_turn("ابحث في الويب عن أخبار الذكاء الاصطناعي.") # يوجَّه إلى INTERNET_SEARCH
flow.handle_turn("لخص النتيجة الأولى.") # يعود إلى converse
finally:
flow.finalize_session_traces()
```
للدردشة المحلية في الطرفية، استخدم `chat()`:
```python
def kickoff() -> None:
SupportFlow().chat()
```
يلف `chat()` استدعاءات `handle_turn()` داخل REPL، ويخرج عند `exit` / `quit`، ويتجاهل الأسطر الفارغة افتراضياً، ويستدعي `finalize_session_traces()` عند انتهاء الجلسة.
### `ConversationConfig`
مزخرف صنف يُلحق افتراضيات الدردشة على مستوى الصنف.
| الحقل | الافتراضي | الغرض |
|-------|-----------|-------|
| `system_prompt` | `slices.conversational_system_prompt` من i18n | رسالة system يستخدمها `converse_turn` المدمج. مرر `""` للتعطيل التام. |
| `llm` | `None` | LLM المحادثة (يستخدمه `converse_turn` وكاحتياطي للموجّه). |
| `router` | `None` | `RouterConfig` للتوجيه عبر LLM. بدونه، يسقط الـ flow دائماً إلى `converse`. |
| `answer_from_history_prompt` | افتراضي الإطار | رسالة system للمسار الاختياري `answer_from_history`. |
| `answer_from_history_llm` | `None` | يُفعّل الاختصار `answer_from_history` عند تعيينه. |
| `intent_llm` | `None` | LLM لمسار التصنيف المسبق القديم `intents=`/`default_intents`. |
| `default_intents` | `None` | تسميات النتائج للتصنيف المسبق القديم. |
| `visible_agent_outputs` | `None` | `"all"` أو قائمة بأسماء الـ agents الذين تُرفع مخرجاتهم من `append_agent_result()` إلى رسائل عامة. |
| `defer_trace_finalization` | `True` | يبقي دفعة trace واحدة مفتوحة عبر استدعاءات `handle_turn()`. |
### `RouterConfig` وفهرس المسارات المُولَّد تلقائياً
```python
RouterConfig(
prompt="تأطير اختياري للنطاق (سياسة، صوت، شخصية).",
response_format=MyRoute, # اختياري؛ يُولَّد تلقائياً عند الإغفال
llm=ROUTER_LLM, # يسقط إلى ConversationConfig.llm
routes=["INTERNET_SEARCH", "CREWAI_DOCS"], # اختياري؛ يُستنتج من المستمعين
route_descriptions={
"INTERNET_SEARCH": "تجاوز الـ docstring لهذا المسار فقط.",
},
default_intent="converse", # يُستخدم عند فشل LLM أو غيابه
fallback_intent="converse", # يُستخدم عندما يعيد LLM مساراً غير صالح
intent_field="intent",
)
```
تُبنى رسالة الموجّه إلى LLM تلقائياً. لكل مسار يختار الإطار وصفاً بهذا الترتيب من الأولوية:
1. `RouterConfig.route_descriptions[label]` — تجاوز صريح.
2. `Flow.builtin_route_descriptions[label]` — نص جاهز من الإطار لـ `converse` و`end` و`answer_from_history` (مصاغ لـ LLM التوجيه).
3. أول سطر غير فارغ من docstring معالج `@listen(label)`.
4. فارغ (المسار يظهر في الفهرس بلا وصف).
عملياً، **إضافة مسار جديد = `@listen("X")` + docstring من سطر واحد**:
```python
@listen("INTERNET_SEARCH")
def handle_internet_search(self) -> str:
"""Fresh web research, current news, real-time lookups."""
...
```
…وسيرى LLM التوجيه:
```
Routes:
- CREWAI_DOCS: Look up the CrewAI documentation for framework/API questions.
- INTERNET_SEARCH: Fresh web research, current news, real-time lookups.
- converse: Ordinary chat, follow-ups, summaries, clarifications…
- end: User signals the conversation is finished (goodbye, exit, done).
```
`RouterConfig.prompt` مخصص لـ **تأطير النطاق** (شخصية المساعد، قواعد العمل، النبرة). فهرس المسارات يُبنى تلقائياً — لا تُدرج المسارات في `prompt`؛ سيختل التزامن لحظة إضافة معالج جديد.
### المسارات المدمجة
| المسار | المعالج | الغرض |
|--------|---------|-------|
| `converse` | `converse_turn` | معالج الدردشة الافتراضي. يستدعي `ConversationConfig.llm` بـ system prompt + التاريخ القانوني للرسائل. |
| `end` | `end_conversation` | يضبط `state.ended = True` ويُصدر رد إنهاء. |
| `answer_from_history` | `answer_from_history_turn` | اختياري. يُوجَّه إليه عندما يكون `ConversationConfig.answer_from_history_llm` مُعيَّناً ويمكن الإجابة على الرسالة من التاريخ فقط. |
يمكنك تجاوز أي من هذه بتعريف معالج بنفس الاسم في الصنف الفرعي.
### دلالات `handle_turn()`
`flow.handle_turn(message)` يُشغّل جولة واحدة:
1. يعيد ضبط تعقّب التنفيذ لكل جولة (`_completed_methods`, `_method_outputs`) ليُعاد تشغيل الرسم — بدون ذلك، استدعاءات `kickoff` المتكررة على نفس النسخة ستُحدث دائرة قصر من الجولة الثانية لأن `Flow.kickoff_async` يعتبر `inputs={"id": ...}` استعادة من نقطة تفتيش.
2. يُلحق رسالة المستخدم بـ `state.messages` ويضبط `current_user_message` / `last_user_message`. يُحافَظ على `last_intent` **من الجولة السابقة** كي يستخدمها LLM التوجيه كإشارة.
3. يُشغّل `conversation_start` → `route_conversation` → معالج `@listen` المختار.
4. يخزّن الموجّه قراره في `state.last_intent` (يكون مرئياً لسياق التوجيه في الجولة التالية).
5. إذا أعاد معالجك سلسلة نصية ولم يستدعِ `append_assistant_message`، فإن `handle_turn` يُلحقها نيابةً عنك.
استدعِ `handle_turn()` لرسائل الدردشة. استدعاء `kickoff(inputs={"id": ...})` مباشرةً يشغل الرسم بدون غلاف الجولة المحادثية.
### `chat()` للـ REPL المحلي
`flow.chat()` هو غلاف الطرفية الجاهز فوق `handle_turn()`:
```python
flow = SupportFlow()
flow.chat()
```
يتولى الحلقة المحلية الشائعة:
1. يطلب رسالة من المستخدم.
2. يتوقف عند `exit` / `quit` أو `EOFError` أو `KeyboardInterrupt`.
3. يستدعي `handle_turn(message, session_id=...)`.
4. يطبع نتيجة المساعد.
5. ينهي traces الجلسة المؤجلة داخل كتلة `finally`.
خصص سلوك الطرفية عبر I/O قابل للحقن:
```python
flow.chat(
session_id="demo-session",
prompt="You: ",
assistant_prefix="Assistant: ",
exit_commands=("exit", "quit", "bye"),
)
```
لتطبيقات الويب والـ workers الخلفية والاختبارات ووسائط النقل المخصصة، استمر في استخدام `handle_turn()` مباشرةً.
### سلوك موجّه مخصص
لتشغيل آثار جانبية (إعداد ناقل أحداث، قياس عن بُعد) في كل قرار توجيه، تجاوز `route_turn`:
```python
class SupportFlow(Flow[ConversationState]):
conversational = True
def route_turn(self, context: dict[str, Any]) -> str | None:
self.event_bus = MyBus(self)
return super().route_turn(context)
```
لتجاوز موجّه LLM واختيار مسار برمجياً، أعد سلسلة نصية من `route_turn`؛ إعادة `None` تسقط إلى `_route_with_config(...)`.
### `append_assistant_message` و`append_agent_result`
داخل معالج `@listen(label)`، اختر:
- `self.append_assistant_message(text)` — يضيف جولة مساعد مرئية للمستخدم إلى `state.messages`. سيراها `converse_turn` في الجولة التالية.
- `self.append_agent_result(agent_name, result, visibility="private")` — يسجّل حدثاً منظماً في `state.events` وموضوعاً في `state.agent_threads[agent_name]`. الرؤية العامة تستدعي `append_assistant_message` أيضاً. استخدم النتائج الخاصة للعمل الجانبي الذي يجب ألا يلوث التاريخ القانوني.
يمكن لـ `ConversationConfig.visible_agent_outputs` رفع النتائج الخاصة لـ agents محددين إلى عامة عالمياً (`"all"` أو قائمة بالأسماء).
## التتبع عبر الجولات
مع `defer_trace_finalization=True` (افتراضي في `ConversationalConfig`):
- **دفعة trace واحدة** لجلسة الدردشة.
- **`flow_started`** في الجولة الأولى فقط؛ **`flow_finished`** مرة في `finalize_session_traces()`.
- **`kickoff` لكل جولة** لا يطبع "Trace batch finalized".
- **العمل المتداخل** (`Agent.kickoff()`, crews, Exa) يُلحق بدفعة **الأب**؛ flow داخلي من `AgentExecutor` لا يغلق دفعة الجلسة مبكراً.
```python
flow.chat(session_id=session_id)
```
`flow.chat()` يستدعي `finalize_session_traces()` نيابةً عنك. عندما تملك الحلقة عبر `handle_turn()` أو `kickoff(...)`، استدعِ `finalize_session_traces()` عند انتهاء الجلسة.
`suppress_flow_events=True` يخفي لوحات Rich فقط؛ أحداث trace والـ methods تُصدر.
### دورة حياة trace لـ `Flow` المحادثاتي
يستخدم [`Flow` المحادثاتي](#flow-المحادثاتي-تجريبي) التجريبي نفس دورة حياة tracing: `defer_trace_finalization` افتراضياً `True`، فيبقي كل `handle_turn()` أثر الجلسة مفتوحاً. أنهِ دوماً عند نهاية الجلسة — لُف حلقتك بـ `try/finally` واستدعِ `flow.finalize_session_traces()` عند الخروج. بدون ذلك، تبقى الدفعة مفتوحة وقد لا تُصدَّر آخر محادثة أبداً.
## البث
اضبط `stream = True` على صنف `Flow`. عندئذٍ يُصدر `kickoff(...)` أحداث `assistant_delta` (وما يرتبط بها) عبر ناقل الأحداث القياسي.
## الاستيراد
```python
from crewai.flow import (
ChatState,
ConversationalConfig,
ConversationalInputs,
Flow,
listen,
persist,
router,
start,
)
```
## مراجع
- [إتقان إدارة حالة Flow](/ar/guides/flows/mastering-flow-state)
- [أنشئ أول Flow](/ar/guides/flows/first-flow)
- Demo: `lib/crewai/runner_conversational_flow_simple.py` — REPL بسيط مع `RESEARCH` ووكيل Exa

View File

@@ -42,21 +42,26 @@ cd guide_creator_flow
## الخطوة 2: فهم هيكل المشروع
يستخدم الـ crew المبدئي المضمّن في مشروع Flow بنية Python/YAML الكلاسيكية. لاستخدام crew بنمط JSON-first داخل Flow، أنشئ `crew.jsonc` و `agents/*.jsonc` داخل مجلد الـ crew وحمّله عبر `crewai.project.load_crew` كما في [Flows](/ar/concepts/flows#building-your-crews).
```
guide_creator_flow/
├── .gitignore
├── pyproject.toml
├── README.md
├── .env
── main.py
├── crews/
── poem_crew/
├── config/
├── agents.yaml
│ └── tasks.yaml
── poem_crew.py
└── tools/
└── custom_tool.py
── src/
└── guide_creator_flow/
── __init__.py
├── main.py
├── crews/
│ └── poem_crew/
── config/
│ │ ├── agents.yaml
│ │ └── tasks.yaml
│ └── poem_crew.py
└── tools/
└── custom_tool.py
```
يوفر هذا الهيكل فصلاً واضحًا بين مكونات Flow المختلفة. سنعدّل هذا الهيكل لإنشاء Flow منشئ الدليل.
@@ -69,139 +74,77 @@ crewai flow add-crew content-crew
## الخطوة 4: تهيئة Crew كتابة المحتوى
1. حدّث ملف تهيئة الـ Agents. تذكر تعيين `llm` للمزود الذي تستخدمه.
سنهيئ crew كتابة المحتوى باستخدام JSONC. سنعرّف Agent للكتابة وAgent للمراجعة، ثم نحمّل `crew.jsonc` من خطوة Flow.
```yaml
# src/guide_creator_flow/crews/content_crew/config/agents.yaml
content_writer:
role: >
Educational Content Writer
goal: >
Create engaging, informative content that thoroughly explains the assigned topic
and provides valuable insights to the reader
backstory: >
You are a talented educational writer with expertise in creating clear, engaging
content. You have a gift for explaining complex concepts in accessible language
and organizing information in a way that helps readers build their understanding.
llm: provider/model-id
1. أنشئ `src/guide_creator_flow/crews/content_crew/agents/content_writer.jsonc`:
content_reviewer:
role: >
Educational Content Reviewer and Editor
goal: >
Ensure content is accurate, comprehensive, well-structured, and maintains
consistency with previously written sections
backstory: >
You are a meticulous editor with years of experience reviewing educational
content. You have an eye for detail, clarity, and coherence.
llm: provider/model-id
```jsonc
{
"role": "Educational Content Writer",
"goal": "Create engaging, informative content that thoroughly explains the assigned topic and provides valuable insights to the reader.",
"backstory": "You are a talented educational writer who explains complex concepts in accessible language and organizes information clearly.",
"llm": "provider/model-id",
"settings": {
"verbose": true
}
}
```
2. حدّث ملف تهيئة المهام:
2. أنشئ `src/guide_creator_flow/crews/content_crew/agents/content_reviewer.jsonc`:
```yaml
# src/guide_creator_flow/crews/content_crew/config/tasks.yaml
write_section_task:
description: >
Write a comprehensive section on the topic: "{section_title}"
Section description: {section_description}
Target audience: {audience_level} level learners
Your content should:
1. Begin with a brief introduction to the section topic
2. Explain all key concepts clearly with examples
3. Include practical applications or exercises where appropriate
4. End with a summary of key points
5. Be approximately 500-800 words in length
Format your content in Markdown with appropriate headings, lists, and emphasis.
Previously written sections:
{previous_sections}
expected_output: >
A well-structured, comprehensive section in Markdown format that thoroughly
explains the topic and is appropriate for the target audience.
agent: content_writer
review_section_task:
description: >
Review and improve the following section on "{section_title}":
{draft_content}
Target audience: {audience_level} level learners
Previously written sections:
{previous_sections}
Your review should:
1. Fix any grammatical or spelling errors
2. Improve clarity and readability
3. Ensure content is comprehensive and accurate
4. Verify consistency with previously written sections
5. Enhance the structure and flow
6. Add any missing key information
expected_output: >
An improved, polished version of the section that maintains the original
structure but enhances clarity, accuracy, and consistency.
agent: content_reviewer
context:
- write_section_task
```jsonc
{
"role": "Educational Content Reviewer and Editor",
"goal": "Ensure content is accurate, comprehensive, well-structured, and consistent with previously written sections.",
"backstory": "You are a meticulous editor with an eye for detail, clarity, and coherence.",
"llm": "provider/model-id",
"settings": {
"verbose": true
}
}
```
3. حدّث ملف تنفيذ Crew:
استبدل `provider/model-id` بالنموذج الذي تستخدمه، مثل `openai/gpt-4o` أو `gemini/gemini-2.0-flash-001` أو `anthropic/claude-sonnet-4-6`.
3. أنشئ `src/guide_creator_flow/crews/content_crew/crew.jsonc`:
```jsonc
{
"name": "Content Crew",
"agents": ["content_writer", "content_reviewer"],
"tasks": [
{
"name": "write_section_task",
"description": "Write a comprehensive section on the topic: \"{section_title}\".\n\nSection description: {section_description}\nTarget audience: {audience_level} level learners\n\nYour content should begin with a brief introduction, explain key concepts clearly with examples, include practical applications where appropriate, end with a summary, and be approximately 500-800 words.\n\nPreviously written sections:\n{previous_sections}",
"expected_output": "A well-structured, comprehensive section in Markdown format that thoroughly explains the topic and is appropriate for the target audience.",
"agent": "content_writer",
"markdown": true
},
{
"name": "review_section_task",
"description": "Review and improve this section on \"{section_title}\":\n\n{draft_content}\n\nTarget audience: {audience_level} level learners\nPreviously written sections:\n{previous_sections}\n\nFix errors, improve clarity, verify consistency, enhance structure, and add missing key information.",
"expected_output": "An improved, polished version of the section that maintains the original structure but enhances clarity, accuracy, and consistency.",
"agent": "content_reviewer",
"context": ["write_section_task"],
"markdown": true
}
],
"process": "sequential",
"verbose": true
}
```
4. استبدل `src/guide_creator_flow/crews/content_crew/content_crew.py` بمحمل صغير:
```python
# src/guide_creator_flow/crews/content_crew/content_crew.py
from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task
from crewai.agents.agent_builder.base_agent import BaseAgent
from typing import List
from pathlib import Path
@CrewBase
class ContentCrew():
"""Content writing crew"""
from crewai.project import load_crew
agents: List[BaseAgent]
tasks: List[Task]
@agent
def content_writer(self) -> Agent:
return Agent(
config=self.agents_config['content_writer'], # type: ignore[index]
verbose=True
)
@agent
def content_reviewer(self) -> Agent:
return Agent(
config=self.agents_config['content_reviewer'], # type: ignore[index]
verbose=True
)
@task
def write_section_task(self) -> Task:
return Task(
config=self.tasks_config['write_section_task'] # type: ignore[index]
)
@task
def review_section_task(self) -> Task:
return Task(
config=self.tasks_config['review_section_task'], # type: ignore[index]
context=[self.write_section_task()]
)
@crew
def crew(self) -> Crew:
"""Creates the content writing crew"""
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True,
)
def kickoff_content_crew(inputs: dict):
crew, default_inputs = load_crew(Path(__file__).with_name("crew.jsonc"))
return crew.kickoff(inputs={**default_inputs, **inputs})
```
## الخطوة 5: إنشاء Flow
@@ -272,6 +215,7 @@ crewai flow plot
3. استكشف دوال `and_` و`or_` لتنفيذ متوازٍ أكثر تعقيدًا
4. اربط Flow بواجهات API خارجية وقواعد بيانات وواجهات مستخدم
5. ادمج عدة Crews متخصصة في Flow واحد
6. أنشئ تطبيقات دردشة متعددة الجولات مع [تدفقات المحادثة](/ar/guides/flows/conversational-flows) (`kickoff` لكل رسالة، `ChatSession`، تأجيل التتبع)
<Check>
تهانينا! لقد بنيت بنجاح أول CrewAI Flow يجمع بين الكود العادي واستدعاءات LLM المباشرة ومعالجة Crew لإنشاء دليل شامل. هذه المهارات الأساسية تمكّنك من إنشاء تطبيقات AI متطورة بشكل متزايد.

View File

@@ -20,6 +20,8 @@ mode: "wide"
5. **توسيع تطبيقاتك** - دعم سير العمل المعقدة بتنظيم بيانات مناسب
6. **تمكين التطبيقات الحوارية** - تخزين والوصول إلى سجل المحادثات للتفاعلات الواعية بالسياق
للدردشة متعددة الجولات (`kickoff` لكل سطر مستخدم، `ChatState`، توجيه النية، تأجيل التتبع، و`ChatSession`)، راجع [تدفقات المحادثة](/ar/guides/flows/conversational-flows).
## أساسيات إدارة الحالة
### نهجان لإدارة الحالة

View File

@@ -113,7 +113,7 @@ python3 --version
# إنشاء مشروع CrewAI
نوصي باستخدام قالب `YAML` لنهج منظم في تعريف الـ Agents والمهام. إليك كيفية البدء:
يقوم `crewai create crew` الآن بإنشاء مشروع crew بأسلوب JSON-first. توضع الـ Agents في `agents/*.jsonc`، وتوضع المهام وإعدادات الـ crew في `crew.jsonc`، ويحمّل `crewai run` هذا التعريف مباشرة.
<Steps>
<Step title="إنشاء هيكل المشروع">
@@ -126,21 +126,20 @@ python3 --version
```
my_project/
├── .gitignore
├── .env
├── agents/
│ └── researcher.jsonc
├── crew.jsonc
├── knowledge/
├── pyproject.toml
├── README.md
├── .env
└── src/
└── my_project/
├── __init__.py
├── main.py
├── crew.py
├── tools/
│ ├── custom_tool.py
│ └── __init__.py
└── config/
├── agents.yaml
└── tasks.yaml
├── skills/
└── tools/
```
- إذا احتجت إلى البنية القديمة Python/YAML التي تحتوي على `crew.py` و `config/agents.yaml` و `config/tasks.yaml`، شغّل:
```shell
crewai create crew <your_project_name> --classic
```
</Step>
@@ -149,15 +148,15 @@ python3 --version
- سيحتوي مشروعك على هذه الملفات الأساسية:
| الملف | الغرض |
| --- | --- |
| `agents.yaml` | تعريف الـ Agents وأدوارهم |
| `tasks.yaml` | إعداد مهام الـ Agents وسير العمل |
| `crew.jsonc` | إعداد الـ crew وترتيب المهام والعملية وقيم الإدخال الافتراضية |
| `agents/*.jsonc` | تعريف دور كل Agent وهدفه و backstory والـ LLM والأدوات والسلوك |
| `.env` | تخزين مفاتيح API ومتغيرات البيئة |
| `main.py` | نقطة دخول المشروع وتدفق التنفيذ |
| `crew.py` | تنسيق وإدارة الـ Crew |
| `tools/` | مجلد الأدوات المخصصة |
| `knowledge/` | مجلد قاعدة المعرفة |
| `tools/` | ملفات Python اختيارية لأدوات `custom:<name>` |
| `knowledge/` | ملفات معرفة اختيارية للـ Agents |
| `skills/` | ملفات skills اختيارية تطبق على الـ crew |
- ابدأ بتحرير `agents.yaml` و`tasks.yaml` لتعريف سلوك الـ Crew.
- ابدأ بتحرير `crew.jsonc` والملفات داخل `agents/` لتعريف سلوك الـ crew.
- استخدم قيم `{placeholder}` في نصوص الـ Agents والمهام، ثم ضع القيم الافتراضية في `inputs` داخل `crew.jsonc`. عند تشغيل `crewai run` ستطلب CLI أي قيم ناقصة.
- احتفظ بالمعلومات الحساسة مثل مفاتيح API في `.env`.
</Step>

View File

@@ -5,11 +5,15 @@ icon: "at"
mode: "wide"
---
يشرح هذا الدليل كيفية استخدام التعليقات التوضيحية للإشارة بشكل صحيح إلى **الوكلاء** و**المهام** والمكونات الأخرى في ملف `crew.py`.
يشرح هذا الدليل كيفية استخدام التعليقات التوضيحية للإشارة بشكل صحيح إلى **الوكلاء** و**المهام** والمكونات الأخرى في ملف `crew.py` كلاسيكي.
<Note>
المشاريع الجديدة التي تُنشأ عبر `crewai create crew <name>` هي JSON-first وتستخدم `crew.jsonc` مع `agents/*.jsonc`. استخدم هذا الدليل عند العمل في مشروع كلاسيكي أُنشئ عبر `crewai create crew <name> --classic`، أو عند ترحيل مشروع Python/YAML موجود، أو عندما تحتاج تحكمًا عبر decorators في Python.
</Note>
## مقدمة
تُستخدم التعليقات التوضيحية في إطار عمل CrewAI لتزيين الفئات والطرق، مما يوفر بيانات وصفية ووظائف للمكونات المختلفة في طاقمك. تساعد هذه التعليقات التوضيحية في تنظيم وهيكلة الكود الخاص بك، مما يجعله أكثر قابلية للقراءة والصيانة.
تُستخدم التعليقات التوضيحية في إطار عمل CrewAI لتزيين الفئات والطرق، مما يوفر بيانات وصفية ووظائف للمكونات المختلفة في طاقمك. في مشاريع Python/YAML الكلاسيكية، تنظم الكود الذي يحمّل `config/agents.yaml` و `config/tasks.yaml` ويعيد كائن `Crew`.
## التعليقات التوضيحية المتاحة
@@ -113,9 +117,9 @@ def crew(self) -> Crew:
تُستخدم التعليقة التوضيحية `@crew` لتزيين الطريقة التي تنشئ وتُرجع كائن `Crew`. تجمع هذه الطريقة جميع المكونات (الوكلاء والمهام) في طاقم وظيفي.
## إعداد YAML
## إعداد YAML الكلاسيكي
تُخزن إعدادات الوكلاء عادةً في ملف YAML. إليك مثالاً على كيفية ظهور ملف `agents.yaml` لوكيل الباحث:
في المشاريع الكلاسيكية، تُخزن إعدادات الوكلاء عادةً في ملف YAML. إليك مثالاً على كيفية ظهور ملف `agents.yaml` لوكيل الباحث:
```yaml
researcher:
@@ -146,6 +150,6 @@ researcher:
- **تسمية متسقة**: استخدم اصطلاحات تسمية واضحة ومتسقة لطرقك. على سبيل المثال، يمكن تسمية طرق الوكلاء بأسماء أدوارهم (مثل researcher، reporting_analyst).
- **متغيرات البيئة**: استخدم متغيرات البيئة للمعلومات الحساسة مثل مفاتيح API.
- **المرونة**: صمم طاقمك ليكون مرناً بالسماح بإضافة أو إزالة الوكلاء والمهام بسهولة.
- **توافق YAML-الكود**: تأكد من أن الأسماء والهياكل في ملفات YAML تتوافق بشكل صحيح مع الطرق المزينة في كود Python الخاص بك.
- **توافق YAML-الكود**: في المشاريع الكلاسيكية، تأكد من أن الأسماء والهياكل في ملفات YAML تتوافق بشكل صحيح مع الطرق المزينة في كود Python الخاص بك.
باتباع هذه الإرشادات واستخدام التعليقات التوضيحية بشكل صحيح، يمكنك إنشاء أطقم منظمة جيداً وسهلة الصيانة باستخدام إطار عمل CrewAI.
باتباع هذه الإرشادات واستخدام التعليقات التوضيحية بشكل صحيح، يمكنك الحفاظ على أطقم كلاسيكية منظمة وسهلة الصيانة. للـ crews الجديدة، استخدم بنية JSON-first في [Crews](/ar/concepts/crews).

View File

@@ -39,84 +39,60 @@ mode: "wide"
يُنشئ ذلك تطبيق Flow ضمن `src/latest_ai_flow/`، بما في ذلك طاقمًا أوليًا في `crews/content_crew/` ستستبدله بطاقم بحث **بوكيل واحد** في الخطوات التالية.
</Step>
<Step title="اضبط وكيلًا واحدًا في `agents.yaml`">
استبدل محتوى `src/latest_ai_flow/crews/content_crew/config/agents.yaml` بباحث واحد. تُملأ المتغيرات مثل `{topic}` من `crew.kickoff(inputs=...)`.
<Step title="اضبط وكيلًا واحدًا في JSONC">
أنشئ `src/latest_ai_flow/crews/content_crew/agents/researcher.jsonc` (أنشئ مجلد `agents/` إذا لزم). تُملأ المتغيرات مثل `{topic}` من `crew.kickoff(inputs=...)`.
```yaml agents.yaml
# src/latest_ai_flow/crews/content_crew/config/agents.yaml
researcher:
role: >
باحث بيانات أول في {topic}
goal: >
اكتشاف أحدث التطورات في {topic}
backstory: >
أنت باحث مخضرم تكشف أحدث المستجدات في {topic}.
تجد المعلومات الأكثر صلة وتعرضها بوضوح.
```jsonc agents/researcher.jsonc
{
"role": "باحث بيانات أول في {topic}",
"goal": "اكتشاف أحدث التطورات في {topic}",
"backstory": "أنت باحث يجد المعلومات الأكثر صلة ويعرضها بوضوح.",
"tools": ["SerperDevTool"],
"settings": {
"verbose": true
}
}
```
</Step>
<Step title="اضبط مهمة واحدة في `tasks.yaml`">
```yaml tasks.yaml
# src/latest_ai_flow/crews/content_crew/config/tasks.yaml
research_task:
description: >
أجرِ بحثًا معمقًا عن {topic}. استخدم البحث على الويب للعثور على معلومات
حديثة وموثوقة. السنة الحالية 2026.
expected_output: >
تقرير بصيغة Markdown بأقسام واضحة: الاتجاهات الرئيسية، أدوات أو شركات بارزة،
والآثار. بين 800 و1200 كلمة تقريبًا. دون إحاطة المستند بأكمله بكتل كود.
agent: researcher
output_file: output/report.md
<Step title="اضبط الـ crew في `crew.jsonc`">
أنشئ `src/latest_ai_flow/crews/content_crew/crew.jsonc`:
```jsonc crew.jsonc
{
"name": "Research Crew",
"agents": ["researcher"],
"tasks": [
{
"name": "research_task",
"description": "أجرِ بحثًا معمقًا عن {topic}. استخدم البحث على الويب للعثور على معلومات حديثة وموثوقة.",
"expected_output": "تقرير بصيغة Markdown بأقسام واضحة: الاتجاهات الرئيسية، أدوات أو شركات بارزة، والآثار. بين 800 و1200 كلمة تقريبًا. دون إحاطة المستند بأكمله بكتل كود.",
"agent": "researcher",
"output_file": "output/report.md",
"markdown": true
}
],
"process": "sequential",
"verbose": true
}
```
</Step>
<Step title="اربط صف الطاقم (`content_crew.py`)">
اجعل الطاقم المُولَّد يشير إلى YAML وأرفق `SerperDevTool` بالباحث.
<Step title="حمّل crew JSON (`content_crew.py`)">
استبدل `content_crew.py` المُولّد بمحمل صغير يحول `crew.jsonc` إلى `Crew`.
```python content_crew.py
# src/latest_ai_flow/crews/content_crew/content_crew.py
from typing import List
from pathlib import Path
from crewai import Agent, Crew, Process, Task
from crewai.agents.agent_builder.base_agent import BaseAgent
from crewai.project import CrewBase, agent, crew, task
from crewai_tools import SerperDevTool
from crewai.project import load_crew
@CrewBase
class ResearchCrew:
"""طاقم بحث بوكيل واحد داخل Flow."""
agents: List[BaseAgent]
tasks: List[Task]
agents_config = "config/agents.yaml"
tasks_config = "config/tasks.yaml"
@agent
def researcher(self) -> Agent:
return Agent(
config=self.agents_config["researcher"], # type: ignore[index]
verbose=True,
tools=[SerperDevTool()],
)
@task
def research_task(self) -> Task:
return Task(
config=self.tasks_config["research_task"], # type: ignore[index]
)
@crew
def crew(self) -> Crew:
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True,
)
def kickoff_content_crew(inputs: dict):
crew, default_inputs = load_crew(Path(__file__).with_name("crew.jsonc"))
return crew.kickoff(inputs={**default_inputs, **inputs})
```
</Step>
@@ -130,7 +106,7 @@ mode: "wide"
from crewai.flow import Flow, listen, start
from latest_ai_flow.crews.content_crew.content_crew import ResearchCrew
from latest_ai_flow.crews.content_crew.content_crew import kickoff_content_crew
class ResearchFlowState(BaseModel):
@@ -149,7 +125,7 @@ mode: "wide"
@listen(prepare_topic)
def run_research(self):
result = ResearchCrew().crew().kickoff(inputs={"topic": self.state.topic})
result = kickoff_content_crew(inputs={"topic": self.state.topic})
self.state.report = result.raw
print("اكتمل طاقم البحث.")
@@ -171,7 +147,7 @@ mode: "wide"
```
<Tip>
إذا كان اسم الحزمة ليس `latest_ai_flow`، عدّل استيراد `ResearchCrew` ليطابق مسار الوحدة في مشروعك.
إذا كان اسم الحزمة ليس `latest_ai_flow`، عدّل استيراد `kickoff_content_crew` ليطابق مسار الوحدة في مشروعك.
</Tip>
</Step>
@@ -198,7 +174,7 @@ mode: "wide"
<CodeGroup>
```markdown output/report.md
# وكلاء الذكاء الاصطناعي في 2026: المشهد والاتجاهات
# وكلاء الذكاء الاصطناعي: المشهد والاتجاهات الحديثة
## ملخص تنفيذي
@@ -219,7 +195,7 @@ mode: "wide"
## كيف يترابط هذا
1. **Flow** — يشغّل `LatestAiFlow` أولًا `prepare_topic` ثم `run_research` ثم `summarize`. الحالة (`topic`، `report`) على Flow.
2. **الطاقم** — يشغّل `ResearchCrew` مهمة واحدة بوكيل واحد: الباحث يستخدم **Serper** للبحث على الويب ثم يكتب التقرير.
2. **الطاقم** — يحمّل `kickoff_content_crew` ملف `crew.jsonc` ويشغّل مهمة واحدة بوكيل واحد: الباحث يستخدم **Serper** للبحث على الويب ثم يكتب التقرير.
3. **المُخرَج** — يكتب `output_file` للمهمة التقرير في `output/report.md`.
للتعمق في أنماط Flow (التوجيه، الاستمرارية، الإنسان في الحلقة)، راجع [ابنِ أول Flow](/ar/guides/flows/first-flow) و[Flows](/ar/concepts/flows). للطواقم دون Flow، راجع [Crews](/ar/concepts/crews). لوكيل `Agent` واحد و`kickoff()` بلا مهام، راجع [Agents](/ar/concepts/agents#direct-agent-interaction-with-kickoff).
@@ -230,7 +206,10 @@ mode: "wide"
### اتساق التسمية
يجب أن تطابق مفاتيح YAML (`researcher`، `research_task`) أسماء الدوال في صف `@CrewBase`. راجع [Crews](/ar/concepts/crews) لنمط الديكورات الكامل.
يجب أن تطابق الأسماء في `crew.jsonc` الملفات والمراجع:
- `agents: ["researcher"]` يحمّل `agents/researcher.jsonc`
- `tasks[].agent: "researcher"` يربط المهمة بذلك الـ agent
## النشر

View File

@@ -20,7 +20,7 @@ npx skills add crewaiinc/skills
## ما يحصل عليه الوكيل
- **Flows** — تطبيقات ذات حالة وخطوات وkickoffs للـ crew على نمط CrewAI
- **Crews والوكلاء** — أنماط YAML أولاً، أدوار، مهام، وتفويض
- **Crews والوكلاء** — أنماط JSON-first (`crew.jsonc` و `agents/*.jsonc`)، أدوار، مهام، وتفويض
- **الأدوات والتكاملات** — ربط الوكلاء بالبحث وواجهات API وأدوات CrewAI الشائعة
- **هيكل المشروع** — مواءمة مع قوالب CLI واتفاقيات المستودع
- **أنماط محدثة** — تتبع المهارات وثائق CrewAI والممارسات الموصى بها

File diff suppressed because it is too large Load Diff

View File

@@ -4,6 +4,281 @@ description: "Product updates, improvements, and bug fixes for CrewAI"
icon: "clock"
mode: "wide"
---
<Update label="Jun 11, 2026">
## v1.14.7
[View release on GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.7)
## What's Changed
### Features
- Add pluggable default backends for memory, knowledge, rag, and flow.
- Surface real finish_reason, sampling params, and response.id on LLM events.
- Type DSL triggers as route-aware decorators.
- Add chat API for conversational flows.
- Make locking backend overridable.
- Build FlowDefinition from Flow DSL metadata.
- Add native Snowflake Cortex LLM provider.
- Add crew trained agents file support.
### Bug Fixes
- Fix checkpoint to rebuild custom BaseLLM as concrete LLM on restore.
- Gate restore on a flag to prevent live snapshots from replaying as resume.
- Scope runtime state per run to bound growth and isolate concurrent runs.
- Fix telemetry setup on crewai-login.
- Respect suppress_flow_events for method-execution events.
- Restore [project.scripts] in crewai package for uv tool install.
- Resolve pip-audit CVEs for aiohttp, docling, and docling-core.
- Fix file input not working reliably.
- Fix Snowflake Claude incomplete tool result histories.
### Documentation
- Update changelog and version for v1.14.7.
- Update OpenTelemetry collector documentation.
- Update NVIDIA Nemotron LLM guide.
- Add Databricks integration guide.
- Add Snowflake integration guide.
### Performance
- Improve crewai import speed by lazy-loading docling imports.
### Refactoring
- Simplify flow condition evaluation to be stateless per event.
- Decouple convo logic from runtime and add a conversational_definition.
- Split `flow.py` into DSL, definition, and runtime.
## Contributors
@Luzk, @alex-clawd, @devin-ai-integration[bot], @greysonlalonde, @gvieira, @jessemiller, @lorenzejay, @lucasgomide, @mattatcha, @vinibrsl
</Update>
<Update label="Jun 10, 2026">
## v1.14.7rc2
[View release on GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.7rc2)
## What's Changed
### Bug Fixes
- Gate restore on a flag to prevent live snapshots from replaying as resume
### Documentation
- Update changelog and version for v1.14.7rc1
## Contributors
@greysonlalonde
</Update>
<Update label="Jun 10, 2026">
## v1.14.7rc1
[View release on GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.7rc1)
## What's Changed
### Features
- Add `reset_runtime_state` to release accumulated bus state
- Handle supporting both custom prompts
- Decouple conversation logic from runtime and add a `conversational_definition`
### Bug Fixes
- Fix scope of runtime state per run to bound growth and isolate concurrent runs
- Fix telemetry setup on `crewai-login`
- Fix respect for `suppress_flow_events` for method-execution events
### Documentation
- Update OpenTelemetry images
- Update documentation to reflect new state of OpenTelemetry collector
- Update changelog and version for v1.14.7a4
### Refactoring
- Simplify flow condition evaluation to be stateless per event
- Improve conversation routing cycle with one less route
## Contributors
@greysonlalonde, @lorenzejay, @lucasgomide, @vinibrsl
</Update>
<Update label="Jun 09, 2026">
## v1.14.7a4
[View release on GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.7a4)
## What's Changed
### Features
- Migrate @listen/@router runtime to read from FlowDefinition
- Add pluggable default backends for memory, knowledge, rag, and flow
### Documentation
- Update changelog and version for v1.14.7a3
## Contributors
@greysonlalonde, @mattatcha, @vinibrsl
</Update>
<Update label="Jun 08, 2026">
## v1.14.7a3
[View release on GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.7a3)
## What's Changed
### Bug Fixes
- Fix exposure of `ask_for_human_input` on experimental `AgentExecutor`
- Resolve pip-audit CVEs for `aiohttp`, `docling`, `docling-core`, and `pip`
### Refactoring
- Migrate `@start` to read from `FlowDefinition`
### Documentation
- Update changelog and version for v1.14.7a2
## Contributors
@greysonlalonde, @lorenzejay, @vinibrsl
</Update>
<Update label="Jun 05, 2026">
## v1.14.7a2
[View release on GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.7a2)
## What's Changed
### Features
- Add conversational flow traces support.
- Update conversational flow documentation to utilize `handle_turn`.
- Surface real `finish_reason`, sampling parameters, and `response.id` in LLM events.
- Type DSL triggers as route-aware decorators.
- Implement chat API for conversational flows.
- Make locking backend overridable in lock store.
- Split flow DSL monolith into focused decorator modules.
- Flatten LiteLLM cache/reasoning usage sub-counts in `_usage_to_dict`.
- Build `FlowDefinition` from Flow DSL metadata.
### Documentation
- Add NVIDIA Nemotron LLM guide.
- Document monorepo deployments.
- Update changelog and version for v1.14.7a1.
## Contributors
@alex-clawd, @gvieira, @lorenzejay, @lucasgomide, @mattatcha, @vinibrsl
</Update>
<Update label="Jun 03, 2026">
## v1.14.7a1
[View release on GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.7a1)
## What's Changed
### Features
- Add crew trained agents file support
- Add native Snowflake Cortex LLM provider
- Add Databricks integration guide
- Add Snowflake integration guide
### Bug Fixes
- Fix CLI by restoring `[project.scripts]` in crewai package for UV tool install
- Resolve file input reliability issues
- Fix incomplete tool result histories in Snowflake Claude
- Handle stringified tool calls for Snowflake Claude
- Re-arm multi-source `or_` listeners across router-driven cycles
### Performance
- Improve crewai import speed by lazy-loading docling imports
### Refactoring
- Split `flow.py` into DSL, definition, and runtime
## Contributors
@Luzk, @alex-clawd, @devin-ai-integration[bot], @greysonlalonde, @jessemiller, @lorenzejay, @vinibrsl
</Update>
<Update label="May 28, 2026">
## v1.14.6
[View release on GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.6)
## What's Changed
### Features
- Enhance StdioTransport to prevent environment variable leakage
- Enhance planning configuration and observation handling
- Declare env_vars on DatabricksQueryTool
- Add Agent Control Plane docs
### Bug Fixes
- Fix structured output leaks in tool-calling loops
- Drop unroundtrippable callbacks and adapter state in checkpoint
- Serialize type[BaseModel] fields as JSON schema in checkpoint
- Avoid orphan task_started on resume scope restore
- Allow AgentExecutor to restore from checkpoint
- Correct mongodb typo to pymongo in package_dependencies
### Documentation
- Add ACP (Beta) docs navigation block to Agent Control Plane pages
- Remove consensual process references from processes page
- Restructure checkpointing page
- Document one-time admin package install step
- Migrate Secrets Manager / Workload Identity from replicated-config
- Remove `{" "}` JSX expressions breaking `<Steps>` render
### Refactoring
- Move Skills Repository to experimental + CREWAI_EXPERIMENTAL gate
## Contributors
@akaKuruma, @alex-clawd, @github-actions[bot], @greysonlalonde, @heitorado, @iris-clawd, @lorenzejay, @lucasgomide, @mattatcha, @thiagomoretto, @vinibrsl
</Update>
<Update label="May 27, 2026">
## v1.14.6a2
[View release on GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.6a2)
## What's Changed
### Features
- Enhance `StdioTransport` to prevent environment variable leakage
- Enhance planning configuration and observation handling
- Declare `env_vars` on `DatabricksQueryTool`
- Add Agent Control Plane documentation
### Bug Fixes
- Fix structured output leaks in tool-calling loops
- Drop unroundtrippable callbacks and adapter state in checkpointing
- Serialize `type[BaseModel]` fields as JSON schema in checkpointing
- Avoid orphan `task_started` on resume scope restore
- Allow `AgentExecutor` to restore from checkpoint
- Correct MongoDB typo to `pymongo` in package dependencies
### Documentation
- Restructure checkpointing page
- Document one-time admin package install step
- Migrate Secrets Manager / Workload Identity from replicated-config
- Remove Skills Repository entry from changelog
## Contributors
@github-actions[bot], @greysonlalonde, @heitorado, @iris-clawd, @lorenzejay, @lucasgomide, @mattatcha, @thiagomoretto, @vinibrsl
</Update>
<Update label="May 21, 2026">
## v1.14.6a1
@@ -12,7 +287,6 @@ mode: "wide"
## What's Changed
### Features
- Add Skills Repository with registry, cache, CLI, and SDK integration
- Generate categorized release notes for enterprise
### Bug Fixes

View File

@@ -71,81 +71,65 @@ The Visual Agent Builder enables:
## Creating Agents
There are two ways to create agents in CrewAI: using **YAML configuration (recommended)** or defining them **directly in code**.
There are two common ways to create agents in CrewAI: using **JSONC project configuration (recommended for new crews)** or defining them **directly in code**.
### YAML Configuration (Recommended)
### JSONC Configuration (Recommended)
Using YAML configuration provides a cleaner, more maintainable way to define agents. We strongly recommend using this approach in your CrewAI projects.
New projects created with `crewai create crew <name>` use JSON-first configuration. Each agent is defined in `agents/<agent_name>.jsonc`, and `crew.jsonc` lists which agents are part of the crew.
After creating your CrewAI project as outlined in the [Installation](/en/installation) section, navigate to the `src/latest_ai_development/config/agents.yaml` file and modify the template to match your requirements.
After creating your CrewAI project as outlined in the [Installation](/en/installation) section, edit the generated files in `agents/`.
<Note>
Variables in your YAML files (like `{topic}`) will be replaced with values from your inputs when running the crew:
```python Code
crew.kickoff(inputs={'topic': 'AI Agents'})
```
Use `{placeholder}` values in `role`, `goal`, or `backstory`. Put defaults in `crew.jsonc` under `inputs`; `crewai run` prompts for any missing values.
</Note>
Here's an example of how to configure agents using YAML:
Here's an example `agents/researcher.jsonc` file:
```yaml agents.yaml
# src/latest_ai_development/config/agents.yaml
researcher:
role: >
{topic} Senior Data Researcher
goal: >
Uncover cutting-edge developments in {topic}
backstory: >
You're a seasoned researcher with a knack for uncovering the latest
developments in {topic}. Known for your ability to find the most relevant
information and present it in a clear and concise manner.
reporting_analyst:
role: >
{topic} Reporting Analyst
goal: >
Create detailed reports based on {topic} data analysis and research findings
backstory: >
You're a meticulous analyst with a keen eye for detail. You're known for
your ability to turn complex data into clear and concise reports, making
it easy for others to understand and act on the information you provide.
```jsonc agents/researcher.jsonc
{
"role": "{topic} Senior Data Researcher",
"goal": "Uncover cutting-edge developments in {topic}",
"backstory": "You find the most relevant information and present it clearly.",
"llm": "openai/gpt-4o",
"tools": ["SerperDevTool"],
"settings": {
"verbose": true,
"allow_delegation": false,
"max_iter": 20
}
}
```
To use this YAML configuration in your code, create a crew class that inherits from `CrewBase`:
Then include that agent from `crew.jsonc`:
```python Code
# src/latest_ai_development/crew.py
from crewai import Agent, Crew, Process
from crewai.project import CrewBase, agent, crew
from crewai_tools import SerperDevTool
@CrewBase
class LatestAiDevelopmentCrew():
"""LatestAiDevelopment crew"""
agents_config = "config/agents.yaml"
@agent
def researcher(self) -> Agent:
return Agent(
config=self.agents_config['researcher'], # type: ignore[index]
verbose=True,
tools=[SerperDevTool()]
)
@agent
def reporting_analyst(self) -> Agent:
return Agent(
config=self.agents_config['reporting_analyst'], # type: ignore[index]
verbose=True
)
```jsonc crew.jsonc
{
"name": "Research Crew",
"agents": ["researcher"],
"tasks": [
{
"name": "research_task",
"description": "Research {topic}",
"expected_output": "A concise briefing about {topic}",
"agent": "researcher"
}
],
"inputs": {
"topic": "AI Agents"
}
}
```
Agent files support any public `Agent` field. Common fields include `role`, `goal`, `backstory`, `llm`, `tools`, `function_calling_llm`, `guardrail`, `step_callback`, and `settings`. Behavior options such as `verbose`, `allow_delegation`, `max_iter`, `max_rpm`, `memory`, `cache`, `planning_config`, and `use_system_prompt` can be placed at the top level or under `settings`; values in `settings` take precedence.
<Note>
The names you use in your YAML files (`agents.yaml`) should match the method
names in your Python code.
JSONC supports comments and trailing commas. If both `agents/<name>.jsonc` and `agents/<name>.json` exist, CrewAI uses the JSONC file.
</Note>
### Classic YAML Configuration
Classic projects created with `crewai create crew <name> --classic` use `config/agents.yaml` and a `@CrewBase` class in `crew.py`. This remains supported for teams that want Python decorators or existing YAML projects.
### Direct Code Definition
You can create agents directly in code by instantiating the `Agent` class. Here's a comprehensive example showing all available parameters:

View File

@@ -5,301 +5,419 @@ icon: floppy-disk
mode: "wide"
---
<Warning>
Checkpointing is in early release. APIs may change in future versions.
</Warning>
Checkpointing saves a snapshot of execution state during a run so a crew, flow, or agent can resume after a failure or be forked into an alternate branch.
## Overview
<CardGroup cols={2}>
<Card title="Explanation" icon="lightbulb" href="#explanation">
How checkpointing works: events, storage, and inheritance.
</Card>
<Card title="Tutorial" icon="graduation-cap" href="#tutorial-resume-a-failing-crew">
A 5-minute walkthrough: run, interrupt, resume.
</Card>
<Card title="How-to guides" icon="screwdriver-wrench" href="#how-to-guides">
Task-focused recipes for common workflows.
</Card>
<Card title="Reference" icon="book" href="#reference">
`CheckpointConfig`, events, providers, and CLI.
</Card>
</CardGroup>
Checkpointing automatically saves execution state during a run. If a crew, flow, or agent fails mid-execution, you can restore from the last checkpoint and resume without re-running completed work.
## Explanation
## Quick Start
### What a checkpoint is
```python
from crewai import Crew, CheckpointConfig
A checkpoint captures everything CrewAI needs to recreate a run mid-flight: the full state of the crew, flow, or agent — configuration, agent memory and knowledge sources, task progress, intermediate outputs, internal state and attributes — alongside the kickoff inputs, the event history up to that point, and a lineage ID that ties the checkpoint to the run it came from.
crew = Crew(
agents=[...],
tasks=[...],
checkpoint=True, # uses defaults: ./.checkpoints, on task_completed
)
result = crew.kickoff()
```
Restoring rebuilds that state and continues. Completed tasks are skipped, memory and knowledge are rehydrated, and downstream work runs against the same outputs the original run produced. Forking does the same restore under a new lineage, so the new branch and the original run can write checkpoints side by side without overwriting each other.
Checkpoint files are written to `./.checkpoints/` after each completed task.
### When checkpoints are written
## Configuration
Checkpointing is event-driven. The runtime subscribes to events you select via `on_events` and writes a checkpoint each time one fires. The default `task_completed` produces one checkpoint per finished task — a sensible tradeoff between granularity and disk use. Higher-frequency events like `llm_call_completed` are available for fine-grained recovery but write far more files.
Use `CheckpointConfig` for full control:
### Storage
```python
from crewai import Crew, CheckpointConfig
Two providers ship with CrewAI:
crew = Crew(
agents=[...],
tasks=[...],
checkpoint=CheckpointConfig(
location="./my_checkpoints",
on_events=["task_completed", "crew_kickoff_completed"],
max_checkpoints=5,
),
)
```
- `JsonProvider` writes one file per checkpoint. Human-readable and easy to inspect.
- `SqliteProvider` writes to a single SQLite database. Better for high-frequency checkpointing.
### CheckpointConfig Fields
Both prune oldest checkpoints when `max_checkpoints` is set.
| Field | Type | Default | Description |
|:------|:-----|:--------|:------------|
| `location` | `str` | `"./.checkpoints"` | Storage destination — a directory for `JsonProvider`, a database file path for `SqliteProvider` |
| `on_events` | `list[str]` | `["task_completed"]` | Event types that trigger a checkpoint |
| `provider` | `BaseProvider` | `JsonProvider()` | Storage backend |
| `max_checkpoints` | `int \| None` | `None` | Max checkpoints to keep. Oldest are pruned after each write. Pruning is handled by the provider. |
| `restore_from` | `Path \| str \| None` | `None` | Path to a checkpoint to restore from. Used when passing config via a kickoff method's `from_checkpoint` parameter. |
<Note>
Auto-checkpoint writes (event-driven) are best-effort: a failed write is logged and the run continues. Manual `state.checkpoint()` and `state.acheckpoint()` calls re-raise on failure.
</Note>
### Inheritance and Opt-Out
### Inheritance model
The `checkpoint` field on Crew, Flow, and Agent accepts `CheckpointConfig`, `True`, `False`, or `None`:
`Crew`, `Flow`, and `Agent` all accept a `checkpoint` argument. Children inherit from their parent unless they set their own value or pass `False` to opt out. Enable checkpointing once on the crew and every agent participates, or selectively exclude one agent.
| Value | Behavior |
|:------|:---------|
| `None` (default) | Inherit from parent. An agent inherits its crew's config. |
| `True` | Enable with defaults. |
| `False` | Explicit opt-out. Stops inheritance from parent. |
| `CheckpointConfig(...)` | Custom configuration. |
## Tutorial: Resume a failing crew
```python
crew = Crew(
agents=[
Agent(role="Researcher", ...), # inherits crew's checkpoint
Agent(role="Writer", ..., checkpoint=False), # opted out, no checkpoints
],
tasks=[...],
checkpoint=True,
)
```
This walkthrough takes ~5 minutes. You will run a two-task crew, kill it midway, and resume from the saved checkpoint.
## Resuming from a Checkpoint
<Steps>
<Step title="Create the crew with checkpointing enabled">
```python
from crewai import Agent, Crew, Task
Pass a `CheckpointConfig` with `restore_from` to any kickoff method. The crew restores from that checkpoint, skips completed tasks, and resumes.
researcher = Agent(role="Researcher", goal="Research", backstory="Expert")
writer = Agent(role="Writer", goal="Write", backstory="Expert")
```python
from crewai import Crew, CheckpointConfig
crew = Crew(
agents=[researcher, writer],
tasks=[
Task(description="Research AI trends", agent=researcher, expected_output="bullets"),
Task(description="Write a summary", agent=writer, expected_output="paragraph"),
],
checkpoint=True,
)
```
</Step>
<Step title="Run it and interrupt after the first task">
```python
result = crew.kickoff()
```
crew = Crew(agents=[...], tasks=[...])
result = crew.kickoff(
from_checkpoint=CheckpointConfig(
restore_from="./my_checkpoints/20260407T120000_abc123.json",
),
)
```
Press `Ctrl+C` after the first task finishes. Look in `./.checkpoints/` — a file named `<timestamp>_<uuid>.json` is the checkpoint.
</Step>
<Step title="Resume from the checkpoint">
```python
from crewai import CheckpointConfig
Remaining `CheckpointConfig` fields apply to the new run, so checkpointing continues after the restore.
result = crew.kickoff(
from_checkpoint=CheckpointConfig(
restore_from="./.checkpoints/<timestamp>_<uuid>.json",
),
)
```
You can also use the classmethod directly:
The research task is skipped, the writer runs against the saved research output, and the crew finishes.
</Step>
</Steps>
```python
config = CheckpointConfig(restore_from="./my_checkpoints/20260407T120000_abc123.json")
crew = Crew.from_checkpoint(config)
result = crew.kickoff()
```
## How-to guides
## Forking from a Checkpoint
<AccordionGroup>
<Accordion title="Enable checkpointing with defaults" icon="play">
```python
crew = Crew(agents=[...], tasks=[...], checkpoint=True)
```
`fork()` restores a checkpoint and starts a new execution branch. Useful for exploring alternative paths from the same point.
Writes to `./.checkpoints/` on every `task_completed`.
</Accordion>
```python
from crewai import Crew, CheckpointConfig
<Accordion title="Customize storage and frequency" icon="sliders">
```python
from crewai import Crew, CheckpointConfig
config = CheckpointConfig(restore_from="./my_checkpoints/20260407T120000_abc123.json")
crew = Crew.fork(config, branch="experiment-a")
result = crew.kickoff(inputs={"strategy": "aggressive"})
```
crew = Crew(
agents=[...],
tasks=[...],
checkpoint=CheckpointConfig(
location="./my_checkpoints",
on_events=["task_completed", "crew_kickoff_completed"],
max_checkpoints=5,
),
)
```
</Accordion>
Each fork gets a unique lineage ID so checkpoints from different branches don't collide. The `branch` label is optional and auto-generated if omitted.
<Accordion title="Choose a storage provider" icon="database">
<CodeGroup>
```python JsonProvider
from crewai import Crew, CheckpointConfig
from crewai.state import JsonProvider
## Works on Crew, Flow, and Agent
crew = Crew(
agents=[...],
tasks=[...],
checkpoint=CheckpointConfig(
location="./my_checkpoints",
provider=JsonProvider(),
max_checkpoints=5,
),
)
```
```python SqliteProvider
from crewai import Crew, CheckpointConfig
from crewai.state import SqliteProvider
### Crew
crew = Crew(
agents=[...],
tasks=[...],
checkpoint=CheckpointConfig(
location="./.checkpoints.db",
provider=SqliteProvider(),
max_checkpoints=50,
),
)
```
</CodeGroup>
```python
crew = Crew(
agents=[researcher, writer],
tasks=[research_task, write_task, review_task],
checkpoint=CheckpointConfig(location="./crew_cp"),
)
```
<Tip>
SQLite enables WAL journal mode for concurrent reads. Prefer it for high-frequency checkpointing.
</Tip>
</Accordion>
Default trigger: `task_completed` (one checkpoint per finished task).
<Accordion title="Opt one agent out" icon="user-slash">
```python
crew = Crew(
agents=[
Agent(role="Researcher", ...),
Agent(role="Writer", ..., checkpoint=False),
],
tasks=[...],
checkpoint=True,
)
```
</Accordion>
### Flow
<Accordion title="Fork into a new branch" icon="code-branch">
`fork()` restores a checkpoint under a fresh lineage so the new run does not collide with the original.
```python
from crewai.flow.flow import Flow, start, listen
from crewai import CheckpointConfig
```python
config = CheckpointConfig(restore_from="./my_checkpoints/<file>.json")
crew = Crew.fork(config, branch="experiment-a")
result = crew.kickoff(inputs={"strategy": "aggressive"})
```
class MyFlow(Flow):
@start()
def step_one(self):
return "data"
The `branch` label is optional; one is generated if omitted.
</Accordion>
@listen(step_one)
def step_two(self, data):
return process(data)
<Accordion title="Checkpoint a Crew, Flow, or Agent" icon="cubes">
<Tabs>
<Tab title="Crew">
```python
crew = Crew(
agents=[researcher, writer],
tasks=[research_task, write_task, review_task],
checkpoint=CheckpointConfig(location="./crew_cp"),
)
```
flow = MyFlow(
checkpoint=CheckpointConfig(
location="./flow_cp",
on_events=["method_execution_finished"],
),
)
result = flow.kickoff()
Default trigger: `task_completed`.
</Tab>
<Tab title="Flow">
```python
from crewai.flow.flow import Flow, start, listen
from crewai import CheckpointConfig
# Resume
config = CheckpointConfig(restore_from="./flow_cp/20260407T120000_abc123.json")
flow = MyFlow.from_checkpoint(config)
result = flow.kickoff()
```
class MyFlow(Flow):
@start()
def step_one(self):
return "data"
### Agent
@listen(step_one)
def step_two(self, data):
return process(data)
```python
agent = Agent(
role="Researcher",
goal="Research topics",
backstory="Expert researcher",
checkpoint=CheckpointConfig(
location="./agent_cp",
on_events=["lite_agent_execution_completed"],
),
)
result = agent.kickoff(messages=[{"role": "user", "content": "Research AI trends"}])
```
flow = MyFlow(
checkpoint=CheckpointConfig(
location="./flow_cp",
on_events=["method_execution_finished"],
),
)
result = flow.kickoff()
```
</Tab>
<Tab title="Agent">
```python
agent = Agent(
role="Researcher",
goal="Research topics",
backstory="Expert researcher",
checkpoint=CheckpointConfig(
location="./agent_cp",
on_events=["lite_agent_execution_completed"],
),
)
result = agent.kickoff(messages=[{"role": "user", "content": "Research AI trends"}])
```
</Tab>
</Tabs>
</Accordion>
## Storage Providers
<Accordion title="Write a checkpoint manually" icon="code">
Register a handler on any event and call `state.checkpoint()`.
CrewAI ships with two checkpoint storage providers.
<CodeGroup>
```python Sync
from __future__ import annotations
### JsonProvider (default)
from typing import TYPE_CHECKING, Any
Writes each checkpoint as a separate JSON file. Simple, human-readable, easy to inspect.
from crewai.events.event_bus import crewai_event_bus
from crewai.events.types.llm_events import LLMCallCompletedEvent
```python
from crewai import Crew, CheckpointConfig
from crewai.state import JsonProvider
if TYPE_CHECKING:
from crewai.state.runtime import RuntimeState
crew = Crew(
agents=[...],
tasks=[...],
checkpoint=CheckpointConfig(
location="./my_checkpoints",
provider=JsonProvider(), # this is the default
max_checkpoints=5, # prunes oldest files
),
)
```
Files are named `<timestamp>_<uuid>.json` inside the location directory.
@crewai_event_bus.on(LLMCallCompletedEvent)
def on_llm_done(source: Any, event: LLMCallCompletedEvent, state: RuntimeState) -> None:
path = state.checkpoint("./my_checkpoints")
print(f"Saved checkpoint: {path}")
```
```python Async
from __future__ import annotations
### SqliteProvider
from typing import TYPE_CHECKING, Any
Stores all checkpoints in a single SQLite database file. Better for high-frequency checkpointing and avoids many small files.
from crewai.events.event_bus import crewai_event_bus
from crewai.events.types.llm_events import LLMCallCompletedEvent
```python
from crewai import Crew, CheckpointConfig
from crewai.state import SqliteProvider
if TYPE_CHECKING:
from crewai.state.runtime import RuntimeState
crew = Crew(
agents=[...],
tasks=[...],
checkpoint=CheckpointConfig(
location="./.checkpoints.db",
provider=SqliteProvider(),
max_checkpoints=50,
),
)
```
WAL journal mode is enabled for concurrent read access.
@crewai_event_bus.on(LLMCallCompletedEvent)
async def on_llm_done_async(source: Any, event: LLMCallCompletedEvent, state: RuntimeState) -> None:
path = await state.acheckpoint("./my_checkpoints")
print(f"Saved checkpoint: {path}")
```
</CodeGroup>
## Event Types
A `state` argument is supplied automatically when the handler takes three parameters. See [Event Listeners](/en/concepts/event-listener) for the full event catalog.
</Accordion>
The `on_events` field accepts any combination of event type strings. Common choices:
<Accordion title="Browse, resume, and fork from the CLI" icon="terminal">
```bash
crewai checkpoint
crewai checkpoint --location ./my_checkpoints
crewai checkpoint --location ./.checkpoints.db
```
| Use Case | Events |
|:---------|:-------|
| After each task (Crew) | `["task_completed"]` |
| After each flow method | `["method_execution_finished"]` |
| After agent execution | `["agent_execution_completed"]`, `["lite_agent_execution_completed"]` |
| On crew completion only | `["crew_kickoff_completed"]` |
| After every LLM call | `["llm_call_completed"]` |
| On everything | `["*"]` |
<Frame caption="Checkpoint tree — branches and forks nest under their parent.">
<img src="/images/checkpoint-tui-tree.png" alt="Checkpoint TUI tree view" />
</Frame>
The left panel groups checkpoints by branch; forks nest under their parent. Selecting a checkpoint opens the detail panel with metadata, entity state, and task progress. **Resume** continues the run; **Fork** starts a new branch.
<Frame caption="Overview tab — metadata, entity state, and run summary.">
<img src="/images/checkpoint-tui-detail-overview.png" alt="Checkpoint detail overview tab" />
</Frame>
The detail panel exposes two editable areas:
- **Inputs** — original kickoff inputs, pre-filled and editable.
<Frame>
<img src="/images/checkpoint-tui-detail-inputs.png" alt="Editable kickoff inputs" />
</Frame>
- **Task outputs** — outputs of completed tasks. Editing an output and hitting **Fork** invalidates downstream tasks so they re-run against the modified context.
<Frame>
<img src="/images/checkpoint-tui-detail-tasks.png" alt="Editable task outputs" />
</Frame>
<Frame caption="Fork view — confirm a new branch from the selected checkpoint.">
<img src="/images/checkpoint-tui-details-fork.png" alt="Fork confirmation panel" />
</Frame>
<Tip>
Useful for "what if" exploration: fork, tweak, observe.
</Tip>
</Accordion>
<Accordion title="Inspect checkpoints without the TUI" icon="magnifying-glass">
```bash
crewai checkpoint list ./my_checkpoints
crewai checkpoint info ./my_checkpoints/<file>.json
crewai checkpoint info ./.checkpoints.db
```
</Accordion>
</AccordionGroup>
## Reference
### `CheckpointConfig`
<ParamField path="location" type="str" default='"./.checkpoints"'>
Storage destination. A directory for `JsonProvider`, a database file path for `SqliteProvider`.
</ParamField>
<ParamField path="on_events" type='list[CheckpointEventType | Literal["*"]]' default='["task_completed"]'>
Event types that trigger a checkpoint. `CheckpointEventType` is a `Literal` — your type checker will autocomplete and reject unsupported values. See [event types](#event-types) for the full list.
</ParamField>
<ParamField path="provider" type="BaseProvider" default="JsonProvider()">
Storage backend. Either `JsonProvider` or `SqliteProvider`.
</ParamField>
<ParamField path="max_checkpoints" type="int | None" default="None">
Maximum checkpoints to retain. Oldest are pruned after each write.
</ParamField>
<ParamField path="restore_from" type="Path | str | None" default="None">
Checkpoint to restore from when passed via `from_checkpoint`.
</ParamField>
### `checkpoint` field values
Accepted by `Crew`, `Flow`, and `Agent`.
<ParamField path="None" type="default">
Inherit from parent.
</ParamField>
<ParamField path="True" type="bool">
Enable with defaults.
</ParamField>
<ParamField path="False" type="bool">
Explicit opt-out. Stops inheritance.
</ParamField>
<ParamField path="CheckpointConfig(...)" type="CheckpointConfig">
Custom configuration.
</ParamField>
### Event types
`on_events` accepts any combination of `CheckpointEventType` values. The default `["task_completed"]` writes one checkpoint per finished task; `["*"]` matches every event.
<Warning>
Using `["*"]` or high-frequency events like `llm_call_completed` will write many checkpoint files and may impact performance. Use `max_checkpoints` to limit disk usage.
`["*"]` and high-frequency events like `llm_call_completed` write many checkpoints and can degrade performance. Pair them with `max_checkpoints`.
</Warning>
## Manual Checkpointing
<Expandable title="All supported events">
For full control, register your own event handler and call `state.checkpoint()` directly:
- **Task** — `task_started`, `task_completed`, `task_failed`, `task_evaluation`
- **Crew** — `crew_kickoff_started`, `crew_kickoff_completed`, `crew_kickoff_failed`, `crew_train_started`, `crew_train_completed`, `crew_train_failed`, `crew_test_started`, `crew_test_completed`, `crew_test_failed`, `crew_test_result`
- **Agent** — `agent_execution_started`, `agent_execution_completed`, `agent_execution_error`, `lite_agent_execution_started`, `lite_agent_execution_completed`, `lite_agent_execution_error`, `agent_evaluation_started`, `agent_evaluation_completed`, `agent_evaluation_failed`
- **Flow** — `flow_created`, `flow_started`, `flow_finished`, `flow_paused`, `method_execution_started`, `method_execution_finished`, `method_execution_failed`, `method_execution_paused`, `human_feedback_requested`, `human_feedback_received`, `flow_input_requested`, `flow_input_received`
- **LLM** — `llm_call_started`, `llm_call_completed`, `llm_call_failed`, `llm_stream_chunk`, `llm_thinking_chunk`
- **LLM Guardrail** — `llm_guardrail_started`, `llm_guardrail_completed`, `llm_guardrail_failed`
- **Tool** — `tool_usage_started`, `tool_usage_finished`, `tool_usage_error`, `tool_validate_input_error`, `tool_selection_error`, `tool_execution_error`
- **Memory** — `memory_save_started`, `memory_save_completed`, `memory_save_failed`, `memory_query_started`, `memory_query_completed`, `memory_query_failed`, `memory_retrieval_started`, `memory_retrieval_completed`, `memory_retrieval_failed`
- **Knowledge** — `knowledge_search_query_started`, `knowledge_search_query_completed`, `knowledge_query_started`, `knowledge_query_completed`, `knowledge_query_failed`, `knowledge_search_query_failed`
- **Reasoning** — `agent_reasoning_started`, `agent_reasoning_completed`, `agent_reasoning_failed`
- **MCP** — `mcp_connection_started`, `mcp_connection_completed`, `mcp_connection_failed`, `mcp_tool_execution_started`, `mcp_tool_execution_completed`, `mcp_tool_execution_failed`, `mcp_config_fetch_failed`
- **Observation** — `step_observation_started`, `step_observation_completed`, `step_observation_failed`, `plan_refinement`, `plan_replan_triggered`, `goal_achieved_early`
- **Skill** — `skill_discovery_started`, `skill_discovery_completed`, `skill_loaded`, `skill_activated`, `skill_load_failed`
- **Logging** — `agent_logs_started`, `agent_logs_execution`
- **A2A** — `a2a_delegation_started`, `a2a_delegation_completed`, `a2a_conversation_started`, `a2a_conversation_completed`, `a2a_message_sent`, `a2a_response_received`, `a2a_polling_started`, `a2a_polling_status`, `a2a_push_notification_registered`, `a2a_push_notification_received`, `a2a_push_notification_sent`, `a2a_push_notification_timeout`, `a2a_streaming_started`, `a2a_streaming_chunk`, `a2a_agent_card_fetched`, `a2a_authentication_failed`, `a2a_artifact_received`, `a2a_connection_error`, `a2a_server_task_started`, `a2a_server_task_completed`, `a2a_server_task_canceled`, `a2a_server_task_failed`, `a2a_parallel_delegation_started`, `a2a_parallel_delegation_completed`, `a2a_transport_negotiated`, `a2a_content_type_negotiated`, `a2a_context_created`, `a2a_context_expired`, `a2a_context_idle`, `a2a_context_completed`, `a2a_context_pruned`
- **System signals** — `SIGTERM`, `SIGINT`, `SIGHUP`, `SIGTSTP`, `SIGCONT`
- **Wildcard** — `"*"` matches every event.
```python
from crewai.events.event_bus import crewai_event_bus
from crewai.events.types.llm_events import LLMCallCompletedEvent
</Expandable>
# Sync handler
@crewai_event_bus.on(LLMCallCompletedEvent)
def on_llm_done(source, event, state):
path = state.checkpoint("./my_checkpoints")
print(f"Saved checkpoint: {path}")
### Storage providers
# Async handler
@crewai_event_bus.on(LLMCallCompletedEvent)
async def on_llm_done_async(source, event, state):
path = await state.acheckpoint("./my_checkpoints")
print(f"Saved checkpoint: {path}")
```
<ParamField path="JsonProvider" type="provider">
One file per checkpoint, named `<timestamp>_<uuid>.json` inside `location`.
</ParamField>
The `state` argument is the `RuntimeState` passed automatically by the event bus when your handler accepts 3 parameters. You can register handlers on any event type listed in the [Event Listeners](/en/concepts/event-listener) documentation.
<ParamField path="SqliteProvider" type="provider">
Single database file at `location` with WAL journaling.
</ParamField>
Checkpointing is best-effort: if a checkpoint write fails, the error is logged but execution continues uninterrupted.
### CLI
## CLI
The `crewai checkpoint` command gives you a TUI for browsing, inspecting, resuming, and forking checkpoints. It auto-detects whether your checkpoints are JSON files or a SQLite database.
```bash
# Launch the TUI — auto-detects .checkpoints/ or .checkpoints.db
crewai checkpoint
# Point at a specific location
crewai checkpoint --location ./my_checkpoints
crewai checkpoint --location ./.checkpoints.db
```
<Frame>
<img src="/images/checkpointing.png" alt="Checkpoint TUI" />
</Frame>
The left panel is a tree view. Checkpoints are grouped by branch, and forks nest under the checkpoint they diverged from. Select a checkpoint to see its metadata, entity state, and task progress in the detail panel. Hit **Resume** to pick up where it left off, or **Fork** to start a new branch from that point.
### Editing inputs and task outputs
When a checkpoint is selected, the detail panel shows:
- **Inputs** — if the original kickoff had inputs (e.g. `{topic}`), they appear as editable fields pre-filled with the original values. Change them before resuming or forking.
- **Task outputs** — completed tasks show their output in editable text areas. Edit a task's output to change the context that downstream tasks receive. When you modify a task output and hit Fork, all subsequent tasks are invalidated and re-run with the new context.
This is useful for "what if" exploration — fork from a checkpoint, tweak a task's result, and see how it changes downstream behavior.
### Subcommands
```bash
# List all checkpoints
crewai checkpoint list ./my_checkpoints
# Inspect a specific checkpoint
crewai checkpoint info ./my_checkpoints/20260407T120000_abc123.json
# Inspect latest in a SQLite database
crewai checkpoint info ./.checkpoints.db
```
| Command | Purpose |
|:--------|:--------|
| `crewai checkpoint` | Launch the TUI; auto-detect storage. |
| `crewai checkpoint --location <path>` | Launch the TUI against a specific location. |
| `crewai checkpoint list <path>` | List checkpoints. |
| `crewai checkpoint info <path>` | Inspect a checkpoint file or the latest entry in a SQLite database. |

View File

@@ -52,6 +52,8 @@ crewai create crew my_new_crew
crewai create flow my_new_flow
```
By default, `crewai create crew` creates a JSON-first crew project with `crew.jsonc` and `agents/*.jsonc`. Use `crewai create crew my_new_crew --classic` only when you want the older Python/YAML scaffold with `crew.py`, `config/agents.yaml`, and `config/tasks.yaml`.
### 2. Version
Show the installed version of CrewAI.
@@ -185,7 +187,20 @@ crewai chat
Ensure you execute these commands from your CrewAI project's root directory.
</Note>
<Note>
IMPORTANT: Set the `chat_llm` property in your `crew.py` file to enable this command.
IMPORTANT: Set the `chat_llm` property in your crew definition to enable this command.
For JSON-first crews, add it to `crew.jsonc`:
```jsonc
{
"name": "My Crew",
"agents": ["researcher"],
"tasks": [],
"chat_llm": "openai/gpt-4o"
}
```
For classic Python/YAML crews, set it in `crew.py`:
```python
@crew
@@ -336,7 +351,7 @@ Notes:
### 12. API Keys
When running `crewai create crew` command, the CLI will show you a list of available LLM providers to choose from, followed by model selection for your chosen provider.
When running the `crewai create crew` command, the CLI shows a list of available LLM providers, followed by model selection for your chosen provider. The selected model is saved in the generated `.env` file and each generated agent JSONC file can set its own `llm`.
Once you've selected an LLM provider and model, you will be prompted for API keys.

View File

@@ -48,108 +48,74 @@ A crew in crewAI represents a collaborative group of agents working together to
## Creating Crews
There are two ways to create crews in CrewAI: using **YAML configuration (recommended)** or defining them **directly in code**.
There are two common ways to create crews in CrewAI: using **JSONC project configuration (recommended for new crews)** or defining them **directly in code**.
### YAML Configuration (Recommended)
### JSONC Configuration (Recommended)
Using YAML configuration provides a cleaner, more maintainable way to define crews and is consistent with how agents and tasks are defined in CrewAI projects.
New projects created with `crewai create crew <name>` use `crew.jsonc` for crew-level settings and tasks, plus one file per agent in `agents/`.
After creating your CrewAI project as outlined in the [Installation](/en/installation) section, you can define your crew in a class that inherits from `CrewBase` and uses decorators to define agents, tasks, and the crew itself.
`crewai run` automatically detects `crew.jsonc` or `crew.json`, loads the referenced agents, prompts for missing placeholders, and kicks off the crew.
#### Example Crew Class with Decorators
#### Example `crew.jsonc`
```python code
from crewai import Agent, Crew, Task, Process
from crewai.project import CrewBase, agent, task, crew, before_kickoff, after_kickoff
from crewai.agents.agent_builder.base_agent import BaseAgent
from typing import List
@CrewBase
class YourCrewName:
"""Description of your crew"""
agents: List[BaseAgent]
tasks: List[Task]
# Paths to your YAML configuration files
# To see an example agent and task defined in YAML, checkout the following:
# - Task: https://docs.crewai.com/concepts/tasks#yaml-configuration-recommended
# - Agents: https://docs.crewai.com/concepts/agents#yaml-configuration-recommended
agents_config = 'config/agents.yaml'
tasks_config = 'config/tasks.yaml'
@before_kickoff
def prepare_inputs(self, inputs):
# Modify inputs before the crew starts
inputs['additional_data'] = "Some extra information"
return inputs
@after_kickoff
def process_output(self, output):
# Modify output after the crew finishes
output.raw += "\nProcessed after kickoff."
return output
@agent
def agent_one(self) -> Agent:
return Agent(
config=self.agents_config['agent_one'], # type: ignore[index]
verbose=True
)
@agent
def agent_two(self) -> Agent:
return Agent(
config=self.agents_config['agent_two'], # type: ignore[index]
verbose=True
)
@task
def task_one(self) -> Task:
return Task(
config=self.tasks_config['task_one'] # type: ignore[index]
)
@task
def task_two(self) -> Task:
return Task(
config=self.tasks_config['task_two'] # type: ignore[index]
)
@crew
def crew(self) -> Crew:
return Crew(
agents=self.agents, # Automatically collected by the @agent decorator
tasks=self.tasks, # Automatically collected by the @task decorator.
process=Process.sequential,
verbose=True,
)
```jsonc crew.jsonc
{
"name": "Market Research Crew",
"agents": ["researcher", "analyst"],
"tasks": [
{
"name": "research",
"description": "Research {topic} and collect the most relevant facts.",
"expected_output": "Structured research notes about {topic}.",
"agent": "researcher"
},
{
"name": "analysis",
"description": "Analyze the research and write a concise report.",
"expected_output": "A markdown report with findings and recommendations.",
"agent": "analyst",
"context": ["research"],
"output_file": "output/report.md"
}
],
"process": "sequential",
"verbose": true,
"memory": true,
"inputs": {
"topic": "AI Agents"
}
}
```
How to run the above code:
Each string in `agents` resolves to `agents/<name>.jsonc` first, then `agents/<name>.json`.
```python code
YourCrewName().crew().kickoff(inputs={"any": "input here"})
```jsonc agents/researcher.jsonc
{
"role": "{topic} Senior Researcher",
"goal": "Find accurate and current information about {topic}.",
"backstory": "You are a careful researcher who cites clear evidence.",
"llm": "openai/gpt-4o",
"tools": ["SerperDevTool"]
}
```
<Note>
Tasks will be executed in the order they are defined.
Tasks run in the order they appear in `tasks` when `process` is `"sequential"`.
</Note>
The `CrewBase` class, along with these decorators, automates the collection of agents and tasks, reducing the need for manual management.
For hierarchical crews, set `"process": "hierarchical"` and provide either `manager_llm` or `manager_agent`. A `manager_agent` can reference an `agents/<name>.jsonc` file that is not included in the top-level `agents` list.
#### Decorators overview from `annotations.py`
JSON crew definitions support crew-level fields such as `process`, `verbose`, `memory`, `cache`, `max_rpm`, `planning`, `planning_llm`, `manager_llm`, `manager_agent`, `function_calling_llm`, `output_log_file`, `stream`, `tracing`, `before_kickoff_callbacks`, and `after_kickoff_callbacks`.
CrewAI provides several decorators in the `annotations.py` file that are used to mark methods within your crew class for special handling:
Python callbacks and custom classes use `{"python": "module.attribute"}`. Custom tools use `"custom:<name>"` and load `tools/<name>.py` at runtime.
- `@CrewBase`: Marks the class as a crew base class.
- `@agent`: Denotes a method that returns an `Agent` object.
- `@task`: Denotes a method that returns a `Task` object.
- `@crew`: Denotes the method that returns the `Crew` object.
- `@before_kickoff`: (Optional) Marks a method to be executed before the crew starts.
- `@after_kickoff`: (Optional) Marks a method to be executed after the crew finishes.
<Warning>
Only run JSON crew projects from sources you trust. `custom:<name>` tools and `{"python": "module.attribute"}` references execute local Python code when the crew loads.
</Warning>
These decorators help in organizing your crew's structure and automatically collecting agents and tasks without manually listing them.
### Classic Python/YAML Configuration
Classic projects created with `crewai create crew <name> --classic` use `crew.py`, `config/agents.yaml`, `config/tasks.yaml`, and the `@CrewBase`, `@agent`, `@task`, and `@crew` decorators. That pattern remains supported and is documented in [Using Annotations](/en/learn/using-annotations).
### Direct Code Definition (Alternative)

View File

@@ -226,6 +226,49 @@ After the Flow has run, you can access the final state to see the updates made b
By ensuring that the final method's output is returned and providing access to the state, CrewAI Flows make it easy to integrate the results of your AI workflows into larger applications or systems,
while also maintaining and accessing the state throughout the Flow's execution.
## Flow Usage Metrics
After a Flow execution completes, you can access the `usage_metrics` property to view aggregated token usage across **every LLM call** made during the run — including calls from every Crew the Flow orchestrated, calls inside Agent tools, and bare `LLM.call(...)` invocations from Flow methods. This is the SDK-side equivalent of the totals shown in the CrewAI Enterprise UI.
```python Code
from crewai import LLM
from crewai.flow.flow import Flow, listen, start
class UsageMetricsFlow(Flow):
@start()
def run_first_crew(self):
self.state.first_result = FirstCrew().crew().kickoff()
@listen(run_first_crew)
def call_llm_directly(self):
# Bare LLM call — still counted by flow.usage_metrics
llm = LLM(model="openai/gpt-4o-mini")
self.state.summary = llm.call("Summarize the key takeaways.")
@listen(call_llm_directly)
def run_second_crew(self):
self.state.second_result = SecondCrew().crew().kickoff()
flow = UsageMetricsFlow()
flow.kickoff()
print(flow.usage_metrics)
# UsageMetrics(total_tokens=8579, prompt_tokens=6210, completion_tokens=2369,
# cached_prompt_tokens=0, reasoning_tokens=0,
# cache_creation_tokens=0, successful_requests=5)
```
<Note>
`flow.usage_metrics` is **not** the same as `flow.kickoff().token_usage`. The
latter returns the `CrewOutput.token_usage` of the **last** `@listen` method
that returned a `CrewOutput`, which means it only reflects the final Crew and
ignores prior Crews and bare `LLM.call(...)` invocations entirely. Use
`flow.usage_metrics` whenever you need the **full** token rollup for the Flow
execution.
</Note>
Each entry in the returned [`UsageMetrics`](https://github.com/crewAIInc/crewAI/blob/main/lib/crewai/src/crewai/types/usage_metrics.py) is the sum across all LLM calls made within a single `flow.kickoff()` invocation. Counters reset on the next `kickoff()` call (or on each iteration of `kickoff_for_each`), so successive runs don't double-count. The property is safe to read at any point after `kickoff()` completes; reading it during execution returns the partial total accumulated so far.
## Flow State Management
Managing state effectively is crucial for building reliable and maintainable AI workflows. CrewAI Flows provides robust mechanisms for both unstructured and structured state management,
@@ -788,7 +831,7 @@ You can generate a new CrewAI project that includes all the scaffolding needed t
crewai create flow name_of_flow
```
This command will generate a new CrewAI project with the necessary folder structure. The generated project includes a prebuilt crew called `poem_crew` that is already working. You can use this crew as a template by copying, pasting, and editing it to create other crews.
This command will generate a new CrewAI project with the necessary folder structure. The generated project includes a prebuilt crew called `poem_crew` that is already working. The starter embedded crew uses the classic Python/YAML layout; new standalone crews created with `crewai create crew` use the JSON-first layout.
### Folder Structure
@@ -812,13 +855,35 @@ After running the `crewai create flow name_of_flow` command, you will see a fold
### Building Your Crews
In the `crews` folder, you can define multiple crews. Each crew will have its own folder containing configuration files and the crew definition file. For example, the `poem_crew` folder contains:
In the `crews` folder, you can define multiple crews. The generated `poem_crew` uses the classic embedded-crew structure:
- `config/agents.yaml`: Defines the agents for the crew.
- `config/tasks.yaml`: Defines the tasks for the crew.
- `poem_crew.py`: Contains the crew definition, including agents, tasks, and the crew itself.
You can copy, paste, and edit the `poem_crew` to create other crews.
You can copy, paste, and edit the `poem_crew` to create other classic embedded crews.
For JSON-first embedded crews, use a folder with `crew.jsonc` and `agents/*.jsonc` instead:
```text
crews/
└── research_crew/
├── agents/
│ └── researcher.jsonc
└── crew.jsonc
```
Then load it from a Flow step:
```python
from pathlib import Path
from crewai.project import load_crew
crew, default_inputs = load_crew(
Path(__file__).parent / "crews" / "research_crew" / "crew.jsonc"
)
result = crew.kickoff(inputs={**default_inputs, "topic": "AI Agents"})
```
### Connecting Crews in `main.py`

View File

@@ -107,7 +107,7 @@ There are different places in CrewAI code where you can specify the model to use
</Tabs>
<Info>
CrewAI provides native SDK integrations for OpenAI, Anthropic, Google (Gemini API), Azure, and AWS Bedrock — no extra install needed beyond the provider-specific extras (e.g. `uv add "crewai[openai]"`).
CrewAI provides native SDK integrations for OpenAI, Anthropic, Google (Gemini API), Azure, AWS Bedrock, and Snowflake Cortex — no extra install needed beyond the provider-specific extras (e.g. `uv add "crewai[openai]"`).
All other providers are powered by **LiteLLM**. If you plan to use any of them, add it as a dependency to your project:
```bash
@@ -291,6 +291,55 @@ In this section, you'll find detailed examples that help you select, configure,
```
</Accordion>
<Accordion title="Snowflake Cortex">
CrewAI provides native integration with the Snowflake Cortex REST API through its OpenAI-compatible Chat Completions endpoint. This avoids LiteLLM fallback for `snowflake/...` models. Snowflake Cortex currently supports Chat Completions only in CrewAI, so use the default `api` mode and do not set `api="responses"`.
```toml Code
# Required
SNOWFLAKE_PAT=<your-programmatic-access-token>
SNOWFLAKE_ACCOUNT_URL=https://<account-identifier>.snowflakecomputing.com
# Alternative account configuration
SNOWFLAKE_ACCOUNT=<account-identifier>
```
**Basic Usage:**
```python Code
from crewai import LLM
llm = LLM(
model="snowflake/openai-gpt-4.1",
temperature=0.7,
max_completion_tokens=1024,
)
```
**Claude Models on Cortex:**
```python Code
from crewai import LLM
llm = LLM(
model="snowflake/claude-sonnet-4-5",
max_completion_tokens=1024,
stream=True,
)
```
**Supported Environment Variables:**
- `SNOWFLAKE_PAT`, `SNOWFLAKE_TOKEN`, or `SNOWFLAKE_JWT`: token used as the Bearer credential
- `SNOWFLAKE_ACCOUNT_URL`: full Snowflake account URL
- `SNOWFLAKE_ACCOUNT`, `SNOWFLAKE_ACCOUNT_ID`, or `SNOWFLAKE_ACCOUNT_IDENTIFIER`: account identifier used to build the account URL
Snowflake REST requests use the user's default Snowflake role. Make sure that role has `SNOWFLAKE.CORTEX_USER` or `SNOWFLAKE.CORTEX_REST_API_USER`. Database, schema, warehouse, and explicit role parameters are not required by the Cortex REST Chat Completions endpoint.
**Features:**
- Native provider selection with `model="snowflake/<model-name>"`
- Streaming and non-streaming Chat Completions only; `api="responses"` is not supported
- Token usage tracking
- Function calling for Snowflake-hosted OpenAI and Claude models
- Automatic removal of invalid trailing assistant prefill for Snowflake Claude models
</Accordion>
<Accordion title="Anthropic">
CrewAI provides native integration with Anthropic through the Anthropic Python SDK.
@@ -903,6 +952,61 @@ In this section, you'll find detailed examples that help you select, configure,
```
</Accordion>
<Accordion title="NVIDIA Nemotron">
NVIDIA Nemotron models are designed for demanding agentic workloads, including complex reasoning, long-context analysis, tool use, multilingual tasks, and high-stakes RAG.
The `NVIDIA-Nemotron-3-Ultra-550B-A55B-NVFP4` model is a frontier-scale open-weight model from NVIDIA with 550B total parameters and 55B active parameters. It uses a LatentMoE architecture that combines Mamba-2, MoE, Attention, and Multi-Token Prediction (MTP), and supports context lengths up to 1M tokens.
<Info>
`NVIDIA-Nemotron-3-Ultra-550B-A55B-NVFP4` is a very large model. NVIDIA lists minimum serving requirements of 4x GB200, 4x B200, 4x GB300, 4x B300, or 8x H100 GPUs. For most CrewAI users, the recommended path is to use NVIDIA NIM or another OpenAI-compatible hosted endpoint rather than running it locally.
</Info>
**Hosted NVIDIA NIM usage:**
```toml Code
NVIDIA_API_KEY=<your-api-key>
```
```python Code
from crewai import LLM
llm = LLM(
model="nvidia_nim/nvidia/nvidia-nemotron-3-ultra-550b-a55b",
temperature=0.2,
max_tokens=4096,
)
```
**Self-hosted OpenAI-compatible endpoint:**
```python Code
from crewai import LLM
llm = LLM(
model="openai/nvidia-nemotron-3-ultra-550b-a55b-nvfp4",
base_url="https://your-nemotron-endpoint.example.com/v1",
api_key="your-api-key",
temperature=0.2,
max_tokens=4096,
)
```
**Model details:**
| Model | Context Window | Best For |
|-------|----------------|----------|
| `nvidia/NVIDIA-Nemotron-3-Ultra-550B-A55B-NVFP4` | Up to 1M tokens | Frontier reasoning, complex agentic workflows, long-context analysis, tool use, multilingual reasoning, and high-stakes RAG |
**Supported languages:** English, French, Spanish, Italian, German, Japanese, Korean, Hindi, Brazilian Portuguese, and Chinese.
**Reasoning mode:** Nemotron 3 Ultra supports configurable reasoning via its chat template using `enable_thinking=True` or `enable_thinking=False`. If you are using a hosted endpoint, check your provider's documentation for how that flag is exposed.
For model details, license, and deployment guidance, see the [NVIDIA Nemotron 3 Ultra model card](https://huggingface.co/nvidia/NVIDIA-Nemotron-3-Ultra-550B-A55B-NVFP4).
**Note:** Hosted NVIDIA NIM usage uses LiteLLM. Add it as a dependency to your project:
```bash
uv add 'crewai[litellm]'
```
</Accordion>
<Accordion title="Local NVIDIA NIM Deployed using WSL2">
NVIDIA NIM enables you to run powerful LLMs locally on your Windows machine using WSL2 (Windows Subsystem for Linux).

View File

@@ -101,7 +101,7 @@ crew = Crew(
)
```
When `memory=True`, the crew creates a default `Memory()` and passes the crew's `embedder` configuration through automatically. All agents in the crew share the crew's memory unless an agent has its own.
When `memory=True`, the crew creates a default `Memory()` and passes the crew's `embedder` configuration through automatically. All agents in the crew share the crew's memory unless an agent has its own. Without a custom `embedder`, memory uses OpenAI `text-embedding-3-large` embeddings.
After each task, the crew automatically extracts discrete facts from the task output and stores them. Before each task, the agent recalls relevant context from memory and injects it into the task prompt.
@@ -515,7 +515,11 @@ memory = Memory(
## Embedder Configuration
Memory needs an embedding model to convert text into vectors for semantic search. You can configure this in three ways.
Memory needs an embedding model to convert text into vectors for semantic search. By default, `Memory()` uses OpenAI `text-embedding-3-large` embeddings, which produce 3072-dimensional vectors. Set `OPENAI_API_KEY` for the default path, or configure a custom embedder in one of three ways.
<Warning>
Existing local memory stores created with 1536-dimensional embeddings, such as `text-embedding-3-small` or `text-embedding-ada-002`, may not be compatible with the `text-embedding-3-large` default. This applies to both the OpenAI and Azure OpenAI providers — Azure's default embedding model also changed from `text-embedding-ada-002` to `text-embedding-3-large`. If local testing fails with an embedding dimension mismatch, reset memory with `crewai reset-memories -m`, delete the local memory storage directory, or explicitly configure the older embedder model until you migrate.
</Warning>
### Passing to Memory Directly
@@ -523,7 +527,7 @@ Memory needs an embedding model to convert text into vectors for semantic search
from crewai import Memory
# As a config dict
memory = Memory(embedder={"provider": "openai", "config": {"model_name": "text-embedding-3-small"}})
memory = Memory(embedder={"provider": "openai", "config": {"model_name": "text-embedding-3-large"}})
# As a pre-built callable
from crewai.rag.embeddings.factory import build_embedder
@@ -542,7 +546,7 @@ crew = Crew(
agents=[...],
tasks=[...],
memory=True,
embedder={"provider": "openai", "config": {"model_name": "text-embedding-3-small"}},
embedder={"provider": "openai", "config": {"model_name": "text-embedding-3-large"}},
)
```
@@ -554,7 +558,7 @@ crew = Crew(
memory = Memory(embedder={
"provider": "openai",
"config": {
"model_name": "text-embedding-3-small",
"model_name": "text-embedding-3-large",
# "api_key": "sk-...", # or set OPENAI_API_KEY env var
},
})
@@ -701,9 +705,9 @@ memory = Memory(embedder=my_embedder)
| Provider | Key | Typical Model | Notes |
| :--- | :--- | :--- | :--- |
| OpenAI | `openai` | `text-embedding-3-small` | Default. Set `OPENAI_API_KEY`. |
| OpenAI | `openai` | `text-embedding-3-large` | Default. Set `OPENAI_API_KEY`. |
| Ollama | `ollama` | `mxbai-embed-large` | Local, no API key needed. |
| Azure OpenAI | `azure` | `text-embedding-ada-002` | Requires `deployment_id`. |
| Azure OpenAI | `azure` | `text-embedding-3-large` | Default model. Requires `deployment_id`. |
| Google AI | `google-generativeai` | `gemini-embedding-001` | Set `GOOGLE_API_KEY`. |
| Google Vertex | `google-vertex` | `gemini-embedding-001` | Requires `project_id`. |
| Cohere | `cohere` | `embed-english-v3.0` | Strong multilingual support. |
@@ -836,6 +840,9 @@ class MemoryMonitor(BaseEventListener):
**Background save errors in logs?**
- Memory saves run in a background thread. Errors are emitted as `MemorySaveFailedEvent` but don't crash the agent. Check logs for the root cause (usually LLM or embedder connection issues).
**Embedding dimension mismatch?**
- Existing local memory stores may have been created with a different embedding model. The default OpenAI memory embedder is now `text-embedding-3-large` (3072 dimensions), while older stores commonly used 1536-dimensional embeddings. For local testing, run `crewai reset-memories -m`, delete the local memory storage directory, or configure the previous embedder model explicitly.
**Concurrent write conflicts?**
- LanceDB operations are serialized with a shared lock and retried automatically on conflict. This handles multiple `Memory` instances pointing at the same database (e.g. agent memory + crew memory). No action needed.
@@ -862,7 +869,7 @@ All configuration is passed as keyword arguments to `Memory(...)`. Every paramet
| :--- | :--- | :--- |
| `llm` | `"gpt-4o-mini"` | LLM for analysis (model name or `BaseLLM` instance). |
| `storage` | `"lancedb"` | Storage backend (`"lancedb"`, a path string, or a `StorageBackend` instance). |
| `embedder` | `None` (OpenAI default) | Embedder (config dict, callable, or `None` for default OpenAI). |
| `embedder` | `None` (OpenAI `text-embedding-3-large`) | Embedder (config dict, callable, or `None` for default OpenAI). |
| `recency_weight` | `0.3` | Weight for recency in composite score. |
| `semantic_weight` | `0.5` | Weight for semantic similarity in composite score. |
| `importance_weight` | `0.2` | Weight for importance in composite score. |

View File

@@ -16,7 +16,6 @@ mode: "wide"
- **Sequential**: Executes tasks sequentially, ensuring tasks are completed in an orderly progression.
- **Hierarchical**: Organizes tasks in a managerial hierarchy, where tasks are delegated and executed based on a structured chain of command. A manager language model (`manager_llm`) or a custom manager agent (`manager_agent`) must be specified in the crew to enable the hierarchical process, facilitating the creation and management of tasks by the manager.
- **Consensual Process (Planned)**: Aiming for collaborative decision-making among agents on task execution, this process type introduces a democratic approach to task management within CrewAI. It is planned for future development and is not currently implemented in the codebase.
## The Role of Processes in Teamwork
Processes enable individual agents to operate as a cohesive unit, streamlining their efforts to achieve common objectives with efficiency and coherence.
@@ -59,9 +58,9 @@ Emulates a corporate hierarchy, CrewAI allows specifying a custom manager agent
## Process Class: Detailed Overview
The `Process` class is implemented as an enumeration (`Enum`), ensuring type safety and restricting process values to the defined types (`sequential`, `hierarchical`). The consensual process is planned for future inclusion, emphasizing our commitment to continuous development and innovation.
The `Process` class is implemented as an enumeration (`Enum`), ensuring type safety and restricting process values to the defined types (`sequential`, `hierarchical`).
## Conclusion
The structured collaboration facilitated by processes within CrewAI is crucial for enabling systematic teamwork among agents.
This documentation has been updated to reflect the latest features, enhancements, and the planned integration of the Consensual Process, ensuring users have access to the most current and comprehensive information.
This documentation has been updated to reflect the latest features and enhancements, ensuring users have access to the most current and comprehensive information.

View File

@@ -74,104 +74,54 @@ crew = Crew(
## Creating Tasks
There are two ways to create tasks in CrewAI: using **YAML configuration (recommended)** or defining them **directly in code**.
There are two common ways to create tasks in CrewAI: using **JSONC project configuration (recommended for new crews)** or defining them **directly in code**.
### YAML Configuration (Recommended)
### JSONC Configuration (Recommended)
Using YAML configuration provides a cleaner, more maintainable way to define tasks. We strongly recommend using this approach to define tasks in your CrewAI projects.
New projects created with `crewai create crew <name>` define tasks in `crew.jsonc`. The `agents` array points to files in `agents/`, and the `tasks` array defines the ordered work the crew should run.
After creating your CrewAI project as outlined in the [Installation](/en/installation) section, navigate to the `src/latest_ai_development/config/tasks.yaml` file and modify the template to match your specific task requirements.
After creating your CrewAI project as outlined in the [Installation](/en/installation) section, edit the generated `crew.jsonc`.
<Note>
Variables in your YAML files (like `{topic}`) will be replaced with values from your inputs when running the crew:
```python Code
crew.kickoff(inputs={'topic': 'AI Agents'})
```
Use `{placeholder}` values in task `description`, `expected_output`, and `output_file`. Put defaults in the top-level `inputs` object; `crewai run` prompts for any missing values.
</Note>
Here's an example of how to configure tasks using YAML:
Here's an example `crew.jsonc` with two ordered tasks:
````yaml tasks.yaml
research_task:
description: >
Conduct a thorough research about {topic}
Make sure you find any interesting and relevant information given
the current year is 2025.
expected_output: >
A list with 10 bullet points of the most relevant information about {topic}
agent: researcher
reporting_task:
description: >
Review the context you got and expand each topic into a full section for a report.
Make sure the report is detailed and contains any and all relevant information.
expected_output: >
A fully fledge reports with the mains topics, each with a full section of information.
Formatted as markdown without '```'
agent: reporting_analyst
markdown: true
output_file: report.md
````jsonc crew.jsonc
{
"name": "Research Crew",
"agents": ["researcher", "reporting_analyst"],
"tasks": [
{
"name": "research_task",
"description": "Conduct thorough research about {topic}. Include current and relevant information.",
"expected_output": "A list of the most relevant information about {topic}.",
"agent": "researcher"
},
{
"name": "reporting_task",
"description": "Review the research and expand it into a detailed report.",
"expected_output": "A polished markdown report without fenced code blocks.",
"agent": "reporting_analyst",
"context": ["research_task"],
"markdown": true,
"output_file": "report.md"
}
],
"inputs": {
"topic": "AI Agents"
}
}
````
To use this YAML configuration in your code, create a crew class that inherits from `CrewBase`:
Each task must include `description` and `expected_output`. The `agent` value should match an agent name listed in `agents`. `context` is a list of prior task names; forward references are rejected so sequential context stays explicit.
```python crew.py
# src/latest_ai_development/crew.py
Task entries support any public `Task` field. Common fields include `name`, `agent`, `context`, `output_file`, `tools`, `human_input`, `async_execution`, `guardrail`, `guardrails`, `guardrail_max_retries`, `markdown`, `input_files`, `output_json`, `output_pydantic`, `response_model`, and `converter_cls`. Use `"type": "ConditionalTask"` with a `condition` field for conditional tasks.
from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task
from crewai_tools import SerperDevTool
### Classic YAML Configuration
@CrewBase
class LatestAiDevelopmentCrew():
"""LatestAiDevelopment crew"""
@agent
def researcher(self) -> Agent:
return Agent(
config=self.agents_config['researcher'], # type: ignore[index]
verbose=True,
tools=[SerperDevTool()]
)
@agent
def reporting_analyst(self) -> Agent:
return Agent(
config=self.agents_config['reporting_analyst'], # type: ignore[index]
verbose=True
)
@task
def research_task(self) -> Task:
return Task(
config=self.tasks_config['research_task'] # type: ignore[index]
)
@task
def reporting_task(self) -> Task:
return Task(
config=self.tasks_config['reporting_task'] # type: ignore[index]
)
@crew
def crew(self) -> Crew:
return Crew(
agents=[
self.researcher(),
self.reporting_analyst()
],
tasks=[
self.research_task(),
self.reporting_task()
],
process=Process.sequential
)
```
<Note>
The names you use in your YAML files (`agents.yaml` and `tasks.yaml`) should
match the method names in your Python code.
</Note>
Classic projects created with `crewai create crew <name> --classic` use `config/tasks.yaml` and a `@CrewBase` class in `crew.py`. This remains supported for existing YAML projects or teams that prefer decorator-based Python wiring.
### Direct Code Definition (Alternative)

View File

@@ -187,7 +187,7 @@ flowchart TD
- **Filename Requirement:** Ensure that the filename ends with `.pkl`. The code will raise a `ValueError` if this condition is not met.
- **Error Handling:** The code handles subprocess errors and unexpected exceptions, providing error messages to the user.
- Trained guidance is applied at prompt time; it does not modify your Python/YAML agent configuration.
- Agents automatically load trained suggestions from a file named `trained_agents_data.pkl` located in the current working directory. If you trained to a different filename, either rename it to `trained_agents_data.pkl` before running, or adjust the loader in code.
- Agents automatically load trained suggestions from a file named `trained_agents_data.pkl` located in the current working directory. If you trained to a different filename, pass that path with `Crew(trained_agents_file="my_custom_trained.pkl")`, set `CREWAI_TRAINED_AGENTS_FILE`, or use `crewai run -f my_custom_trained.pkl`.
- You can change the output filename when calling `crewai train` with `-f/--filename`. Absolute paths are supported if you want to save outside the CWD.
It is important to note that the training process may take some time, depending on the complexity of your agents and will also require your feedback on each iteration.

View File

@@ -0,0 +1,112 @@
---
title: "Watch your Automations"
description: "Watch fleet health, LLM consumption, and per-automation behavior from the Automations tab."
sidebarTitle: "Monitoring"
icon: "gauge"
mode: "wide"
---
<Info>
**ACP (Beta) Docs Navigation**
- [Overview](/en/enterprise/features/agent-control-plane/overview)
- **Monitoring** *(you are here)*
- [Rules](/en/enterprise/features/agent-control-plane/rules)
</Info>
## Overview
The **Automations** tab is the read-only operations view of the [Agent Control Plane](/en/enterprise/features/agent-control-plane/overview). It combines two metric cards, an interactive sankey, and two sub-tables — **Automations** and **Consumption** — that you can search, filter, and sort.
<Frame>
![Agent Control Plane overview](/images/enterprise/acp-overview-automations-sankey.png)
</Frame>
All charts and tables respect the **Last 24 hours / Last Week / Last 30 days** selector at the top right. Deltas compare the selected window against the previous one of the same length.
<Note>
Rows only show data for deployments on **crewAI v1.13 or higher** — older deployments appear in the *"We've detected N other automations that we can't display"* banner under the sankey and contribute zero metrics until they're updated and re-deployed. See [Overview — Requirements](/en/enterprise/features/agent-control-plane/overview#requirements).
</Note>
## Dashboard
The header of the page has two metric cards and an interactive sankey. Clicking either card switches the sankey between two modes:
- **Health mode** — `Total Automations → status buckets (Critical / Warning / Healthy)`. Click a bucket to filter the Automations table to just those deployments.
- **Consumption mode** — `Model Providers → Automations → Total Cost`. Click a provider to filter the Consumption table to that provider.
| Card | What it shows |
|------|---------------|
| **Automations** | `active` automations (and total count), total `errors` in the window, currently `active executions` (and total in the window), with a delta vs the previous period. |
| **Consumption** | Total `cost` and `tokens used`, with a cost delta vs the previous period. |
<Frame>
![Overview with consumption sankey](/images/enterprise/acp-overview-consumption-sankey.png)
</Frame>
## Automations table
The **Automations** sub-tab is the per-deployment breakdown of fleet health. Each row is one deployed crew or flow.
<Frame>
![Automations table with health status breakdown](/images/enterprise/acp-automations-table.png)
</Frame>
| Column | What it shows |
|--------|---------------|
| **Automation** | Deployment name and any tags assigned to it (e.g. `production`, `financial`). |
| **Last execution** | Time since the most recent run. |
| **Health Status Breakdown** | Stacked bar of `Critical` / `Warning` / `Healthy` percentages for executions in the window. |
| **Executions with Errors** | Total failed executions in the window. |
| **PII detection applied** | `Yes` if a per-deployment PII config or a matching [PII rule](/en/enterprise/features/agent-control-plane/rules) is active. |
| **Executions** | Total executions in the window. |
| **Last updated** | When the deployment was last re-deployed. |
| **Crew Version** | The `crewai` version reported by the deployment. An info icon next to versions below `1.13` flags rows that can't contribute metrics. |
Search by name, filter by `Status` (`Healthy` / `Warning` / `Critical`), and sort by any column header. Click a deployment name to open the **Automation panel** (see below).
## Consumption table
The **Consumption** sub-tab is the per-deployment breakdown of LLM spend and token usage.
<Frame>
![Consumption table broken down by LLM provider](/images/enterprise/acp-consumption-table.png)
</Frame>
| Column | What it shows |
|--------|---------------|
| **Automation** | Deployment name. |
| **Last execution** | Time since the most recent run. |
| **Tokens used** | One row per LLM provider used by this automation, with the delta vs the previous period. |
| **Cost** | Cost per LLM provider, with the delta vs the previous period. |
| **Total cost** | Sum across all providers, with the delta. |
| **Executions** | Total executions in the window. |
| **Last updated** | When the deployment was last re-deployed. |
| **Crew Version** | The `crewai` version reported by the deployment. |
Filter by **LLM provider** and sort by `Cost`, `Executions`, or `Last run`.
<Info>
**Empty cells (`—` or `$0.00`) usually mean the deployment is below crewAI v1.13.** In the screenshot above, *Automation F* (`1.7.0`) and *Automation I* (`1.12.2`) show blanks for tokens and cost — their executions still run, but they don't emit the provider-level telemetry that powers this table. Update and re-deploy these crews to start collecting consumption data.
</Info>
## Related
<CardGroup cols={2}>
<Card title="Agent Control Plane — Overview" icon="book-open" href="/en/enterprise/features/agent-control-plane/overview">
What ACP is, requirements, plan tiers, and RBAC.
</Card>
<Card title="Agent Control Plane — Rules" icon="shield-check" href="/en/enterprise/features/agent-control-plane/rules">
Apply organization-wide PII Redaction rules across many automations.
</Card>
<Card title="Traces" icon="timeline" href="/en/enterprise/features/traces">
Drill into a single execution to see agent reasoning, tool calls, and token usage.
</Card>
<Card title="Deploy to AMP" icon="rocket" href="/en/enterprise/guides/deploy-to-amp">
Deploy a crew on a crewAI version that supports the Agent Control Plane.
</Card>
</CardGroup>
<Card title="Need Help?" icon="headset" href="mailto:support@crewai.com">
Contact our support team for help interpreting metrics in the Agent Control Plane.
</Card>

View File

@@ -0,0 +1,82 @@
---
title: Agent Control Plane Overview
description: "Single operations hub for live automations — fleet health, LLM consumption, and organization-wide policies in one place."
sidebarTitle: Overview
icon: "book-open"
---
<Info>
**ACP (Beta) Docs Navigation**
- **Overview** *(you are here)*
- [Monitoring](/en/enterprise/features/agent-control-plane/monitoring)
- [Rules](/en/enterprise/features/agent-control-plane/rules)
</Info>
## Overview
The **Agent Control Plane** (ACP) is the operations hub for everything you have running on CrewAI AMP. It is a single screen — split into **Automations** and **Rules** tabs — that lets your team:
- Monitor the **health** of every live automation (crew or flow), with `Critical` / `Warning` / `Healthy` breakdowns and execution counts.
- Track **LLM consumption** — tokens and cost — per automation, per provider, and per model, with a delta vs the previous period.
- Drill into any single automation or model provider for time-series charts and per-provider breakdowns.
- Apply organization-wide **Rules** (today: PII Redaction) across many automations at once instead of editing each deployment individually.
<Frame>
![Agent Control Plane overview](/images/enterprise/acp-overview-automations-sankey.png)
</Frame>
<Note>
The Agent Control Plane is currently labeled **Beta** in CrewAI Platform.
</Note>
The two tabs answer two different questions:
- **Automations** — *"How is my fleet behaving right now, and what is it costing me?"* See [Monitoring](/en/enterprise/features/agent-control-plane/monitoring).
- **Rules** — *"How do I enforce a policy (e.g. PII redaction) across many deployments without re-deploying each one?"* See [Rules](/en/enterprise/features/agent-control-plane/rules).
## Requirements
<Warning>
**crewAI v1.13 or higher** is required for an automation to populate any data on this page — health, executions, errors, tokens, and cost all flow through telemetry that lit up in `crewai==1.13`. Older deployments appear in the *"We've detected N other automations that we can't display"* banner and contribute zero rows until they are updated and re-deployed.
</Warning>
<Warning>
**Enterprise Plan or Ultra Plan** is required to create or edit [Rules](/en/enterprise/features/agent-control-plane/rules). Lower-tier organizations can open the Rules tab and view existing rules, but the editor renders read-only with an "Enterprise" lock pill and the alert *"PII Redaction rules require an Enterprise plan."* Monitoring (the Automations tab) is available on all plans where the feature is enabled.
</Warning>
- The **Agent Control Plane** feature must be enabled for your organization. If you don't see it in the sidebar, ask your account owner to request enablement.
- Inside ACP, [RBAC](/en/enterprise/features/rbac) governs access: `read` to view the dashboard and rules, `manage` to create, edit, toggle, or delete rules.
- All charts and tables can be scoped to the **Last 24 hours**, **Last Week**, or **Last 30 days** using the time selector at the top right. Deltas (`↑ 8 vs yesterday`, `↓ $20.57 vs yesterday`, etc.) compare the selected window against the previous one of the same length.
## What you can do here
<CardGroup cols={2}>
<Card title="Monitoring" icon="gauge" href="/en/enterprise/features/agent-control-plane/monitoring">
Watch fleet health and LLM spend with metric cards, an interactive sankey, per-automation tables, and drill-down side panels for any automation or provider.
</Card>
<Card title="Rules" icon="shield-check" href="/en/enterprise/features/agent-control-plane/rules">
Apply organization-wide PII Redaction policies scoped by tools and tags. Changes take effect on the next execution — no re-deploy required.
</Card>
</CardGroup>
## Related
<CardGroup cols={2}>
<Card title="Traces" icon="timeline" href="/en/enterprise/features/traces">
Drill into a single execution to see agent reasoning, tool calls, and token usage.
</Card>
<Card title="RBAC" icon="users" href="/en/enterprise/features/rbac">
Manage who can read the Agent Control Plane and who can edit rules.
</Card>
<Card title="PII Redaction for Traces" icon="lock" href="/en/enterprise/features/pii-trace-redactions">
Entity catalog and per-deployment PII configuration referenced by Rules.
</Card>
<Card title="Deploy to AMP" icon="rocket" href="/en/enterprise/guides/deploy-to-amp">
Deploy a crew on a crewAI version that supports the Agent Control Plane.
</Card>
</CardGroup>
<Card title="Need Help?" icon="headset" href="mailto:support@crewai.com">
Contact our support team for help interpreting metrics or designing rules.
</Card>

View File

@@ -0,0 +1,122 @@
---
title: "Set up the Rules"
description: "Apply organization-wide policies across many automations from a single place."
sidebarTitle: "Rules"
icon: "shield-check"
mode: "wide"
---
<Info>
**ACP (Beta) Docs Navigation**
- [Overview](/en/enterprise/features/agent-control-plane/overview)
- [Monitoring](/en/enterprise/features/agent-control-plane/monitoring)
- **Rules** *(you are here)*
</Info>
## Overview
Rules let you apply policies — today: **PII Redaction** — across many automations at once, instead of configuring each deployment individually. Open the **Rules** tab in the [Agent Control Plane](/en/enterprise/features/agent-control-plane/overview) to manage them.
<Frame>
![Rules list](/images/enterprise/acp-rules-list.png)
</Frame>
Each rule card shows the name, description, the **scope** the rule applies to (selected tools and tags), and a count of **engaged automations** — deployments that currently match the scope. The toggle on the right enables or disables the rule without deleting it.
## Requirements
<Warning>
**Enterprise Plan or Ultra Plan** is required to create or edit PII Redaction rules. Lower-tier organizations can still open the Rules tab and view existing rules, but the editor renders read-only with an "Enterprise" lock pill and the alert *"PII Redaction rules require an Enterprise plan."* — contact your account owner or sales to upgrade.
</Warning>
- The **Agent Control Plane** feature must be enabled for your organization. See [Overview — Requirements](/en/enterprise/features/agent-control-plane/overview#requirements).
- The `manage` [RBAC permission](/en/enterprise/features/rbac) on Agent Control Plane is required to create, edit, toggle, or delete rules. The `read` permission is enough to view them.
- All rule changes are versioned for auditing.
## Available rule types
| Type | What it does |
|------|---------------|
| **PII Redaction** | Applies PII redaction to executions of every matching automation, using the same entity catalog and custom recognizers documented in [PII Redaction for Traces](/en/enterprise/features/pii-trace-redactions). |
More rule types will be added over time.
## Creating a rule
<Frame>
<img src="/images/enterprise/acp-rules-edit-side-panel.png" alt="Rule edit side panel with conditions and PII mask type" width="450" />
</Frame>
<Steps>
<Step title="Open the editor">
Click **+ Create new** at the top-right of the Rules tab, or **View Details** on an existing rule card.
</Step>
<Step title="Name and describe the rule">
Give the rule a clear name (e.g. *Mask PII (CC)*) and a description explaining when it applies. Both show up on the rule card and in the Engaged Automations modal.
</Step>
<Step title="Pick the type">
Today only **PII Redaction** is available.
</Step>
<Step title="Set the conditions">
Conditions decide which automations the rule engages with. Both are optional and use **set-equality** semantics:
- **Tools** — only automations whose tool set **exactly matches** the selected tools will engage. Picks from Studio apps, MCPs, OSS tools, and Tool Repository registry tools.
- **Automations** — only automations whose tag set **exactly matches** the selected tags will engage.
Leaving a picker empty means "no filter on this dimension". Leaving both empty means the rule applies to **every** automation in the organization.
</Step>
<Step title="Configure the PII Mask Type table">
Check each entity type you want covered and choose **Mask** (replaces with the entity label, e.g. `<CREDIT_CARD>`) or **Redact** (removes the matched text entirely). See [PII Redaction for Traces](/en/enterprise/features/pii-trace-redactions) for the full entity catalog and how to add organization-level custom recognizers.
</Step>
<Step title="Save">
The rule applies to **future** executions of every engaged automation as soon as you save. No re-deploy is needed.
</Step>
</Steps>
## Engaged automations
Click **Engaged N automations** on any rule card to see exactly which deployments the rule is currently matching, along with each one's last execution.
<Frame>
![Engaged automations modal](/images/enterprise/acp-rules-engaged-modal.png)
</Frame>
This is the fastest way to sanity-check a rule's scope before enabling it — for example, to confirm that a rule scoped to the `production` tag isn't accidentally matching a staging deployment.
## Org-wide rules vs per-deployment settings
PII Redaction can be configured in two places:
- **Per-deployment** — under **Settings → PII Protection** on each individual deployment ([guide](/en/enterprise/features/pii-trace-redactions))
- **Org-wide** — as a Rule on this page
When an enabled org-wide rule's scope matches a deployment, the rule's entity configuration **overrides** the deployment-owned PII settings for that deployment's executions — the rule becomes the single source of truth while it's attached. Disable or detach the rule (or change its scope so it no longer matches) and the deployment falls back to its own PII Protection settings.
Prefer org-wide rules when you want to enforce a consistent policy across many deployments; reserve per-deployment configuration for one-off exceptions.
## Related
<CardGroup cols={2}>
<Card title="Agent Control Plane — Overview" icon="book-open" href="/en/enterprise/features/agent-control-plane/overview">
What ACP is, requirements, plan tiers, and RBAC.
</Card>
<Card title="Agent Control Plane — Monitoring" icon="gauge" href="/en/enterprise/features/agent-control-plane/monitoring">
Monitor automations and LLM consumption across your fleet.
</Card>
<Card title="PII Redaction for Traces" icon="lock" href="/en/enterprise/features/pii-trace-redactions">
Entity catalog, custom recognizers, and per-deployment configuration.
</Card>
<Card title="RBAC" icon="users" href="/en/enterprise/features/rbac">
Manage who can create or edit rules.
</Card>
</CardGroup>
<Card title="Need Help?" icon="headset" href="mailto:support@crewai.com">
Contact our support team for help designing rules for your organization.
</Card>

View File

@@ -26,10 +26,10 @@ Before running this verification:
## Step 1 — Scaffold a Verification Crew
Create a new crew project. The CrewAI CLI scaffolds the structure:
Create a classic crew project because this example wires a Python tool through `crew.py`:
```bash
crewai create crew rotation_verifier --skip_provider
crewai create crew rotation_verifier --classic --skip_provider
cd rotation_verifier
```

View File

@@ -24,15 +24,39 @@ Telemetry data follows the [OpenTelemetry GenAI semantic conventions](https://op
1. In CrewAI AMP, go to **Settings** > **OpenTelemetry Collectors**.
2. Click **Add Collector**.
3. Select an integration type — **OpenTelemetry Traces** or **OpenTelemetry Logs**.
4. Configure the connection:
- **Endpoint** — Your collector's OTLP endpoint (e.g., `https://otel-collector.example.com:4317`).
- **Service Name** — A name to identify this service in your observability platform.
- **Custom Headers** *(optional)* — Add authentication or routing headers as key-value pairs.
- **Certificate** *(optional)* — Provide a TLS certificate if your collector requires one.
5. Click **Save**.
3. Select an integration:
- **OpenTelemetry Traces** and **OpenTelemetry Logs** — export to any OTLP-compatible collector or backend.
- **Datadog** — send traces straight to Datadog's OTLP intake, no separate collector or Datadog Agent required.
4. Configure the connection. The fields depend on the integration you selected:
<Frame>![OpenTelemetry Collector Configuration](/images/crewai-otel-collector-config.png)</Frame>
<Tabs>
<Tab title="OpenTelemetry Traces / Logs">
**OpenTelemetry Traces** and **OpenTelemetry Logs** are separate integrations that share the same fields — pick the one matching the signal you want to export.
- **Endpoint** — Your collector's OTLP endpoint (e.g., `https://otel-collector.example.com:4317`).
- **Service Name** — A name to identify this service in your observability platform.
- **Custom Headers** *(optional)* — Add authentication or routing headers as key-value pairs.
- **Certificate** *(optional)* — Provide a TLS certificate if your collector requires one.
<Frame>![OpenTelemetry collector configuration](/images/crewai-otel-collector-opentelemetry.png)</Frame>
</Tab>
<Tab title="Datadog">
- **Datadog Site Domain** — Your Datadog site's OTLP host only, with no protocol or path. CrewAI builds the full HTTPS OTLP endpoint for you. Use the host that matches your [Datadog site](https://docs.datadoghq.com/getting_started/site/):
- `otlp.datadoghq.com` (US1)
- `otlp.us3.datadoghq.com` (US3)
- `otlp.us5.datadoghq.com` (US5)
- `otlp.datadoghq.eu` (EU1)
- `otlp.ap1.datadoghq.com` (AP1)
- **API Key** — Your Datadog API key. See [how to create one](https://docs.datadoghq.com/account_management/api-app-keys/#api-keys).
The Datadog integration exports **traces**.
<Frame>![Datadog collector configuration](/images/crewai-otel-collector-datadog.png)</Frame>
</Tab>
</Tabs>
5. *(optional)* Click **Test Connection** to verify CrewAI can reach the endpoint with the credentials you provided.
6. Click **Save**.
<Tip>
You can add multiple collectors — for example, one for traces and another for logs, or send to different backends for different purposes.

View File

@@ -164,6 +164,12 @@ You need to push your crew to a GitHub repository. If you haven't created a crew
![Select Repository](/images/enterprise/select-repo.png)
</Frame>
<Tip>
If your Crew or Flow is inside a monorepo subfolder, expand **Advanced**
and set a working directory before deploying. See
[Monorepo Deployments](/en/enterprise/guides/monorepo-deployments).
</Tip>
</Step>
<Step title="Set Environment Variables">
@@ -368,17 +374,17 @@ git push
**Solution**: Verify your project matches the expected structure:
- **Both Crews and Flows**: Must have entry point at `src/project_name/main.py`
- **Crews**: Use a `run()` function as entry point
- **Flows**: Use a `kickoff()` function as entry point
- **JSON-first Crews**: Keep `crew.jsonc` or `crew.json` and `agents/` at the project root
- **Classic Crews**: Use `src/project_name/main.py` with a `run()` entry point
- **Flows**: Use `src/project_name/main.py` with a `kickoff()` entry point
See [Prepare for Deployment](/en/enterprise/guides/prepare-for-deployment) for detailed structure diagrams.
#### Missing CrewBase Decorator
#### Missing CrewBase Decorator in a Classic Crew
**Symptom**: "Crew not found", "Config not found", or agent/task configuration errors
**Solution**: Ensure **all** crew classes use the `@CrewBase` decorator:
**Solution**: For classic Python/YAML crews, ensure all crew classes use the `@CrewBase` decorator. JSON-first crews do not need this decorator.
```python
from crewai.project import CrewBase, agent, crew, task
@@ -398,8 +404,8 @@ class YourCrew():
```
<Info>
This applies to standalone Crews AND crews embedded inside Flow projects.
Every crew class needs the decorator.
This applies to classic Python crew classes, including classic crews embedded inside Flow projects.
JSON-first crews are validated from `crew.jsonc` and `agents/` instead.
</Info>
#### Incorrect pyproject.toml Type
@@ -436,8 +442,8 @@ type = "flow"
**Solution**:
1. Check the execution logs in the AMP dashboard (Traces tab)
2. Verify all tools have required API keys configured
3. Ensure agent configurations in `agents.yaml` are valid
4. Check task configurations in `tasks.yaml` for syntax errors
3. For JSON-first crews, validate `crew.jsonc` and the referenced files in `agents/`
4. For classic crews, ensure `agents.yaml` and `tasks.yaml` are valid
<Card title="Need Help?" icon="headset" href="mailto:support@crewai.com">
Contact our support team for assistance with deployment issues or questions

View File

@@ -0,0 +1,229 @@
---
title: "Monorepo Deployments"
description: "Deploy a Crew or Flow from a subfolder in a larger repository"
icon: "folder-tree"
mode: "wide"
---
<Note>
Use a working directory when your Crew or Flow lives inside a larger
repository. CrewAI AMP validates, builds, tests, and runs the automation from
that subfolder instead of the repository root.
</Note>
## When to Use This
Monorepo deployments are useful when one repository contains multiple
automations, shared packages, or other application code:
```text
company-ai/
|-- uv.lock
|-- packages/
| `-- shared_tools/
`-- crews/
|-- support_agent/
| |-- pyproject.toml
| |-- crew.jsonc
| `-- agents/
| `-- support_agent.jsonc
`-- research_flow/
|-- pyproject.toml
`-- src/
`-- research_flow/
`-- main.py
```
To deploy `support_agent`, set the working directory to:
```text
crews/support_agent
```
AMP still pulls or uploads the whole repository, but it treats the selected
folder as the automation project root.
## What the Working Directory Controls
When a working directory is set, AMP uses that folder for:
- Project validation, including `pyproject.toml`, JSON crew files, and any classic Crew or Flow entry point
- Dependency installation with `uv`
- The running process working directory
- The `CREW_ROOT_DIR` environment variable
Leaving the field empty keeps the existing behavior and uses the repository
root.
## Supported Sources
You can set a working directory when creating a deployment from:
- A connected GitHub repository
- A Git repository configured in AMP
- A ZIP upload
<Info>
Configure working directories in the AMP web interface. The
`crewai deploy create` CLI flow does not prompt for this field.
</Info>
You can also add or change the working directory on an existing deployment from
the deployment's **Settings** page. The change takes effect on the next deploy.
<Warning>
Working directories and auto-deploy cannot be used together. If a deployment
has a working directory, auto-deploy is disabled for that deployment. Turn
auto-deploy off before setting a working directory.
</Warning>
## Configure a New Deployment
<Steps>
<Step title="Open Deploy from Code">
In CrewAI AMP, create a new deployment and choose your source: GitHub, Git
Repository, or ZIP upload.
</Step>
<Step title="Select the repository, branch, or ZIP file">
Choose the repository and branch that contain your monorepo, or upload a ZIP
file whose root contains the monorepo contents.
</Step>
<Step title="Open Advanced settings">
Expand the **Advanced** section in the deploy form.
</Step>
<Step title="Enter the working directory">
Enter the path from the repository root to the Crew or Flow project:
```text
crews/support_agent
```
Do not include a leading slash.
</Step>
<Step title="Deploy">
Add any required environment variables, then start the deployment.
</Step>
</Steps>
## Configure an Existing Deployment
<Steps>
<Step title="Open the deployment settings">
Go to your automation in AMP and open **Settings**.
</Step>
<Step title="Turn off auto-deploy if needed">
If auto-deploy is enabled, disable it first. The working directory field is
unavailable while auto-deploy is on.
</Step>
<Step title="Set the working directory">
In **Basic settings**, enter the subfolder path, such as:
```text
crews/support_agent
```
</Step>
<Step title="Redeploy">
Save the setting and redeploy the automation. The new working directory is
used on the next deploy.
</Step>
</Steps>
## Path Rules
The working directory must be a relative path inside the repository or ZIP root.
| Rule | Example |
|------|---------|
| Use a relative path | `crews/support_agent` |
| Do not start with `/` | `/crews/support_agent` is invalid |
| Do not use `.` or `..` path segments | `crews/../support_agent` is invalid |
| Use only letters, numbers, dashes, underscores, dots, and forward slashes | `crews/support agent` is invalid |
| Keep the path at 255 characters or fewer | Longer paths are rejected |
AMP trims leading and trailing whitespace, collapses repeated slashes, and
removes trailing slashes. A blank value uses the repository root.
## Lock Files and UV Workspaces
The selected folder must contain the automation's `pyproject.toml` and the
project files for its type:
- JSON-first crew: `crew.jsonc` or `crew.json`, plus `agents/`
- Classic crew or Flow: `src/` with the expected Python entry point
A `uv.lock` or `poetry.lock` file can live either in the selected folder or at
the repository root.
This supports both common lock-file layouts:
<Tabs>
<Tab title="Project lock file">
```text
company-ai/
`-- crews/
`-- support_agent/
|-- pyproject.toml
|-- uv.lock
|-- crew.jsonc
`-- agents/
`-- support_agent.jsonc
```
</Tab>
<Tab title="Workspace lock file">
```text
company-ai/
|-- uv.lock
|-- packages/
| `-- shared_tools/
`-- crews/
`-- support_agent/
|-- pyproject.toml
|-- crew.jsonc
`-- agents/
`-- support_agent.jsonc
```
</Tab>
</Tabs>
<Tip>
If your automation imports shared packages from elsewhere in the monorepo,
declare those packages in `pyproject.toml` using UV workspace, path, or source
configuration. AMP runs the automation from the selected folder, so shared
code should be installed as a dependency instead of relying on the repository
root being on the Python path.
</Tip>
## Troubleshooting
### Working Directory Not Found
Check that the path is relative to the repository or ZIP root. For ZIP uploads,
the ZIP contents must include the working directory path exactly as entered.
### Missing pyproject.toml
The working directory should point to the Crew or Flow project folder, not just
to a parent folder that contains several projects.
### Missing uv.lock or poetry.lock
Commit a lock file either in the selected project folder or in the repository
root. For UV workspaces, keeping `uv.lock` at the workspace root is supported.
### Auto-Deploy Is Unavailable
Auto-deploy is disabled while a working directory is set. Use manual redeploys
or trigger redeployments from CI/CD with the AMP API instead.
<Card title="Deploy to AMP" icon="rocket" href="/en/enterprise/guides/deploy-to-amp">
Continue with the deployment guide after choosing your monorepo working
directory.
</Card>

View File

@@ -24,7 +24,7 @@ Understanding which type you're deploying is essential because they have differe
<CardGroup cols={2}>
<Card title="Crew Projects" icon="users">
Standalone AI agent teams with `crew.py` defining agents and tasks. Best for focused, collaborative tasks.
Standalone AI agent teams. New crews are JSON-first with `crew.jsonc` and `agents/`; classic crews can still use `crew.py`.
</Card>
<Card title="Flow Projects" icon="diagram-project">
Orchestrated workflows with embedded crews in a `crews/` folder. Best for complex, multi-stage processes.
@@ -33,19 +33,19 @@ Understanding which type you're deploying is essential because they have differe
| Aspect | Crew | Flow |
|--------|------|------|
| **Project structure** | `src/project_name/` with `crew.py` | `src/project_name/` with `crews/` folder |
| **Main logic location** | `src/project_name/crew.py` | `src/project_name/main.py` (Flow class) |
| **Entry point function** | `run()` in `main.py` | `kickoff()` in `main.py` |
| **Project structure** | Project root with `crew.jsonc` and `agents/` | `src/project_name/` with `crews/` folder |
| **Main logic location** | `crew.jsonc` (classic: `src/project_name/crew.py`) | `src/project_name/main.py` (Flow class) |
| **Entry point function** | Loaded from `crew.jsonc` (classic: `run()` in `main.py`) | `kickoff()` in `main.py` |
| **pyproject.toml type** | `type = "crew"` | `type = "flow"` |
| **CLI create command** | `crewai create crew name` | `crewai create flow name` |
| **Config location** | `src/project_name/config/` | `src/project_name/crews/crew_name/config/` |
| **Config location** | `crew.jsonc`, `agents/`, optional `tools/` | `src/project_name/crews/crew_name/config/` or embedded JSON crew folders |
| **Can contain other crews** | No | Yes (in `crews/` folder) |
## Project Structure Reference
### Crew Project Structure
When you run `crewai create crew my_crew`, you get this structure:
When you run `crewai create crew my_crew`, you get the JSON-first structure:
```
my_crew/
@@ -54,24 +54,27 @@ my_crew/
├── README.md
├── .env
├── uv.lock # REQUIRED for deployment
── src/
└── my_crew/
├── __init__.py
├── main.py # Entry point with run() function
├── crew.py # Crew class with @CrewBase decorator
├── tools/
│ ├── custom_tool.py
│ └── __init__.py
└── config/
├── agents.yaml # Agent definitions
└── tasks.yaml # Task definitions
── crew.jsonc # Crew settings, tasks, process, inputs
├── agents/
└── researcher.jsonc # Agent definitions
├── tools/ # Optional custom:<name> tools
├── knowledge/
└── skills/
```
<Warning>
The nested `src/project_name/` structure is critical for Crews.
Placing files at the wrong level will cause deployment failures.
For JSON-first crews, keep `crew.jsonc`, `agents/`, `tools/`, `knowledge/`, and `skills/`
at the project root. Placing them under `src/` will prevent `crewai run` and deployment
validation from finding the crew definition.
</Warning>
<Info>
Classic projects created with `crewai create crew my_crew --classic` use the older
`src/project_name/crew.py`, `src/project_name/config/agents.yaml`, and
`src/project_name/config/tasks.yaml` layout. That layout remains supported for
decorator-based Python crews.
</Info>
### Flow Project Structure
When you run `crewai create flow my_flow`, you get this structure:
@@ -100,9 +103,9 @@ my_flow/
```
<Info>
Both Crews and Flows use the `src/project_name/` structure.
The key difference is that Flows have a `crews/` folder for embedded crews,
while Crews have `crew.py` directly in the project folder.
JSON-first standalone crews use project-root JSON files. Flows still use
`src/project_name/` and can contain either classic embedded crews or embedded
JSON crew folders loaded with `crewai.project.load_crew`.
</Info>
## Pre-Deployment Checklist
@@ -154,60 +157,91 @@ git commit -m "Add uv.lock for deployment"
git push
```
### 3. Validate CrewBase Decorator Usage
### 3. Validate the Crew Definition
**Every crew class must use the `@CrewBase` decorator.** This applies to:
<Tabs>
<Tab title="JSON-first Crews">
JSON-first crews must have a `crew.jsonc` or `crew.json` file at the project root.
The `agents` array must reference files in `agents/`, and each task should reference
a valid agent name.
- Standalone crew projects
- Crews embedded inside Flow projects
```jsonc crew.jsonc
{
"name": "Research Crew",
"agents": ["researcher"],
"tasks": [
{
"name": "research_task",
"description": "Research {topic}.",
"expected_output": "A concise report.",
"agent": "researcher"
}
],
"inputs": {
"topic": "AI Agents"
}
}
```
```python
from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task
from crewai.agents.agent_builder.base_agent import BaseAgent
from typing import List
Custom tools are referenced as `"custom:<name>"` and must be implemented in
`tools/<name>.py` with a `BaseTool` subclass.
</Tab>
<Tab title="Classic Python/YAML Crews">
Classic crews and Python crews embedded in Flows must use the `@CrewBase` decorator.
@CrewBase # This decorator is REQUIRED
class MyCrew():
"""My crew description"""
```python
from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task
from crewai.agents.agent_builder.base_agent import BaseAgent
from typing import List
agents: List[BaseAgent]
tasks: List[Task]
@CrewBase
class MyCrew():
"""My crew description"""
@agent
def my_agent(self) -> Agent:
return Agent(
config=self.agents_config['my_agent'], # type: ignore[index]
verbose=True
)
agents: List[BaseAgent]
tasks: List[Task]
@task
def my_task(self) -> Task:
return Task(
config=self.tasks_config['my_task'] # type: ignore[index]
)
@agent
def my_agent(self) -> Agent:
return Agent(
config=self.agents_config['my_agent'], # type: ignore[index]
verbose=True
)
@crew
def crew(self) -> Crew:
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True,
)
```
@task
def my_task(self) -> Task:
return Task(
config=self.tasks_config['my_task'] # type: ignore[index]
)
<Warning>
If you forget the `@CrewBase` decorator, your deployment will fail with
errors about missing agents or tasks configurations.
</Warning>
@crew
def crew(self) -> Crew:
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True,
)
```
</Tab>
</Tabs>
### 4. Check Project Entry Points
Both Crews and Flows have their entry point in `src/project_name/main.py`:
JSON-first standalone crews do not need a hand-written `src/project_name/main.py`; `crewai run`
and deployment packaging load `crew.jsonc` directly. Classic crews and Flows use Python entry
points:
<Tabs>
<Tab title="For Crews">
<Tab title="JSON-first Crews">
Run locally from the project root:
```bash
crewai run
```
</Tab>
<Tab title="Classic Crews">
The entry point uses a `run()` function:
```python
@@ -278,16 +312,17 @@ grep -A2 "\[tool.crewai\]" pyproject.toml
# 2. Verify uv.lock exists
ls -la uv.lock || echo "ERROR: uv.lock missing! Run 'uv lock'"
# 3. Verify src/ structure exists
ls -la src/*/main.py 2>/dev/null || echo "No main.py found in src/"
# 3. For JSON-first crews, verify crew.jsonc and agents/ exist
([ -f crew.jsonc ] || [ -f crew.json ]) || echo "No crew.jsonc or crew.json found"
test -d agents || echo "No agents/ directory found"
# 4. For Crews - verify crew.py exists
# 4. For classic Crews - verify crew.py exists
ls -la src/*/crew.py 2>/dev/null || echo "No crew.py (expected for Crews)"
# 5. For Flows - verify crews/ folder exists
ls -la src/*/crews/ 2>/dev/null || echo "No crews/ folder (expected for Flows)"
# 6. Check for CrewBase usage
# 6. For classic Python crews - check for CrewBase usage
grep -r "@CrewBase" . --include="*.py"
```
@@ -297,8 +332,9 @@ grep -r "@CrewBase" . --include="*.py"
|---------|---------|-----|
| Missing `uv.lock` | Build fails during dependency resolution | Run `uv lock` and commit |
| Wrong `type` in pyproject.toml | Build succeeds but runtime fails | Change to correct type |
| Missing `@CrewBase` decorator | "Config not found" errors | Add decorator to all crew classes |
| Files at root instead of `src/` | Entry point not found | Move to `src/project_name/` |
| Missing `crew.jsonc` or `agents/` in a JSON-first crew | Crew definition not found | Keep `crew.jsonc` and `agents/` at the project root |
| Missing `@CrewBase` decorator in a classic crew | "Config not found" errors | Add decorator to all classic crew classes |
| Classic files at root instead of `src/` | Entry point not found | Move classic Python files to `src/project_name/` |
| Missing `run()` or `kickoff()` | Cannot start automation | Add correct entry function |
## Next Steps

View File

@@ -0,0 +1,123 @@
---
title: Databricks Integration
description: "Connect CrewAI agents to Databricks Genie, SQL, Unity Catalog Functions, and Vector Search through Databricks managed MCP servers."
icon: "layer-group"
mode: "wide"
---
## Overview
Connect your CrewAI agents directly to your Databricks workspace through [Databricks managed MCP servers](https://docs.databricks.com/aws/en/generative-ai/mcp/managed-mcp). The Databricks integration lets your agents ask natural-language questions with **Genie**, run governed **SQL**, call **Unity Catalog Functions**, and retrieve documents with **Vector Search** — all without writing or hosting any connector code, and with Unity Catalog permissions enforced on every call.
Under the hood, the Databricks integration is a managed wrapper around CrewAI's [Custom MCP Server](/en/enterprise/guides/custom-mcp-server) support. Databricks exposes each capability as its own [Model Context Protocol](https://modelcontextprotocol.io/) endpoint, and CrewAI connects to them securely on your behalf. Because each server is added separately, you can enable exactly the capabilities your crews need.
## Key Capabilities
<CardGroup cols={2}>
<Card title="Genie" icon="comments">
Ask questions in plain language and get grounded answers from your data with [Genie](https://docs.databricks.com/aws/en/genie/), which queries Genie Spaces and Unity Catalog and links back to the Databricks UI.
</Card>
<Card title="Databricks SQL" icon="database">
Run governed SQL against your Databricks warehouses to query, transform, and author data pipelines directly from your agents.
</Card>
<Card title="Unity Catalog Functions" icon="function">
Invoke [Unity Catalog functions](https://docs.databricks.com/aws/en/udf/unity-catalog) to run predefined SQL and custom business logic as governed, reusable tools.
</Card>
<Card title="Vector Search" icon="magnifying-glass">
Retrieve relevant documents for RAG and knowledge workflows from [Mosaic AI Vector Search](https://docs.databricks.com/aws/en/generative-ai/vector-search) indexes using semantic similarity.
</Card>
</CardGroup>
Every server runs behind the Unity AI Gateway and enforces Unity Catalog access controls, so your agents only ever see the data and tools they're permitted to use.
## Prerequisites
Before using the Databricks integration, ensure you have:
- A [CrewAI AMP](https://app.crewai.com) account with an active subscription
- A Databricks workspace with the capabilities you want to expose (Genie Spaces, SQL warehouses, Unity Catalog functions, or Vector Search indexes)
- Appropriate [Unity Catalog privileges](https://docs.databricks.com/aws/en/data-governance/unity-catalog) on the underlying objects
- Your Databricks workspace hostname (e.g. `your-workspace.cloud.databricks.com`)
## Databricks Managed MCP Servers
Databricks publishes a separate managed MCP server for each capability. CrewAI exposes these as individual connections, each configured with your workspace host and the relevant Unity Catalog identifiers. The endpoints follow these patterns:
| Server | What it does | MCP URL pattern |
|--------|--------------|-----------------|
| **Genie** | Natural-language Q&A over a Genie Space | `https://<workspace-hostname>/api/2.0/mcp/genie/{genie_space_id}` |
| **Databricks SQL** | Execute SQL against your warehouses | `https://<workspace-hostname>/api/2.0/mcp/sql` |
| **Unity Catalog Functions** | Run registered UC functions | `https://<workspace-hostname>/api/2.0/mcp/functions/{catalog}/{schema}` |
| **Vector Search** | Query a Vector Search index | `https://<workspace-hostname>/api/2.0/mcp/vector-search/{catalog}/{schema}` |
<Note>
You don't construct these URLs by hand — CrewAI builds each endpoint from the workspace host and identifiers (Genie Space ID, or catalog/schema) you provide when configuring the connection. For the full specification and the latest endpoint details, see the [Databricks managed MCP documentation](https://docs.databricks.com/aws/en/generative-ai/mcp/managed-mcp).
</Note>
## Connecting Databricks in CrewAI AMP
<Frame>
<img src="/images/enterprise/databricks-configure.png" alt="Configure a Databricks managed MCP server in CrewAI AMP" />
</Frame>
Each Databricks capability — **Databricks Genie**, **Databricks SQL**, **Databricks Unity Catalog Functions**, and **Databricks Vector Search** — appears as its own MCP server under the Databricks group on the **Tools & Integrations** page. Configure the ones you need:
<Steps>
<Step title="Open Tools & Integrations">
Navigate to **Tools & Integrations** in the left sidebar of CrewAI AMP and locate the **Databricks** group in the Connections list. You'll see the Genie, SQL, Unity Catalog Functions, and Vector Search servers listed beneath it.
</Step>
<Step title="Configure a server">
Click **Configure** next to the capability you want to enable and provide its connection details:
- **Workspace Host** — your Databricks workspace hostname (e.g. `my-workspace.cloud.databricks.com`).
- **Genie** — the **Genie Space ID** to query.
- **Unity Catalog Functions** — the **catalog** and **schema** that contain your functions.
- **Vector Search** — the **catalog** and **schema** that contain your index.
- **Databricks SQL** — no additional identifiers; queries run against your workspace's SQL warehouses.
</Step>
<Step title="Choose an authentication method">
Select how CrewAI authenticates to Databricks. **OAuth** is recommended.
- **Use OAuth** — Connect securely using OAuth 2.0. Each user authenticates individually, and Databricks issues tokens scoped to the capability (`genie`, `sql`, `unity-catalog`, or `vector-search`). CrewAI handles the authorization flow and refreshes tokens automatically.
- **Use personal access token** — Authenticate with a [Databricks personal access token](https://docs.databricks.com/aws/en/dev-tools/auth/pat). Use a least-privileged identity to limit exposure.
</Step>
<Step title="Authenticate">
Complete authentication. Once connected, the server's tools become available to your crews. Repeat for any other Databricks capabilities you want to enable.
</Step>
</Steps>
<Tip>
Because each capability is a separate connection, you can mix and match — for example, enable Genie and Vector Search for a research crew while reserving SQL and Unity Catalog Functions for a data-engineering crew. Visibility settings let you control which team members can use each one.
</Tip>
## Using Databricks Tools in Your Crews
Once connected, the tools each MCP server exposes appear alongside built-in connections on the **Tools & Integrations** page. You can:
- **Assign tools to agents** in your crews just like any other CrewAI tool.
- **Manage visibility** to control which team members can use each connection.
- **Edit or remove** any connection at any time from the Connections list.
Your agents can now ask Genie for grounded answers, run SQL against your warehouses, call Unity Catalog functions, and search Vector Search indexes — with results flowing back into their reasoning automatically.
<Warning>
Databricks enforces governance through Unity Catalog and the Unity AI Gateway: a user can only discover and invoke tools their workspace identity is permitted to use. If a tool call fails, confirm the connecting user (or token identity) has the required Unity Catalog privileges on the Genie Space, warehouse, function, or index. Some Genie and SQL queries run asynchronously and may take a moment to return results.
</Warning>
## Learn More
<CardGroup cols={2}>
<Card title="Databricks Managed MCP Servers" icon="layer-group" href="https://docs.databricks.com/aws/en/generative-ai/mcp/managed-mcp">
Official Databricks documentation for the managed Genie, SQL, Unity Catalog Functions, and Vector Search MCP servers.
</Card>
<Card title="Custom MCP Servers in CrewAI" icon="plug" href="/en/enterprise/guides/custom-mcp-server">
Learn how CrewAI connects to any MCP server, the foundation the Databricks integration builds on.
</Card>
</CardGroup>
<Card title="Need Help?" icon="headset" href="mailto:support@crewai.com">
Contact our support team for assistance with the Databricks integration or troubleshooting.
</Card>

View File

@@ -17,15 +17,61 @@ Before using the Salesforce integration, ensure you have:
- A Salesforce account with appropriate permissions
- Connected your Salesforce account through the [Integrations page](https://app.crewai.com/integrations)
<Note>
Salesforce requires a **one-time admin install** of the CrewAI package in
your org before any user can connect. This is a Salesforce platform
requirement for all ExternalClientApp-based integrations as of the Spring
'26 release — not a CrewAI-specific step. The Connect Salesforce flow in
CrewAI AMP walks you through it the first time.
</Note>
## Setting Up Salesforce Integration
### 1. Connect Your Salesforce Account
1. Navigate to [CrewAI AMP Integrations](https://app.crewai.com/crewai_plus/connectors)
2. Find **Salesforce** in the Authentication Integrations section
3. Click **Connect** and complete the OAuth flow
4. Grant the necessary permissions for CRM and sales management
5. Copy your Enterprise Token from [Integration Settings](https://app.crewai.com/crewai_plus/settings/integrations)
1. Navigate to [CrewAI AMP Integrations](https://app.crewai.com/crewai_plus/unified_tools).
2. Find **Salesforce** in the Authentication Integrations section.
3. Click **Connect**.
What happens next depends on whether a Salesforce admin in your org has
already installed the CrewAI package:
- **Package already installed:** you're taken straight to the Salesforce
OAuth consent screen — approve it and you're connected.
- **Package not installed yet:** you'll see an **Install CrewAI in
Salesforce** page. Follow the one-time install steps below, then come
back to CrewAI AMP and click **Connect** again.
4. Grant the necessary permissions for CRM and sales management.
5. Copy your Enterprise Token from [Integration Settings](https://app.crewai.com/crewai_plus/settings/integrations).
#### One-time admin install (Salesforce admin only)
The first time anyone in your org clicks **Connect Salesforce**, CrewAI
redirects them to an install page that points at the CrewAI managed package.
A Salesforce admin needs to install it once for the whole org.
1. On the install page in CrewAI, click **Install in Salesforce**. (You can
also share the page URL with your admin — the install link works for
anyone who opens it.)
2. Sign in to Salesforce as an admin. For sandboxes, swap `login.salesforce.com`
for `test.salesforce.com` in the URL before opening it.
3. Choose **Install for All Users**, acknowledge the third-party app prompt,
and click **Install**.
4. In Salesforce Setup, search **External Client App Manager** → **CrewAI
App** → open the **Policies** tab → **Edit** and set:
- **Permitted Users:** All users may self-authorize
- **IP Relaxation:** Relax IP restrictions
- **Refresh Token Policy:** Refresh token is valid until revoked
5. Save.
6. Return to CrewAI AMP and click **Connect Salesforce** again. OAuth will
complete this time.
<Note>
**Not a Salesforce admin?** Forward the install page URL (or the install
link itself) to your Salesforce admin and ask them to complete the steps
above. Once they're done, return to CrewAI AMP and click **Connect** again.
</Note>
### 2. Install Required Package

View File

@@ -0,0 +1,134 @@
---
title: Snowflake Integration
description: "Connect CrewAI agents to Snowflake Cortex Analyst, Cortex Search, and SQL execution through the Snowflake-managed MCP server."
icon: "snowflake"
mode: "wide"
---
## Overview
Connect your CrewAI agents directly to your Snowflake data through the [Snowflake-managed MCP server](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp). The Snowflake integration lets your agents query structured data with **Cortex Analyst**, search unstructured data with **Cortex Search**, and run governed SQL against your warehouses — all without writing or hosting any connector code.
Under the hood, the Snowflake integration is a managed wrapper around CrewAI's [Custom MCP Server](/en/enterprise/guides/custom-mcp-server) support. Snowflake exposes its Cortex AI capabilities through a [Model Context Protocol](https://modelcontextprotocol.io/) endpoint, and CrewAI connects to it securely on your behalf. Any tool you expose on the Snowflake side — Cortex Analyst, Cortex Search, SQL execution, Cortex Agents, or your own custom tools — becomes available to your crews.
## Key Capabilities
<CardGroup cols={3}>
<Card title="Cortex Analyst" icon="chart-bar">
Ask questions in natural language and let [Cortex Analyst](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-analyst) generate and run SQL against your **structured** data using rich semantic models.
</Card>
<Card title="Cortex Search" icon="magnifying-glass">
Retrieve relevant **unstructured** data for RAG and knowledge workflows with [Cortex Search](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-search/cortex-search-overview), Snowflake's fully managed search service.
</Card>
<Card title="SQL Execution" icon="database">
Run governed SQL queries directly against your Snowflake warehouses, with configurable read-only mode, timeouts, and warehouse selection.
</Card>
</CardGroup>
Because the integration surfaces whatever tools your MCP server publishes, you can also expose **Cortex Agents** and **custom tools** (user-defined functions and stored procedures) to your CrewAI agents.
## Prerequisites
Before using the Snowflake integration, ensure you have:
- A [CrewAI AMP](https://app.crewai.com) account with an active subscription
- A Snowflake account with access to Cortex AI features
- A [Snowflake-managed MCP server](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp) configured with the tools you want to expose
- Appropriate Snowflake privileges (USAGE/SELECT) on the MCP server and its underlying objects
## Setting Up the Snowflake MCP Server
The Snowflake-managed MCP server runs inside your Snowflake account and defines which tools are available to external clients like CrewAI. Create one with the [`CREATE MCP SERVER`](https://docs.snowflake.com/en/sql-reference/sql/create-mcp-server) command, listing the Cortex Search services, Cortex Analyst semantic views, and SQL tools you want to expose.
```sql
CREATE MCP SERVER my_mcp_server
FROM SPECIFICATION $$
tools:
- name: "sales_analyst"
type: "CORTEX_ANALYST"
identifier: "MY_DATABASE.MY_SCHEMA.sales_semantic_view"
description: "Answer questions about sales metrics"
- name: "docs_search"
type: "CORTEX_SEARCH_SERVICE_QUERY"
identifier: "MY_DATABASE.MY_SCHEMA.support_docs_search"
description: "Search internal support documentation"
- name: "run_sql"
type: "SQL_EXECUTION"
description: "Execute read-only SQL queries"
$$;
```
<Note>
The MCP endpoint follows the format `https://<account_URL>/api/v2/databases/{database}/schemas/{schema}/mcp-servers/{name}`. CrewAI builds this URL automatically from the **Account URL**, **Database**, **Schema**, and **MCP Server Name** you provide when configuring the integration.
</Note>
For the complete specification — including Cortex Agents, custom tools, response-size limits, and governance options — see the [Snowflake-managed MCP server documentation](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp).
## Connecting Snowflake in CrewAI AMP
<Frame>
<img src="/images/enterprise/snowflake-configure.png" alt="Configure Snowflake integration in CrewAI AMP" />
</Frame>
<Steps>
<Step title="Open Tools & Integrations">
Navigate to **Tools & Integrations** in the left sidebar of CrewAI AMP, find **Snowflake** in the list of applications, and open its configuration panel.
</Step>
<Step title="Provide connection details">
Fill in the connection fields that CrewAI uses to reach your Snowflake MCP server:
| Field | Required | Description |
|-------|----------|-------------|
| **Name** | Yes | A descriptive name for this connection (defaults to `Snowflake`). |
| **Description** | No | An optional summary of what this connection provides. |
| **Account URL** | Yes | Your Snowflake account URL, e.g. `xy12345.us-east-1.snowflakecomputing.com`. |
| **Database** | Yes | The database that contains your MCP server (e.g. `MY_DATABASE`). |
| **Schema** | Yes | The schema that contains your MCP server (e.g. `MY_SCHEMA`). |
| **MCP Server Name** | Yes | The name of the MCP server object you created in Snowflake (e.g. `MY_MCP_SERVER`). |
</Step>
<Step title="Choose an authentication method">
Select how CrewAI authenticates to Snowflake. **OAuth** is recommended.
- **Use OAuth** — Connect securely using OAuth 2.0 for token-based authentication without sharing your credentials. CrewAI handles the full authorization flow and refreshes tokens automatically. Copy the **Redirect URI** shown in the form (`https://oauth.crewai.com/oauth/add`) and register it as an authorized redirect URI in your Snowflake [OAuth security integration](https://docs.snowflake.com/en/user-guide/oauth-custom).
- **Use personal access token** — Authenticate using a [programmatic access token](https://docs.snowflake.com/en/user-guide/programmatic-access-tokens) generated from your Snowflake account settings. Assign a least-privileged role to the token to limit exposure.
</Step>
<Step title="Authenticate">
Click **Authenticate**. For OAuth, you'll be redirected to Snowflake to authorize access. Once authenticated, the Snowflake server appears in your Connections and its tools become available to your crews.
</Step>
</Steps>
<Tip>
With OAuth, each user authenticates individually and queries run with their Snowflake `DEFAULT_ROLE`. Make sure connecting users have a default role and warehouse set (`ALTER USER <username> SET DEFAULT_ROLE = '<role>' DEFAULT_WAREHOUSE = '<warehouse>'`) so Cortex Analyst and SQL tools have compute to run on.
</Tip>
## Using Snowflake Tools in Your Crews
Once connected, the tools your MCP server exposes appear alongside built-in connections on the **Tools & Integrations** page. You can:
- **Assign tools to agents** in your crews just like any other CrewAI tool.
- **Manage visibility** to control which team members can use the connection.
- **Edit or remove** the connection at any time from the Connections list.
Your agents can now ask Cortex Analyst for metrics, run Cortex Search over your documents, and execute SQL — with results flowing back into their reasoning automatically.
<Warning>
Snowflake enforces governance on the MCP server: role-based access control determines which tools a user can discover and invoke, and limits apply to response size, tool count (max 50 per server), and recursion depth. If a tool call fails, confirm the connecting user's role has the required privileges on the MCP server and its underlying objects.
</Warning>
## Learn More
<CardGroup cols={2}>
<Card title="Snowflake-managed MCP Server" icon="snowflake" href="https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp">
Official Snowflake documentation for creating and governing the MCP server.
</Card>
<Card title="Custom MCP Servers in CrewAI" icon="plug" href="/en/enterprise/guides/custom-mcp-server">
Learn how CrewAI connects to any MCP server, the foundation the Snowflake integration builds on.
</Card>
</CardGroup>
<Card title="Need Help?" icon="headset" href="mailto:support@crewai.com">
Contact our support team for assistance with the Snowflake integration or troubleshooting.
</Card>

View File

@@ -161,6 +161,18 @@ crew = Crew(
)
```
<Note>
`agent.i18n` is maintained only for backward compatibility and is deprecated. For runtime prompt customization, pass `prompt_file` to `Crew`. For programmatic access to prompt slices, use the i18n utility directly:
</Note>
```python
from crewai.utilities.i18n import get_i18n
i18n = get_i18n("custom_prompts.json")
format_slice = i18n.slice("format")
tool_prompt = i18n.tools("ask_question")
```
#### Option 3: Disable System Prompts for o1 Models
```python
agent = Agent(
@@ -208,6 +220,8 @@ One straightforward approach is to create a JSON file for the prompts you want t
CrewAI then merges your customizations with the defaults, so you don't have to redefine every prompt. Here's how:
For code that needs to read prompt slices directly, use `crewai.utilities.i18n.get_i18n()` with the same prompt file instead of reading `agent.i18n`.
### Example: Basic Prompt Customization
Create a `custom_prompts.json` file with the prompts you want to modify. Ensure you list all top-level prompts it should contain, not just your changes:

View File

@@ -43,7 +43,7 @@ CrewAI is AI-native. This page brings together everything an AI coding agent nee
| Skill | When it runs |
|-------|--------------|
| `getting-started` | Scaffolding new projects, choosing between `LLM.call()` / `Agent` / `Crew` / `Flow`, wiring `crew.py` / `main.py` |
| `getting-started` | Scaffolding new projects, choosing between `LLM.call()` / `Agent` / `Crew` / `Flow`, wiring `crew.jsonc` / `main.py` |
| `design-agent` | Configuring agents — role, goal, backstory, tools, LLMs, memory, guardrails |
| `design-task` | Writing task descriptions, dependencies, structured output (`output_pydantic`, `output_json`), human review |
| `ask-docs` | Querying the live [CrewAI docs MCP server](https://docs.crewai.com/mcp) for up-to-date API details |
@@ -64,7 +64,7 @@ CrewAI is AI-native. This page brings together everything an AI coding agent nee
<Step title="Your agent gets instant CrewAI expertise">
The skill pack teaches your agent:
- **Flows** — stateful apps, steps, and crew kickoffs
- **Crews & Agents** — YAML-first patterns, roles, tasks, delegation
- **Crews & Agents** — JSON-first patterns (`crew.jsonc`, `agents/*.jsonc`), roles, tasks, delegation
- **Tools & Integrations** — search, APIs, MCP servers, and common CrewAI tools
- **Project layout** — CLI scaffolds and repo conventions
- **Up-to-date patterns** — tracks current CrewAI docs and best practices

View File

@@ -172,7 +172,7 @@ Flows are ideal when:
```python
# Example: Customer Support Flow with structured processing
from crewai.flow.flow import Flow, listen, router, start
from crewai.flow.flow import Flow, listen, or_, router, start
from pydantic import BaseModel
from typing import List, Dict
@@ -238,7 +238,7 @@ class CustomerSupportFlow(Flow[SupportTicketState]):
# Additional category handlers...
@listen("billing", "account_access", "technical_issue", "feature_request", "other")
@listen(or_("billing", "account_access", "technical_issue", "feature_request", "other"))
def resolve_ticket(self, resolution_info):
# Final resolution step
self.state.resolution = f"Issue resolved: {resolution_info}"

View File

@@ -1,396 +1,162 @@
---
title: Build Your First Crew
description: Step-by-step tutorial to create a collaborative AI team that works together to solve complex problems.
description: Step-by-step tutorial to create a collaborative AI team with JSON-first crew configuration.
icon: users-gear
mode: "wide"
---
## Unleashing the Power of Collaborative AI
## Build a Research Crew
Imagine having a team of specialized AI agents working together seamlessly to solve complex problems, each contributing their unique skills to achieve a common goal. This is the power of CrewAI - a framework that enables you to create collaborative AI systems that can accomplish tasks far beyond what a single AI could achieve alone.
In this guide, we'll walk through creating a research crew that will help us research and analyze a topic, then create a comprehensive report. This practical example demonstrates how AI agents can collaborate to accomplish complex tasks, but it's just the beginning of what's possible with CrewAI.
### What You'll Build and Learn
By the end of this guide, you'll have:
1. **Created a specialized AI research team** with distinct roles and responsibilities
2. **Orchestrated collaboration** between multiple AI agents
3. **Automated a complex workflow** that involves gathering information, analysis, and report generation
4. **Built foundational skills** that you can apply to more ambitious projects
While we're building a simple research crew in this guide, the same patterns and techniques can be applied to create much more sophisticated teams for tasks like:
- Multi-stage content creation with specialized writers, editors, and fact-checkers
- Complex customer service systems with tiered support agents
- Autonomous business analysts that gather data, create visualizations, and generate insights
- Product development teams that ideate, design, and plan implementation
Let's get started building your first crew!
In this guide, you will create a two-agent research crew that gathers information about a topic and writes a markdown report. New crew projects are JSON-first: agents are defined in `agents/*.jsonc`, tasks and crew settings are defined in `crew.jsonc`, and `crewai run` loads the JSON definition directly.
### Prerequisites
Before starting, make sure you have:
1. Installed CrewAI following the [installation guide](/en/installation)
2. Set up your LLM API key in your environment, following the [LLM setup
guide](/en/concepts/llms#setting-up-your-llm)
3. Basic understanding of Python
2. Set up your LLM API key following the [LLM setup guide](/en/concepts/llms#setting-up-your-llm)
3. A [Serper.dev](https://serper.dev/) API key if you want the researcher to use web search
## Step 1: Create a New CrewAI Project
First, let's create a new CrewAI project using the CLI. This command will set up a complete project structure with all the necessary files, allowing you to focus on defining your agents and their tasks rather than setting up boilerplate code.
## Step 1: Create a New Crew
```bash
crewai create crew research_crew
cd research_crew
```
This will generate a project with the basic structure needed for your crew. The CLI automatically creates:
The CLI creates a JSON-first project:
- A project directory with the necessary files
- Configuration files for agents and tasks
- A basic crew implementation
- A main script to run the crew
<Frame caption="CrewAI Framework Overview">
<img src="/images/crews.png" alt="CrewAI Framework Overview" />
</Frame>
## Step 2: Explore the Project Structure
Let's take a moment to understand the project structure created by the CLI. CrewAI follows best practices for Python projects, making it easy to maintain and extend your code as your crews become more complex.
```
```text
research_crew/
├── .gitignore
├── .env
├── agents/
│ └── researcher.jsonc
├── crew.jsonc
├── knowledge/
├── pyproject.toml
├── README.md
├── .env
└── src/
└── research_crew/
├── __init__.py
├── main.py
├── crew.py
├── tools/
│ ├── custom_tool.py
│ └── __init__.py
└── config/
├── agents.yaml
└── tasks.yaml
├── skills/
└── tools/
```
This structure follows best practices for Python projects and makes it easy to organize your code. The separation of configuration files (in YAML) from implementation code (in Python) makes it easy to modify your crew's behavior without changing the underlying code.
<Tip>
Need the older `crew.py`, `config/agents.yaml`, and `config/tasks.yaml` layout? Create it with `crewai create crew research_crew --classic`.
</Tip>
## Step 3: Configure Your Agents
## Step 2: Define Your Agents
Now comes the fun part - defining your AI agents! In CrewAI, agents are specialized entities with specific roles, goals, and backstories that shape their behavior. Think of them as characters in a play, each with their own personality and purpose.
Replace the generated `agents/researcher.jsonc` file and add `agents/analyst.jsonc`. The file names are the names you reference from `crew.jsonc`.
For our research crew, we'll create two agents:
1. A **researcher** who excels at finding and organizing information
2. An **analyst** who can interpret research findings and create insightful reports
Let's modify the `agents.yaml` file to define these specialized agents. Be sure
to set `llm` to the provider you are using.
```yaml
# src/research_crew/config/agents.yaml
researcher:
role: >
Senior Research Specialist for {topic}
goal: >
Find comprehensive and accurate information about {topic}
with a focus on recent developments and key insights
backstory: >
You are an experienced research specialist with a talent for
finding relevant information from various sources. You excel at
organizing information in a clear and structured manner, making
complex topics accessible to others.
llm: provider/model-id # e.g. openai/gpt-4o, google/gemini-2.0-flash, anthropic/claude...
analyst:
role: >
Data Analyst and Report Writer for {topic}
goal: >
Analyze research findings and create a comprehensive, well-structured
report that presents insights in a clear and engaging way
backstory: >
You are a skilled analyst with a background in data interpretation
and technical writing. You have a talent for identifying patterns
and extracting meaningful insights from research data, then
communicating those insights effectively through well-crafted reports.
llm: provider/model-id # e.g. openai/gpt-4o, google/gemini-2.0-flash, anthropic/claude...
```jsonc agents/researcher.jsonc
{
"role": "Senior Research Specialist for {topic}",
"goal": "Find comprehensive and accurate information about {topic}, with a focus on recent developments and key insights.",
"backstory": "You are an experienced research specialist who organizes complex information into clear, useful notes.",
// Replace with your model, for example "openai/gpt-4o".
"llm": "provider/model-id",
"tools": ["SerperDevTool"],
"settings": {
"verbose": true,
"allow_delegation": false
}
}
```
Notice how each agent has a distinct role, goal, and backstory. These elements aren't just descriptive - they actively shape how the agent approaches its tasks. By crafting these carefully, you can create agents with specialized skills and perspectives that complement each other.
## Step 4: Define Your Tasks
With our agents defined, we now need to give them specific tasks to perform. Tasks in CrewAI represent the concrete work that agents will perform, with detailed instructions and expected outputs.
For our research crew, we'll define two main tasks:
1. A **research task** for gathering comprehensive information
2. An **analysis task** for creating an insightful report
Let's modify the `tasks.yaml` file:
```yaml
# src/research_crew/config/tasks.yaml
research_task:
description: >
Conduct thorough research on {topic}. Focus on:
1. Key concepts and definitions
2. Historical development and recent trends
3. Major challenges and opportunities
4. Notable applications or case studies
5. Future outlook and potential developments
Make sure to organize your findings in a structured format with clear sections.
expected_output: >
A comprehensive research document with well-organized sections covering
all the requested aspects of {topic}. Include specific facts, figures,
and examples where relevant.
agent: researcher
analysis_task:
description: >
Analyze the research findings and create a comprehensive report on {topic}.
Your report should:
1. Begin with an executive summary
2. Include all key information from the research
3. Provide insightful analysis of trends and patterns
4. Offer recommendations or future considerations
5. Be formatted in a professional, easy-to-read style with clear headings
expected_output: >
A polished, professional report on {topic} that presents the research
findings with added analysis and insights. The report should be well-structured
with an executive summary, main sections, and conclusion.
agent: analyst
context:
- research_task
output_file: output/report.md
```jsonc agents/analyst.jsonc
{
"role": "Report Analyst for {topic}",
"goal": "Turn research findings into a clear, well-structured report.",
"backstory": "You are a careful analyst with strong technical writing skills and a talent for extracting useful insights.",
// Replace with your model, for example "openai/gpt-4o".
"llm": "provider/model-id",
"settings": {
"verbose": true,
"allow_delegation": false
}
}
```
Note the `context` field in the analysis task - this is a powerful feature that allows the analyst to access the output of the research task. This creates a workflow where information flows naturally between agents, just as it would in a human team.
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`.
## Step 5: Configure Your Crew
## Step 3: Define Tasks and Crew Settings
Now it's time to bring everything together by configuring our crew. The crew is the container that orchestrates how agents work together to complete tasks.
Replace `crew.jsonc` with:
Let's modify the `crew.py` file:
```python
# src/research_crew/crew.py
from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task
from crewai_tools import SerperDevTool
from crewai.agents.agent_builder.base_agent import BaseAgent
from typing import List
@CrewBase
class ResearchCrew():
"""Research crew for comprehensive topic analysis and reporting"""
agents: List[BaseAgent]
tasks: List[Task]
@agent
def researcher(self) -> Agent:
return Agent(
config=self.agents_config['researcher'], # type: ignore[index]
verbose=True,
tools=[SerperDevTool()]
)
@agent
def analyst(self) -> Agent:
return Agent(
config=self.agents_config['analyst'], # type: ignore[index]
verbose=True
)
@task
def research_task(self) -> Task:
return Task(
config=self.tasks_config['research_task'] # type: ignore[index]
)
@task
def analysis_task(self) -> Task:
return Task(
config=self.tasks_config['analysis_task'], # type: ignore[index]
output_file='output/report.md'
)
@crew
def crew(self) -> Crew:
"""Creates the research crew"""
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True,
)
```
In this code, we're:
1. Creating the researcher agent and equipping it with the SerperDevTool to search the web
2. Creating the analyst agent
3. Setting up the research and analysis tasks
4. Configuring the crew to run tasks sequentially (the analyst will wait for the researcher to finish)
This is where the magic happens - with just a few lines of code, we've defined a collaborative AI system where specialized agents work together in a coordinated process.
## Step 6: Set Up Your Main Script
Now, let's set up the main script that will run our crew. This is where we provide the specific topic we want our crew to research.
```python
#!/usr/bin/env python
# src/research_crew/main.py
import os
from research_crew.crew import ResearchCrew
# Create output directory if it doesn't exist
os.makedirs('output', exist_ok=True)
def run():
"""
Run the research crew.
"""
inputs = {
'topic': 'Artificial Intelligence in Healthcare'
```jsonc crew.jsonc
{
"name": "Research Crew",
"agents": ["researcher", "analyst"],
"tasks": [
{
"name": "research_task",
"description": "Conduct thorough research on {topic}. Focus on key concepts, recent developments, major challenges, notable applications, and future outlook.",
"expected_output": "A comprehensive research document with organized sections, specific facts, and useful examples about {topic}.",
"agent": "researcher"
},
{
"name": "analysis_task",
"description": "Analyze the research findings and create a polished report on {topic}. Include an executive summary, key insights, trend analysis, and recommendations.",
"expected_output": "A professional markdown report with clear headings, a concise summary, main findings, and recommendations.",
"agent": "analyst",
"context": ["research_task"],
"output_file": "output/report.md",
"markdown": true
}
# Create and run the crew
result = ResearchCrew().crew().kickoff(inputs=inputs)
# Print the result
print("\n\n=== FINAL REPORT ===\n\n")
print(result.raw)
print("\n\nReport has been saved to output/report.md")
if __name__ == "__main__":
run()
],
"process": "sequential",
"verbose": true,
"memory": true,
"inputs": {
"topic": "Artificial Intelligence in Healthcare"
}
}
```
This script prepares the environment, specifies our research topic, and kicks off the crew's work. The power of CrewAI is evident in how simple this code is - all the complexity of managing multiple AI agents is handled by the framework.
`context` points to prior task names, so the analyst receives the research task output. The `inputs` object provides default values for `{topic}`. If you remove a default, `crewai run` prompts for it.
## Step 7: Set Up Your Environment Variables
## Step 4: Set Environment Variables
Create a `.env` file in your project root with your API keys:
Open `.env` and add the keys your model and tools need:
```sh
SERPER_API_KEY=your_serper_api_key
# Add your provider's API key here too.
# Add your model provider API key here too.
```
See the [LLM Setup guide](/en/concepts/llms#setting-up-your-llm) for details on configuring your provider of choice. You can get a Serper API key from [Serper.dev](https://serper.dev/).
See the [LLM setup guide](/en/concepts/llms#setting-up-your-llm) for provider-specific keys.
## Step 8: Install Dependencies
Install the required dependencies using the CrewAI CLI:
## Step 5: Install and Run
```bash
crewai install
```
This command will:
1. Read the dependencies from your project configuration
2. Create a virtual environment if needed
3. Install all required packages
## Step 9: Run Your Crew
Now for the exciting moment - it's time to run your crew and see AI collaboration in action!
```bash
crewai run
```
When you run this command, you'll see your crew spring to life. The researcher will gather information about the specified topic, and the analyst will then create a comprehensive report based on that research. You'll see the agents' thought processes, actions, and outputs in real-time as they work together to complete their tasks.
`crewai run` detects `crew.jsonc`, loads the agents from `agents/`, prompts for missing placeholders, and runs the crew. When the run finishes, open `output/report.md`.
## Step 10: Review the Output
## How It Works
Once the crew completes its work, you'll find the final report in the `output/report.md` file. The report will include:
1. `crew.jsonc` defines the crew, task order, process, memory, and runtime inputs.
2. `agents/researcher.jsonc` and `agents/analyst.jsonc` define the agents.
3. The researcher runs first.
4. The analyst runs second with `context: ["research_task"]`.
5. The final task writes `output/report.md`.
1. An executive summary
2. Detailed information about the topic
3. Analysis and insights
4. Recommendations or future considerations
## Extending Your Crew
Take a moment to appreciate what you've accomplished - you've created a system where multiple AI agents collaborated on a complex task, each contributing their specialized skills to produce a result that's greater than what any single agent could achieve alone.
You can add:
## Exploring Other CLI Commands
- More agents by creating new `agents/<name>.jsonc` files and listing them in `crew.jsonc`
- More tasks by appending objects to the `tasks` array
- Built-in tools by adding tool class names such as `"FileReadTool"` or `"SerperDevTool"`
- Custom tools with `"custom:<name>"`, which loads `tools/<name>.py`
- Hierarchical execution with `"process": "hierarchical"` and a `manager_llm` or `manager_agent`
CrewAI offers several other useful CLI commands for working with crews:
```bash
# View all available commands
crewai --help
# Run the crew
crewai run
# Test the crew
crewai test
# Reset crew memories
crewai reset-memories
# Replay from a specific task
crewai replay -t <task_id>
```
## The Art of the Possible: Beyond Your First Crew
What you've built in this guide is just the beginning. The skills and patterns you've learned can be applied to create increasingly sophisticated AI systems. Here are some ways you could extend this basic research crew:
### Expanding Your Crew
You could add more specialized agents to your crew:
- A **fact-checker** to verify research findings
- A **data visualizer** to create charts and graphs
- A **domain expert** with specialized knowledge in a particular area
- A **critic** to identify weaknesses in the analysis
### Adding Tools and Capabilities
You could enhance your agents with additional tools:
- Web browsing tools for real-time research
- CSV/database tools for data analysis
- Code execution tools for data processing
- API connections to external services
### Creating More Complex Workflows
You could implement more sophisticated processes:
- Hierarchical processes where manager agents delegate to worker agents
- Iterative processes with feedback loops for refinement
- Parallel processes where multiple agents work simultaneously
- Dynamic processes that adapt based on intermediate results
### Applying to Different Domains
The same patterns can be applied to create crews for:
- **Content creation**: Writers, editors, fact-checkers, and designers working together
- **Customer service**: Triage agents, specialists, and quality control working together
- **Product development**: Researchers, designers, and planners collaborating
- **Data analysis**: Data collectors, analysts, and visualization specialists
## Next Steps
Now that you've built your first crew, you can:
1. Experiment with different agent configurations and personalities
2. Try more complex task structures and workflows
3. Implement custom tools to give your agents new capabilities
4. Apply your crew to different topics or problem domains
5. Explore [CrewAI Flows](/en/guides/flows/first-flow) for more advanced workflows with procedural programming
<Warning>
Only run JSON crew projects from sources you trust. `custom:<name>` tools and `{"python": "module.attribute"}` references execute local Python code when the crew loads.
</Warning>
<Check>
Congratulations! You've successfully built your first CrewAI crew that can research and analyze any topic you provide. This foundational experience has equipped you with the skills to create increasingly sophisticated AI systems that can tackle complex, multi-stage problems through collaborative intelligence.
You now have a working JSON-first crew that researches a topic and writes a report.
</Check>

View File

@@ -0,0 +1,501 @@
---
title: Conversational Flows
description: Build multi-turn chat apps with handle_turn per turn, message history, intent routing, tracing, and WebSocket bridges.
icon: comments
mode: "wide"
---
## Overview
Conversational apps treat each user line as a **new flow run** with the **same session id**. CrewAI adds helpers for message history, optional intent routing, deferred tracing, UI bridges, and a local `flow.chat()` REPL for conversational flows.
| Concept | Implementation |
|---------|----------------|
| Session id | `handle_turn(..., session_id=...)` → `kickoff(inputs={"id": ...})` → `state.id` |
| User line | `handle_turn(message)` appends to `state.messages` before the graph runs |
| Turn complete | `FlowFinished` for **this run** only; chat continues on the next `handle_turn` |
| Full-session trace | `ConversationConfig(defer_trace_finalization=True)` + `finalize_session_traces()` |
## Turn APIs
Use **`flow.handle_turn(message, session_id=...)`** for every user message from REST, WebSocket, tests, and custom UIs. Use **`flow.chat()`** when you want a local terminal chat loop for a conversational `Flow`.
`Flow.kickoff()` does **not** accept `user_message=` or `session_id=` keyword arguments. For conversational flows, `handle_turn()` stores the pending message and calls `kickoff(inputs={"id": session_id})` internally after resetting per-turn execution state.
| API | Use for |
|-----|---------|
| `handle_turn(message, session_id=...)` | Ergonomic one-turn wrapper for conversational `Flow` |
| `chat()` | Local terminal REPL for conversational `Flow` |
| `kickoff(inputs={...})` | Advanced flow execution without conversational turn handling |
| `ask()` | Blocking prompt **inside** one step (wizard, clarification) |
| `@human_feedback` | Approve/reject **a step output** — not the next chat line |
| `ChatSession.handle_turn(...)` | Transport layer over `handle_turn` (SSE / WebSocket) |
## Quick start
```python
from uuid import uuid4
from crewai import Flow
from crewai.flow import listen
from crewai.experimental.conversational import (
ConversationConfig,
ConversationState,
)
@ConversationConfig(defer_trace_finalization=True)
class SupportFlow(Flow[ConversationState]):
conversational = True
def route_turn(self, context):
message = (self.state.current_user_message or "").lower()
if "order" in message:
return "order"
if "bye" in message or "goodbye" in message:
return "goodbye"
return "help"
@listen("order")
def handle_order(self):
reply = "Your order is on the way."
self.append_assistant_message(reply)
return reply
@listen("help")
def handle_help(self):
reply = "How can I help?"
self.append_assistant_message(reply)
return reply
@listen("goodbye")
def handle_goodbye(self):
reply = "Goodbye!"
self.append_assistant_message(reply)
return reply
session_id = str(uuid4())
flow = SupportFlow()
try:
flow.handle_turn("Where is my order?", session_id=session_id)
flow.handle_turn("What about returns?", session_id=session_id)
finally:
flow.finalize_session_traces() # one trace link for the whole chat
```
## Turn lifecycle
Each `handle_turn` runs this pipeline:
1. **Turn setup** — stores the pending user message, resolves the session id, resets per-turn execution tracking, and calls `kickoff(inputs={"id": session_id})`.
2. **State restore** — if `inputs["id"]` exists and `@persist` is configured, loads the latest snapshot.
3. **`FlowStarted`** — emitted on the first deferred session turn only.
4. **Pending turn hydration** — appends the user message to `state.messages`, sets `current_user_message` / `last_user_message`, and optionally classifies when `intents` / `default_intents` + `intent_llm` are set.
5. **Graph execution** — `conversation_start` → `route_conversation` → the selected `@listen` handler.
6. **End of run** — per-turn `flow_finished` and trace finalization are **skipped** when deferral is enabled; nested `Agent.kickoff()` / crews do not close the parent batch either.
Handlers should call **`append_assistant_message(reply)`** so the next turns `conversation_messages` includes assistant text. The user line is already stored by `handle_turn` — do not append it again in handlers.
## `ConversationConfig` (class-level defaults)
Decorate your conversational `Flow` subclass with `ConversationConfig`.
| Field | Default | Purpose |
|-------|---------|---------|
| `system_prompt` | Framework default | System message used by the built-in `converse_turn`. |
| `llm` | `None` | Conversation LLM used by `converse_turn` and as router fallback. |
| `router` | `None` | `RouterConfig` for LLM-driven routing. |
| `intent_llm` | `None` | LLM for `intents=` / `default_intents` pre-classification. |
| `default_intents` | `None` | Outcome labels for pre-classification. |
| `defer_trace_finalization` | `True` | Keep one trace batch open across `handle_turn()` calls. |
Override pre-classification per turn with `handle_turn(..., intents=..., intent_llm=...)`.
## Lower-level `ChatState` helpers
`ChatState`, `ConversationalConfig`, and `crewai.flow.conversation` helpers are still importable for advanced orchestration, tests, or custom wrappers. They do not add `user_message=` or `session_id=` keyword arguments to `Flow.kickoff()`.
```python
from crewai.flow import ChatState
class MyChatState(ChatState):
# Inherited: id, messages, last_user_message, last_intent, session_ready
research_turn_count: int = 0
custom_flag: bool = False
```
| Field | Role |
|-------|------|
| `id` | Session UUID (same as `inputs["id"]`) |
| `messages` | `list` of `{role, content}` for LLM history |
| `last_user_message` | Latest user line for this turn |
| `last_intent` | Route label after classification (if used) |
| `session_ready` | One-time bootstrap flag (permissions, caches, etc.) |
`ConversationalInputs` is a `TypedDict` for conventional `kickoff(inputs={...})` keys: `id`, `user_message`, `last_intent`.
## `Flow` conversational API
### `handle_turn` parameters
| Parameter | Purpose |
|-----------|---------|
| `message` | This turns text |
| `session_id` | Conversation UUID → `inputs["id"]` / `state.id` |
| `intents` | Outcome labels for pre-kickoff `classify_intent` |
| `intent_llm` | LLM for classification (required with `intents`) |
| `**kickoff_kwargs` | Forwarded to `kickoff()` for options like `input_files`, `from_checkpoint`, and `restore_from_state_id` |
### `kickoff` parameters
`Flow.kickoff()` accepts `inputs`, `input_files`, `from_checkpoint`, and `restore_from_state_id`. Pass `inputs={"id": session_id}` when you need raw flow execution, but use `handle_turn()` when the call represents a chat message.
### Instance attributes
| Attribute | Purpose |
|-----------|---------|
| `conversational` | Set to `True` to enable the conversational graph and `handle_turn()` |
| `defer_trace_finalization` | Instance flag; set automatically from config on `handle_turn()` |
| `suppress_flow_events` | Hides console flow panels; **tracing still records** method/flow events |
| `stream` | Enable streaming; use with `ChatSession.handle_turn(..., stream=True)` |
### Methods and properties
| Name | Description |
|------|-------------|
| `append_assistant_message(content)` | Append a user-visible assistant reply to `state.messages` |
| `append_message(role, content, **extra)` | Lower-level append to `state.messages` |
| `conversation_messages` | Read-only history for LLM calls |
| `classify_intent(text, outcomes, *, llm, context=None)` | Map text to one outcome (same collapse logic as `@human_feedback`) |
| `receive_user_message(text, *, outcomes=None, llm=None)` | Append user message; optionally set `last_intent` |
| `finalize_session_traces()` | Emit deferred `flow_finished` and finalize the session trace batch |
| `_should_defer_trace_finalization()` | Whether this flow defers per-turn trace finalization |
| `input_history` | Audit trail of `ask()` prompts and responses |
### Module helpers (`crewai.flow.conversation`)
Importable for tests or custom orchestration:
| Function | Description |
|----------|-------------|
| `normalize_kickoff_inputs(inputs, user_message=..., session_id=...)` | Merge conversational kwargs into `inputs` |
| `get_conversation_messages(flow)` | Read messages from state or internal buffer |
| `append_message(flow, role, content, **extra)` | Same as instance method |
| `prepare_conversational_turn(flow, user_message=..., intents=..., intent_llm=..., config=...)` | Lower-level turn hydration for custom wrappers |
| `receive_user_message(flow, text, ...)` | Same as instance method |
| `set_state_field(flow, name, value)` | Set a field on dict or Pydantic state |
| `get_conversational_config(flow)` | Read class `conversational_config` |
| `input_history_to_messages(entries)` | Convert `input_history` to LLM message format |
## Intent routing patterns
### A. Pre-classify via `ConversationConfig` (simplest)
Set `default_intents` and `intent_llm`. Each `handle_turn()` runs classification before routing; read `self.state.last_intent` in `route_turn()`.
### B. Classify inside `route_turn` (richer prompts)
Set `default_intents=None` so `handle_turn()` only appends the user message. In `route_turn()`, call `classify_intent` with a custom prompt or descriptions:
```python
def route_turn(self, context):
intent = self.classify_intent(
self._routing_prompt(self.state.current_user_message),
("GREETING", "ORDER", "RESEARCH", "GOODBYE"),
llm="gpt-4o-mini",
)
self.state.last_intent = intent
return intent
```
Use **`@listen("RESEARCH")`** (or similar) for steps that run `Agent.kickoff()` with tools — not bare `LLM.call()` — when you need web research or multi-step tool use.
## When the flow finishes but the user keeps chatting
`FlowFinished` means **this graph run** completed. The conversation continues with another `handle_turn()` and the same `session_id`. `@persist` restores `messages`, flags, and context.
**Persist pattern:** prefer `@persist` on a **single terminal step** (for example `finalize`) rather than on the whole `Flow` class. Class-level persist saves after every method; `load_state` uses the latest row, which may be a mid-run snapshot (for example right after `bootstrap`) and miss handler updates from the same turn.
Do **not** use `@human_feedback` for follow-up chat lines unless a human must approve a specific step output before it is shown.
## Conversational `Flow` (experimental)
<Warning>
**This is an experimental feature.** The conversational `Flow` surface
(`conversational = True`, `handle_turn`, `ConversationConfig`,
`RouterConfig`, `ConversationState`, the built-in graph + helpers) lives
under `crewai.experimental` and may change shape before it graduates.
Pin your CrewAI version if you depend on specific behavior, and watch the
changelog for breaking updates. Open issues / feedback welcome.
</Warning>
Opt into the conversational chat graph by setting `conversational = True` on a `Flow` subclass. The base `Flow` then ships a built-in `@start` / `@router` / `converse_turn` / `end_conversation` graph, manages `state.messages`, can drive a router LLM, and keeps the trace batch open across turns. You write the **custom routes**; the framework owns the rest.
Use this when you want a multi-turn chat with a router and per-route handlers without wiring the lifecycle yourself. Use `Flow[ChatState]` (the lower-level pattern above) when you need full control.
### Quick example
```python
from crewai import Flow
from crewai.flow import listen
from crewai.experimental.conversational import (
ConversationConfig,
ConversationState,
)
@ConversationConfig(defer_trace_finalization=True)
class SupportFlow(Flow[ConversationState]):
conversational = True
def route_turn(self, context: dict) -> str | None:
message = (self.state.current_user_message or "").lower()
if "search" in message or "news" in message:
return "INTERNET_SEARCH"
if "docs" in message or "crewai" in message:
return "CREWAI_DOCS"
return "converse"
@listen("INTERNET_SEARCH")
def handle_internet_search(self) -> str:
"""Fresh web research, current news, real-time lookups."""
reply = "I would run the web research route here."
self.append_assistant_message(reply)
return reply
@listen("CREWAI_DOCS")
def handle_crewai_docs(self) -> str:
"""Look up the CrewAI documentation for framework/API questions."""
reply = "I would look up the CrewAI docs here."
self.append_assistant_message(reply)
return reply
flow = SupportFlow()
try:
flow.handle_turn("What can you do?") # routes to converse
flow.handle_turn("Search the web for AI news.") # routes to INTERNET_SEARCH
flow.handle_turn("Check the CrewAI docs.") # routes to CREWAI_DOCS
finally:
flow.finalize_session_traces()
```
For a local terminal chat, use `chat()`:
```python
def kickoff() -> None:
SupportFlow().chat()
```
`chat()` wraps `handle_turn()` in a REPL, exits on `exit` / `quit`, skips blank lines by default, and calls `finalize_session_traces()` when the session ends.
### `ConversationConfig`
Class decorator that attaches per-class chat defaults.
| Field | Default | Purpose |
|-------|---------|---------|
| `system_prompt` | `slices.conversational_system_prompt` from i18n | System message used by the built-in `converse_turn`. Pass `""` to opt out entirely. |
| `llm` | `None` | Conversation LLM (used by `converse_turn` and as router fallback). |
| `router` | `None` | `RouterConfig` for LLM-driven routing. Without it, the flow always falls through to `converse`. |
| `answer_from_history_prompt` | Framework default | System message for the optional `answer_from_history` route. |
| `answer_from_history_llm` | `None` | Enables the `answer_from_history` short-circuit when set. |
| `intent_llm` | `None` | LLM for legacy `intents=`/`default_intents` pre-classification. |
| `default_intents` | `None` | Outcome labels for legacy pre-classification. |
| `visible_agent_outputs` | `None` | `"all"`, or a list of agent names whose `append_agent_result()` calls should be promoted to public assistant messages. |
| `defer_trace_finalization` | `True` | Keep one trace batch open across `handle_turn()` calls. |
### `RouterConfig` and the auto-built route catalog
```python
from typing import Literal
from pydantic import BaseModel
from crewai import LLM
from crewai.experimental.conversational import RouterConfig
class MyRoute(BaseModel):
intent: Literal["INTERNET_SEARCH", "CREWAI_DOCS", "converse"]
ROUTER_LLM = LLM(model="gpt-4o-mini")
router_config = RouterConfig(
prompt="Optional domain framing (policy, voice, persona).",
response_format=MyRoute, # optional; auto-generated otherwise
llm=ROUTER_LLM, # falls back to ConversationConfig.llm
routes=["INTERNET_SEARCH", "CREWAI_DOCS"], # optional; inferred from listeners
route_descriptions={
"INTERNET_SEARCH": "Override the docstring for this one route.",
},
default_intent="converse", # used when LLM call fails or no LLM available
fallback_intent="converse", # used when LLM returns an invalid route
intent_field="intent",
)
```
The router prompt that gets sent to the LLM is built automatically. For each route the framework picks a description with this precedence:
1. `RouterConfig.route_descriptions[label]` — explicit override.
2. `Flow.builtin_route_descriptions[label]` — framework-canned text for `converse`, `end`, `answer_from_history` (phrased for the router LLM).
3. First non-empty line of the `@listen(label)` handler's docstring.
4. Empty (the route is listed without a description).
So in practice, **adding a new route is `@listen("X")` + a one-line docstring**:
```python
from crewai.flow import listen
@listen("INTERNET_SEARCH")
def handle_internet_search(self) -> str:
"""Fresh web research, current news, real-time lookups."""
...
```
…and the router LLM sees:
```
Routes:
- CREWAI_DOCS: Look up the CrewAI documentation for framework/API questions.
- INTERNET_SEARCH: Fresh web research, current news, real-time lookups.
- converse: Ordinary chat, follow-ups, summaries, clarifications…
- end: User signals the conversation is finished (goodbye, exit, done).
```
`RouterConfig.prompt` is for **domain framing** (assistant persona, business rules, voice). The route catalog is auto-built — don't list routes in `prompt`; they'll drift the moment you add a handler.
### Built-in routes
| Route | Handler | Purpose |
|-------|---------|---------|
| `converse` | `converse_turn` | Default chat handler. Calls `ConversationConfig.llm` with the system prompt + canonical message history. |
| `end` | `end_conversation` | Sets `state.ended = True` and emits a terminator reply. |
| `answer_from_history` | `answer_from_history_turn` | Optional. Routes here when `ConversationConfig.answer_from_history_llm` is set and the message can be answered from existing history. |
You can override any of these by defining a same-named handler in your subclass.
### `handle_turn()` semantics
`flow.handle_turn(message)` runs one turn:
1. Resets per-execution tracking (`_completed_methods`, `_method_outputs`) so the graph re-runs — without this, repeated `kickoff` calls on the same flow instance would short-circuit on turn 2+ because `Flow.kickoff_async` treats `inputs={"id": ...}` as a checkpoint restore.
2. Appends the user message to `state.messages`, sets `current_user_message` / `last_user_message`. `last_intent` is **preserved from the prior turn** so the router LLM can use it as a signal.
3. Runs `conversation_start` → `route_conversation` → the chosen `@listen` handler.
4. The router stores its decision in `state.last_intent` (visible to the next turn's router context).
5. If your handler returned a string and didn't already call `append_assistant_message`, `handle_turn` appends it for you.
Call `handle_turn()` for chat messages. Calling `kickoff(inputs={"id": ...})` directly runs the flow graph without applying the conversational turn wrapper.
### `chat()` for local REPLs
`flow.chat()` is the batteries-included terminal wrapper around `handle_turn()`:
```python
flow = SupportFlow()
flow.chat()
```
It handles the common local loop:
1. Prompts for a user message.
2. Stops on `exit` / `quit`, `EOFError`, or `KeyboardInterrupt`.
3. Calls `handle_turn(message, session_id=...)`.
4. Prints the assistant result.
5. Finalizes deferred session traces in a `finally` block.
Customize the terminal behavior with injectable I/O:
```python
flow.chat(
session_id="demo-session",
prompt="You: ",
assistant_prefix="Assistant: ",
exit_commands=("exit", "quit", "bye"),
)
```
For web apps, background workers, tests, and custom transports, keep using `handle_turn()` directly.
### Custom router behavior
To run side effects (event bus setup, telemetry) on every routing decision, override `route_turn`:
```python
from typing import Any
from crewai import Flow
from crewai.experimental.conversational import ConversationState
class SupportFlow(Flow[ConversationState]):
conversational = True
def route_turn(self, context: dict[str, Any]) -> str | None:
self.event_bus = MyBus(self)
return super().route_turn(context)
```
To bypass the LLM router entirely and pick a route programmatically, return a string from `route_turn`; returning `None` falls back to `_route_with_config(...)`.
### `append_assistant_message` and `append_agent_result`
Inside a `@listen(label)` handler, choose:
- `self.append_assistant_message(text)` — adds a user-visible assistant turn to `state.messages`. The next turn's `converse_turn` sees it.
- `self.append_agent_result(agent_name, result, visibility="private")` — records a structured event in `state.events` and a thread in `state.agent_threads[agent_name]`. Public visibility also calls `append_assistant_message` for you. Use private results for scratch work that shouldn't pollute the canonical history.
`ConversationConfig.visible_agent_outputs` can promote specific agents' private results to public globally (`"all"`, or a list of agent names).
## Tracing across turns
With `defer_trace_finalization=True` (default in `ConversationConfig`):
- **One trace batch** for the whole chat session.
- **`flow_started`** on the first turn only; **`flow_finished`** once in `finalize_session_traces()`.
- **Per-turn** `kickoff` does not print “Trace batch finalized”.
- **Nested work** (`Agent.kickoff()`, crews, Exa tools) appends to the **parent** batch; inner `AgentExecutor` flows do not close the session batch early.
```python
flow.chat(session_id=session_id)
```
`flow.chat()` calls `finalize_session_traces()` for you. When you own the loop
with `handle_turn()`, call `finalize_session_traces()` when
the session ends.
`suppress_flow_events=True` only hides Rich console panels; trace and method events still emit for observability.
### Conversational `Flow` trace lifecycle
The experimental [conversational `Flow`](#conversational-flow-experimental) uses the same tracing lifecycle: `defer_trace_finalization` defaults to `True`, so each `handle_turn()` keeps the session trace open. Always finalize at the end of the session — wrap your REPL/loop in `try/finally` and call `flow.finalize_session_traces()` on exit. Without it, the trace batch stays open and the final conversation may never export.
## Streaming
Set `stream = True` on the `Flow` class. `kickoff(...)` will then emit `assistant_delta` (and related) events through the standard event bus.
## Imports
```python
from crewai.flow import (
ChatState,
ConversationalConfig,
ConversationalInputs,
Flow,
listen,
persist,
router,
start,
)
```
## See also
- [Mastering Flow State Management](/en/guides/flows/mastering-flow-state) — persistence, Pydantic state, `@persist`
- [Build Your First Flow](/en/guides/flows/first-flow) — flow basics
- Demo: `lib/crewai/runner_conversational_flow_simple.py` — minimal REPL with `RESEARCH` + Exa agent

View File

@@ -65,7 +65,7 @@ This will generate a project with the basic structure needed for your flow.
## Step 2: Understanding the Project Structure
The generated project has the following structure. Take a moment to familiarize yourself with it, as understanding this structure will help you create more complex flows in the future.
The generated project has the following structure. The starter embedded crew uses the classic Python/YAML layout, and in Step 4 we will replace the content crew with a JSONC crew.
```
guide_creator_flow/
@@ -73,21 +73,24 @@ guide_creator_flow/
├── pyproject.toml
├── README.md
├── .env
── main.py
├── crews/
── poem_crew/
├── config/
├── agents.yaml
│ └── tasks.yaml
── poem_crew.py
└── tools/
└── custom_tool.py
── src/
└── guide_creator_flow/
── __init__.py
├── main.py
├── crews/
│ └── poem_crew/
── config/
│ │ ├── agents.yaml
│ │ └── tasks.yaml
│ └── poem_crew.py
└── tools/
└── custom_tool.py
```
This structure provides a clear separation between different components of your flow:
- The main flow logic in the `main.py` file
- Specialized crews in the `crews` directory
- Custom tools in the `tools` directory
- The main flow logic in the `src/guide_creator_flow/main.py` file
- Specialized crews in the `src/guide_creator_flow/crews` directory
- Custom tools in the `src/guide_creator_flow/tools` directory
We'll modify this structure to create our guide creator flow, which will orchestrate the process of generating comprehensive learning guides.
@@ -103,157 +106,82 @@ This command automatically creates the necessary directories and template files
## Step 4: Configure the Content Writer Crew
Now, let's modify the generated files for the content writer crew. We'll set up two specialized agents - a writer and a reviewer - that will collaborate to create high-quality content for our guide.
Now, let's configure the content writer crew with JSONC. We'll set up two specialized agents - a writer and a reviewer - that collaborate to create high-quality content for our guide.
1. First, update the agents configuration file to define our content creation team:
1. Create `src/guide_creator_flow/crews/content_crew/agents/content_writer.jsonc`:
Remember to set `llm` to the provider you are using.
```yaml
# src/guide_creator_flow/crews/content_crew/config/agents.yaml
content_writer:
role: >
Educational Content Writer
goal: >
Create engaging, informative content that thoroughly explains the assigned topic
and provides valuable insights to the reader
backstory: >
You are a talented educational writer with expertise in creating clear, engaging
content. You have a gift for explaining complex concepts in accessible language
and organizing information in a way that helps readers build their understanding.
llm: provider/model-id # e.g. openai/gpt-4o, google/gemini-2.0-flash, anthropic/claude...
content_reviewer:
role: >
Educational Content Reviewer and Editor
goal: >
Ensure content is accurate, comprehensive, well-structured, and maintains
consistency with previously written sections
backstory: >
You are a meticulous editor with years of experience reviewing educational
content. You have an eye for detail, clarity, and coherence. You excel at
improving content while maintaining the original author's voice and ensuring
consistent quality across multiple sections.
llm: provider/model-id # e.g. openai/gpt-4o, google/gemini-2.0-flash, anthropic/claude...
```jsonc
{
"role": "Educational Content Writer",
"goal": "Create engaging, informative content that thoroughly explains the assigned topic and provides valuable insights to the reader.",
"backstory": "You are a talented educational writer who explains complex concepts in accessible language and organizes information clearly.",
"llm": "provider/model-id",
"settings": {
"verbose": true
}
}
```
These agent definitions establish the specialized roles and perspectives that will shape how our AI agents approach content creation. Notice how each agent has a distinct purpose and expertise.
2. Create `src/guide_creator_flow/crews/content_crew/agents/content_reviewer.jsonc`:
2. Next, update the tasks configuration file to define the specific writing and reviewing tasks:
```yaml
# src/guide_creator_flow/crews/content_crew/config/tasks.yaml
write_section_task:
description: >
Write a comprehensive section on the topic: "{section_title}"
Section description: {section_description}
Target audience: {audience_level} level learners
Your content should:
1. Begin with a brief introduction to the section topic
2. Explain all key concepts clearly with examples
3. Include practical applications or exercises where appropriate
4. End with a summary of key points
5. Be approximately 500-800 words in length
Format your content in Markdown with appropriate headings, lists, and emphasis.
Previously written sections:
{previous_sections}
Make sure your content maintains consistency with previously written sections
and builds upon concepts that have already been explained.
expected_output: >
A well-structured, comprehensive section in Markdown format that thoroughly
explains the topic and is appropriate for the target audience.
agent: content_writer
review_section_task:
description: >
Review and improve the following section on "{section_title}":
{draft_content}
Target audience: {audience_level} level learners
Previously written sections:
{previous_sections}
Your review should:
1. Fix any grammatical or spelling errors
2. Improve clarity and readability
3. Ensure content is comprehensive and accurate
4. Verify consistency with previously written sections
5. Enhance the structure and flow
6. Add any missing key information
Provide the improved version of the section in Markdown format.
expected_output: >
An improved, polished version of the section that maintains the original
structure but enhances clarity, accuracy, and consistency.
agent: content_reviewer
context:
- write_section_task
```jsonc
{
"role": "Educational Content Reviewer and Editor",
"goal": "Ensure content is accurate, comprehensive, well-structured, and consistent with previously written sections.",
"backstory": "You are a meticulous editor with an eye for detail, clarity, and coherence.",
"llm": "provider/model-id",
"settings": {
"verbose": true
}
}
```
These task definitions provide detailed instructions to our agents, ensuring they produce content that meets our quality standards. Note how the `context` parameter in the review task creates a workflow where the reviewer has access to the writer's output.
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`.
3. Now, update the crew implementation file to define how our agents and tasks work together:
3. Create `src/guide_creator_flow/crews/content_crew/crew.jsonc`:
```jsonc
{
"name": "Content Crew",
"agents": ["content_writer", "content_reviewer"],
"tasks": [
{
"name": "write_section_task",
"description": "Write a comprehensive section on the topic: \"{section_title}\".\n\nSection description: {section_description}\nTarget audience: {audience_level} level learners\n\nYour content should begin with a brief introduction, explain key concepts clearly with examples, include practical applications where appropriate, end with a summary, and be approximately 500-800 words.\n\nPreviously written sections:\n{previous_sections}",
"expected_output": "A well-structured, comprehensive section in Markdown format that thoroughly explains the topic and is appropriate for the target audience.",
"agent": "content_writer",
"markdown": true
},
{
"name": "review_section_task",
"description": "Review and improve this section on \"{section_title}\":\n\n{draft_content}\n\nTarget audience: {audience_level} level learners\nPreviously written sections:\n{previous_sections}\n\nFix errors, improve clarity, verify consistency, enhance structure, and add missing key information.",
"expected_output": "An improved, polished version of the section that maintains the original structure but enhances clarity, accuracy, and consistency.",
"agent": "content_reviewer",
"context": ["write_section_task"],
"markdown": true
}
],
"process": "sequential",
"verbose": true
}
```
The `context` field lets the reviewer use the writer's output.
4. Replace `src/guide_creator_flow/crews/content_crew/content_crew.py` with a small loader:
```python
# src/guide_creator_flow/crews/content_crew/content_crew.py
from crewai import Agent, Crew, Process, Task
from crewai.project import CrewBase, agent, crew, task
from crewai.agents.agent_builder.base_agent import BaseAgent
from typing import List
from pathlib import Path
@CrewBase
class ContentCrew():
"""Content writing crew"""
from crewai.project import load_crew
agents: List[BaseAgent]
tasks: List[Task]
@agent
def content_writer(self) -> Agent:
return Agent(
config=self.agents_config['content_writer'], # type: ignore[index]
verbose=True
)
@agent
def content_reviewer(self) -> Agent:
return Agent(
config=self.agents_config['content_reviewer'], # type: ignore[index]
verbose=True
)
@task
def write_section_task(self) -> Task:
return Task(
config=self.tasks_config['write_section_task'] # type: ignore[index]
)
@task
def review_section_task(self) -> Task:
return Task(
config=self.tasks_config['review_section_task'], # type: ignore[index]
context=[self.write_section_task()]
)
@crew
def crew(self) -> Crew:
"""Creates the content writing crew"""
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True,
)
def kickoff_content_crew(inputs: dict):
crew, default_inputs = load_crew(Path(__file__).with_name("crew.jsonc"))
return crew.kickoff(inputs={**default_inputs, **inputs})
```
This crew definition establishes the relationship between our agents and tasks, setting up a sequential process where the content writer creates a draft and then the reviewer improves it. While this crew can function independently, in our flow it will be orchestrated as part of a larger system.
This loader turns `crew.jsonc` into a `Crew` at runtime. While this crew can function independently, in our flow it will be orchestrated as part of a larger system.
## Step 5: Create the Flow
@@ -275,7 +203,7 @@ from typing import List, Dict
from pydantic import BaseModel, Field
from crewai import LLM
from crewai.flow.flow import Flow, listen, start
from guide_creator_flow.crews.content_crew.content_crew import ContentCrew
from guide_creator_flow.crews.content_crew.content_crew import kickoff_content_crew
# Define our models for structured data
class Section(BaseModel):
@@ -380,7 +308,7 @@ class GuideCreatorFlow(Flow[GuideCreatorState]):
previous_sections_text = "No previous sections written yet."
# Run the content crew for this section
result = ContentCrew().crew().kickoff(inputs={
result = kickoff_content_crew(inputs={
"section_title": section.title,
"section_description": section.description,
"audience_level": self.state.audience_level,
@@ -600,7 +528,7 @@ This provides a type-safe way to track and transform data throughout your flow.
Flows can seamlessly integrate with crews for complex collaborative tasks:
```python
result = ContentCrew().crew().kickoff(inputs={
result = kickoff_content_crew(inputs={
"section_title": section.title,
# ...
})
@@ -617,6 +545,7 @@ Now that you've built your first flow, you can:
3. Explore the `and_` and `or_` functions for more complex parallel execution
4. Connect your flow to external APIs, databases, or user interfaces
5. Combine multiple specialized crews in a single flow
6. Build multi-turn chat apps with [Conversational Flows](/en/guides/flows/conversational-flows) (`kickoff` per message, `ChatSession`, deferred tracing)
<Check>
Congratulations! You've successfully built your first CrewAI Flow that combines regular code, direct LLM calls, and crew-based processing to create a comprehensive guide. These foundational skills enable you to create increasingly sophisticated AI applications that can tackle complex, multi-stage problems through a combination of procedural control and collaborative intelligence.

View File

@@ -22,6 +22,8 @@ Effective state management enables you to:
5. **Scale your applications** - Support complex workflows with proper data organization
6. **Enable conversational applications** - Store and access conversation history for context-aware AI interactions
For multi-turn chat (`kickoff` per user line, `ChatState`, intent routing, deferred tracing, and `ChatSession`), see [Conversational Flows](/en/guides/flows/conversational-flows).
Let's explore how to leverage these capabilities effectively.
## State Management Fundamentals

View File

@@ -141,7 +141,7 @@ crew = Crew(
process=Process.sequential, # or Process.hierarchical
memory=True,
cache=True,
embedder={"provider": "openai", "config": {"model": "text-embedding-3-small"}},
embedder={"provider": "openai", "config": {"model": "text-embedding-3-large"}},
)
```
@@ -173,7 +173,7 @@ write = Task(
### Memory & embedder config {#memory-embedder-config}
If `memory=True` and you're not using the default OpenAI embeddings, you must pass an `embedder`:
If `memory=True` and you're not using the default OpenAI `text-embedding-3-large` embeddings, you must pass an `embedder`:
```python
crew = Crew(
@@ -187,4 +187,4 @@ crew = Crew(
)
```
Set the relevant provider credentials (`OPENAI_API_KEY`, `OLLAMA_HOST`, etc.) in your `.env` file. Memory storage paths are project-local by default — delete the project's memory directory if you change embedders, since dimensions don't mix.
Set the relevant provider credentials (`OPENAI_API_KEY`, `OLLAMA_HOST`, etc.) in your `.env` file. Memory storage paths are project-local by default. Existing local memory stores created with 1536-dimensional embeddings may not be compatible with the default OpenAI `text-embedding-3-large` embedder, which uses 3072 dimensions. If you hit a dimension mismatch, delete the project's memory directory, run `crewai reset-memories -m`, or explicitly configure the older embedder model until you migrate.

View File

@@ -116,7 +116,7 @@ If you haven't installed `uv` yet, follow **step 1** to quickly get it set up on
# Creating a CrewAI Project
We recommend using the `YAML` template scaffolding for a structured approach to defining agents and tasks. Here's how to get started:
`crewai create crew` now creates a JSON-first crew project. Agents live in `agents/*.jsonc`, tasks and crew-level settings live in `crew.jsonc`, and `crewai run` loads that JSON definition directly.
<Steps>
<Step title="Generate Project Scaffolding">
@@ -129,21 +129,20 @@ We recommend using the `YAML` template scaffolding for a structured approach to
```
my_project/
├── .gitignore
├── .env
├── agents/
│ └── researcher.jsonc
├── crew.jsonc
├── knowledge/
├── pyproject.toml
├── README.md
├── .env
└── src/
└── my_project/
├── __init__.py
├── main.py
├── crew.py
├── tools/
│ ├── custom_tool.py
│ └── __init__.py
└── config/
├── agents.yaml
└── tasks.yaml
├── skills/
└── tools/
```
- If you need the older Python/YAML scaffold with `crew.py`, `config/agents.yaml`, and `config/tasks.yaml`, run:
```shell
crewai create crew <your_project_name> --classic
```
</Step>
@@ -152,15 +151,15 @@ We recommend using the `YAML` template scaffolding for a structured approach to
- Your project will contain these essential files:
| File | Purpose |
| --- | --- |
| `agents.yaml` | Define your AI agents and their roles |
| `tasks.yaml` | Set up agent tasks and workflows |
| `crew.jsonc` | Configure the crew, task order, process, and input defaults |
| `agents/*.jsonc` | Define each agent's role, goal, backstory, LLM, tools, and behavior |
| `.env` | Store API keys and environment variables |
| `main.py` | Project entry point and execution flow |
| `crew.py` | Crew orchestration and coordination |
| `tools/` | Directory for custom agent tools |
| `knowledge/` | Directory for knowledge base |
| `tools/` | Optional Python files for `custom:<name>` tools |
| `knowledge/` | Optional knowledge files for agents |
| `skills/` | Optional skill files applied to the crew |
- Start by editing `agents.yaml` and `tasks.yaml` to define your crew's behavior.
- Start by editing `crew.jsonc` and the files in `agents/` to define your crew's behavior.
- Use `{placeholder}` values in agent and task text, then set defaults in `crew.jsonc` under `inputs`. When you run `crewai run`, the CLI prompts for any missing values.
- Keep sensitive information like API keys in `.env`.
</Step>

View File

@@ -1,15 +1,19 @@
---
title: "Using Annotations in crew.py"
description: "Learn how to use annotations to properly structure agents, tasks, and components in CrewAI"
description: "Learn how to use classic Python annotations to structure agents, tasks, and components in CrewAI"
icon: "at"
mode: "wide"
---
This guide explains how to use annotations to properly reference **agents**, **tasks**, and other components in the `crew.py` file.
This guide explains how to use annotations to properly reference **agents**, **tasks**, and other components in a classic `crew.py` file.
<Note>
New crew projects created with `crewai create crew <name>` are JSON-first and use `crew.jsonc` plus `agents/*.jsonc`. Use this annotations guide when you are working in a classic project created with `crewai create crew <name> --classic`, migrating an existing Python/YAML project, or need decorator-based Python control.
</Note>
## Introduction
Annotations in the CrewAI framework are used to decorate classes and methods, providing metadata and functionality to various components of your crew. These annotations help in organizing and structuring your code, making it more readable and maintainable.
Annotations in the CrewAI framework are used to decorate classes and methods, providing metadata and functionality to various components of your crew. In classic Python/YAML projects, these annotations help organize the code that loads `config/agents.yaml`, `config/tasks.yaml`, and returns the `Crew` object.
## Available Annotations
@@ -113,9 +117,9 @@ def crew(self) -> Crew:
The `@crew` annotation is used to decorate the method that creates and returns the `Crew` object. This method assembles all the components (agents and tasks) into a functional crew.
## YAML Configuration
## Classic YAML Configuration
The agent configurations are typically stored in a YAML file. Here's an example of how the `agents.yaml` file might look for the researcher agent:
In classic projects, agent configurations are typically stored in a YAML file. Here's an example of how the `agents.yaml` file might look for the researcher agent:
```yaml
researcher:
@@ -146,6 +150,6 @@ Note how the `llm` and `tools` in the YAML file correspond to the methods decora
- **Consistent Naming**: Use clear and consistent naming conventions for your methods. For example, agent methods could be named after their roles (e.g., researcher, reporting_analyst).
- **Environment Variables**: Use environment variables for sensitive information like API keys.
- **Flexibility**: Design your crew to be flexible by allowing easy addition or removal of agents and tasks.
- **YAML-Code Correspondence**: Ensure that the names and structures in your YAML files correspond correctly to the decorated methods in your Python code.
- **YAML-Code Correspondence**: In classic projects, ensure that the names and structures in your YAML files correspond correctly to the decorated methods in your Python code.
By following these guidelines and properly using annotations, you can create well-structured and maintainable crews using the CrewAI framework.
By following these guidelines and properly using annotations, you can maintain classic Python/YAML crews cleanly. For new crews, prefer the JSON-first structure covered in [Crews](/en/concepts/crews).

View File

@@ -39,85 +39,60 @@ If you have not installed CrewAI yet, follow the [installation guide](/en/instal
This creates a Flow app under `src/latest_ai_flow/`, including a starter crew under `crews/content_crew/` that you will replace with a minimal **single-agent** research crew in the next steps.
</Step>
<Step title="Configure one agent in `agents.yaml`">
Replace the contents of `src/latest_ai_flow/crews/content_crew/config/agents.yaml` with a single researcher. Variables like `{topic}` are filled from `crew.kickoff(inputs=...)`.
<Step title="Configure one agent in JSONC">
Create `src/latest_ai_flow/crews/content_crew/agents/researcher.jsonc` (create the `agents/` directory if needed). Variables like `{topic}` are filled from `crew.kickoff(inputs=...)`.
```yaml agents.yaml
# src/latest_ai_flow/crews/content_crew/config/agents.yaml
researcher:
role: >
{topic} Senior Data Researcher
goal: >
Uncover cutting-edge developments in {topic}
backstory: >
You're a seasoned researcher with a knack for uncovering the latest
developments in {topic}. You find the most relevant information and
present it clearly.
```jsonc agents/researcher.jsonc
{
"role": "{topic} Senior Data Researcher",
"goal": "Uncover cutting-edge developments in {topic}",
"backstory": "You're a seasoned researcher who finds relevant information and presents it clearly.",
"tools": ["SerperDevTool"],
"settings": {
"verbose": true
}
}
```
</Step>
<Step title="Configure one task in `tasks.yaml`">
```yaml tasks.yaml
# src/latest_ai_flow/crews/content_crew/config/tasks.yaml
research_task:
description: >
Conduct thorough research about {topic}. Use web search to find current,
credible information. The current year is 2026.
expected_output: >
A markdown report with clear sections: key trends, notable tools or companies,
and implications. Aim for 8001200 words. No fenced code blocks around the whole document.
agent: researcher
output_file: output/report.md
<Step title="Configure the crew in `crew.jsonc`">
Create `src/latest_ai_flow/crews/content_crew/crew.jsonc`:
```jsonc crew.jsonc
{
"name": "Research Crew",
"agents": ["researcher"],
"tasks": [
{
"name": "research_task",
"description": "Conduct thorough research about {topic}. Use web search to find recent, credible information.",
"expected_output": "A markdown report with clear sections: key trends, notable tools or companies, and implications. Aim for 800-1200 words. No fenced code blocks around the whole document.",
"agent": "researcher",
"output_file": "output/report.md",
"markdown": true
}
],
"process": "sequential",
"verbose": true
}
```
</Step>
<Step title="Wire the crew class (`content_crew.py`)">
Point the generated crew at your YAML and attach `SerperDevTool` to the researcher.
<Step title="Load the JSON crew (`content_crew.py`)">
Replace the generated `content_crew.py` with a small loader that turns `crew.jsonc` into a `Crew`.
```python content_crew.py
# src/latest_ai_flow/crews/content_crew/content_crew.py
from typing import List
from pathlib import Path
from crewai import Agent, Crew, Process, Task
from crewai.agents.agent_builder.base_agent import BaseAgent
from crewai.project import CrewBase, agent, crew, task
from crewai_tools import SerperDevTool
from crewai.project import load_crew
@CrewBase
class ResearchCrew:
"""Single-agent research crew used inside the Flow."""
agents: List[BaseAgent]
tasks: List[Task]
agents_config = "config/agents.yaml"
tasks_config = "config/tasks.yaml"
@agent
def researcher(self) -> Agent:
return Agent(
config=self.agents_config["researcher"], # type: ignore[index]
verbose=True,
tools=[SerperDevTool()],
)
@task
def research_task(self) -> Task:
return Task(
config=self.tasks_config["research_task"], # type: ignore[index]
)
@crew
def crew(self) -> Crew:
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True,
)
def kickoff_content_crew(inputs: dict):
crew, default_inputs = load_crew(Path(__file__).with_name("crew.jsonc"))
return crew.kickoff(inputs={**default_inputs, **inputs})
```
</Step>
@@ -131,7 +106,7 @@ If you have not installed CrewAI yet, follow the [installation guide](/en/instal
from crewai.flow import Flow, listen, start
from latest_ai_flow.crews.content_crew.content_crew import ResearchCrew
from latest_ai_flow.crews.content_crew.content_crew import kickoff_content_crew
class ResearchFlowState(BaseModel):
@@ -150,7 +125,7 @@ If you have not installed CrewAI yet, follow the [installation guide](/en/instal
@listen(prepare_topic)
def run_research(self):
result = ResearchCrew().crew().kickoff(inputs={"topic": self.state.topic})
result = kickoff_content_crew(inputs={"topic": self.state.topic})
self.state.report = result.raw
print("Research crew finished.")
@@ -172,7 +147,7 @@ If you have not installed CrewAI yet, follow the [installation guide](/en/instal
```
<Tip>
If your package name differs from `latest_ai_flow`, change the import of `ResearchCrew` to match your projects module path.
If your package name differs from `latest_ai_flow`, change the `kickoff_content_crew` import to match your projects module path.
</Tip>
</Step>
@@ -202,7 +177,7 @@ If you have not installed CrewAI yet, follow the [installation guide](/en/instal
<CodeGroup>
```markdown output/report.md
# AI Agents in 2026: Landscape and Trends
# AI Agents: Recent Landscape and Trends
## Executive summary
@@ -223,7 +198,7 @@ If you have not installed CrewAI yet, follow the [installation guide](/en/instal
## How this run fits together
1. **Flow** — `LatestAiFlow` runs `prepare_topic` first, then `run_research`, then `summarize`. State (`topic`, `report`) lives on the Flow.
2. **Crew** — `ResearchCrew` runs one task with one agent: the researcher uses **Serper** to search the web, then writes the structured report.
2. **Crew** — `kickoff_content_crew` loads `crew.jsonc` and runs one task with one agent: the researcher uses **Serper** to search the web, then writes the structured report.
3. **Artifact** — The tasks `output_file` writes the report under `output/report.md`.
To go deeper on Flow patterns (routing, persistence, human-in-the-loop), see [Build your first Flow](/en/guides/flows/first-flow) and [Flows](/en/concepts/flows). For crews without a Flow, see [Crews](/en/concepts/crews). For a single `Agent` and `kickoff()` without tasks, see [Agents](/en/concepts/agents#direct-agent-interaction-with-kickoff).
@@ -234,7 +209,10 @@ You now have an end-to-end Flow with an agent crew and a saved report — a soli
### Naming consistency
YAML keys (`researcher`, `research_task`) must match the method names on your `@CrewBase` class. See [Crews](/en/concepts/crews) for the full decorator pattern.
The names in `crew.jsonc` must match the files and task references you use:
- `agents: ["researcher"]` loads `agents/researcher.jsonc`
- `tasks[].agent: "researcher"` assigns the task to that agent
## Deploying

View File

@@ -20,7 +20,7 @@ That pulls the official skill pack into your agent workflow so it can apply Crew
## What your agent gets
- **Flows** — structure stateful apps, steps, and crew kickoffs the CrewAI way
- **Crews & agents** — YAML-first patterns, roles, tasks, and delegation
- **Crews & agents** — JSON-first patterns (`crew.jsonc`, `agents/*.jsonc`), roles, tasks, and delegation
- **Tools & integrations** — hook agents to search, APIs, and common CrewAI tools
- **Project layout** — align with CLI scaffolds and repo conventions
- **Up-to-date patterns** — skills track current CrewAI docs and recommended practices

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 455 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 420 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 343 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 327 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 449 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 MiB

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