Compare commits

..

4 Commits

Author SHA1 Message Date
Alex
fad083ffaa fix: add 'task' (singular) to TRACE_EXCLUDE_FIELDS
agent_execution_error and task_failed events have a task: Any field
holding a full Task object. 'tasks' (plural) was excluded but 'task'
(singular) was not, so the full object leaked through serialization.
2026-03-30 18:53:31 -07:00
Alex
b753012fc8 fix: preserve agent/task identification in error events and fix exclude propagation
- Add custom handlers for agent_execution_error and task_failed events to
  extract agent_role/agent_id and task_name/task_id before generic serialization
  strips them (these fields are in TRACE_EXCLUDE_FIELDS)
- Remove exclude propagation in __dict__ handler to match Pydantic fallback behavior

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-30 14:18:09 -07:00
Alex
b40098b28e fix: address PR review comments on trace serialization
1. Remove unused import Mock from test_trace_serialization.py
2. Remove unused import safe_serialize_to_dict from test_trace_serialization.py
3. Fix LLM event tools data being silently excluded: Remove 'tools' from
   TRACE_EXCLUDE_FIELDS since LLMCallStartedEvent.tools is a lightweight
   list of tool schemas, not heavy Agent.tools objects. Agent.tools is
   already excluded explicitly in _build_crew_started_data.
4. Remove dead code: complex_events class variable from TraceCollectionListener

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-30 11:00:28 -07:00
Alex
a4f1164812 fix: reduce trace event serialization bloat by excluding redundant nested objects
Each trace event was serializing the ENTIRE Crew/Task/Agent object graph into
event_data JSONB, causing 500GB+ trace tables in production. For a crew with
5 agents and 10 tasks, each event could be 50-100KB because:
- Crew serialized full tasks AND full agents (with all tools, LLM configs)
- Each Task re-serialized its agent (same Agent already in Crew.agents)
- Each Task re-serialized context tasks (same Tasks already in Crew.tasks)

This fix:
1. Adds TRACE_EXCLUDE_FIELDS constant listing back-references and heavy fields
   to exclude (crew, agent, agents, tasks, context, tools, llm, callbacks, etc.)

2. Adds _serialize_for_trace() helper that uses safe_serialize_to_dict with
   the exclusion set, keeping scalar fields (agent_role, task_name, etc.)
   that the AMP frontend actually reads

3. Updates _build_event_data() to use lightweight serialization for all
   events except crew_kickoff_started

4. Adds _build_crew_started_data() that serializes the full crew structure
   ONCE with:
   - Agents with tool_names (list of strings, not full tool objects)
   - Tasks with agent_ref (just {id, role}) instead of full agent
   - Tasks with context_task_ids (just IDs) instead of full context tasks

5. Updates to_serializable() in serialization.py to:
   - Handle callable objects (functions/lambdas) by falling through to repr()
   - Handle regular classes with __dict__ (not just Pydantic models)

Expected size reduction: 50-100KB per event down to ~1-2KB per event.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-30 09:25:01 -07:00
23279 changed files with 56967 additions and 4863140 deletions

5
.github/security.md vendored
View File

@@ -5,10 +5,7 @@ CrewAI ecosystem.
### How to Report
Please submit reports through one of the following channels:
- **crewai-vdp-ess@submit.bugcrowd.com**
- https://security.crewai.com
Please submit reports to **crewai-vdp-ess@submit.bugcrowd.com**
- **Please do not** disclose vulnerabilities via public GitHub issues, pull requests,
or social media

View File

@@ -23,12 +23,12 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6
uses: astral-sh/setup-uv@v6
with:
version: "0.11.3"
version: "0.8.4"
python-version: ${{ matrix.python-version }}
enable-cache: false
@@ -39,7 +39,7 @@ jobs:
echo "Cache populated successfully"
- name: Save uv caches
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: actions/cache/save@v4
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@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
uses: actions/checkout@v4
# 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@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5
uses: github/codeql-action/init@v4
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@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5
uses: github/codeql-action/analyze@v4
with:
category: "/language:${{matrix.language}}"

View File

@@ -13,18 +13,15 @@ on:
- "docs.json"
workflow_dispatch:
permissions:
contents: read
jobs:
check-links:
name: Check broken links
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
- uses: actions/checkout@v4
- name: Set up Node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
uses: actions/setup-node@v4
with:
node-version: "22"

View File

@@ -14,7 +14,6 @@ permissions:
jobs:
generate-specs:
if: github.event_name == 'workflow_dispatch' || github.event.pull_request.head.repo.full_name == github.repository
runs-on: ubuntu-latest
env:
PYTHONUNBUFFERED: 1
@@ -22,21 +21,21 @@ jobs:
steps:
- name: Generate GitHub App token
id: app-token
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
uses: tibdex/github-app-token@v2
with:
app-id: ${{ secrets.CREWAI_TOOL_SPECS_APP_ID }}
private-key: ${{ secrets.CREWAI_TOOL_SPECS_PRIVATE_KEY }}
app_id: ${{ secrets.CREWAI_TOOL_SPECS_APP_ID }}
private_key: ${{ secrets.CREWAI_TOOL_SPECS_PRIVATE_KEY }}
- name: Checkout code
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
uses: actions/checkout@v4
with:
ref: ${{ github.head_ref }}
token: ${{ steps.app-token.outputs.token }}
- name: Install uv
uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6
uses: astral-sh/setup-uv@v6
with:
version: "0.11.3"
version: "0.8.4"
python-version: "3.12"
enable-cache: true

View File

@@ -6,31 +6,14 @@ permissions:
contents: read
jobs:
changes:
name: Detect changes
runs-on: ubuntu-latest
outputs:
code: ${{ steps.filter.outputs.code }}
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
- uses: dorny/paths-filter@d1c1ffe0248fe513906c8e24db8ea791d46f8590 # v3
id: filter
with:
filters: |
code:
- '!docs/**'
- '!**/*.md'
lint-run:
needs: changes
if: needs.changes.outputs.code == 'true'
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
- uses: actions/checkout@v4
- name: Restore global uv cache
id: cache-restore
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: actions/cache/restore@v4
with:
path: |
~/.cache/uv
@@ -41,9 +24,9 @@ jobs:
uv-main-py3.11-
- name: Install uv
uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6
uses: astral-sh/setup-uv@v6
with:
version: "0.11.3"
version: "0.8.4"
python-version: "3.11"
enable-cache: false
@@ -58,30 +41,10 @@ jobs:
- name: Save uv caches
if: steps.cache-restore.outputs.cache-hit != 'true'
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: actions/cache/save@v4
with:
path: |
~/.cache/uv
~/.local/share/uv
.venv
key: uv-main-py3.11-${{ hashFiles('uv.lock') }}
# Summary job to provide single status for branch protection
lint:
name: lint
runs-on: ubuntu-latest
needs: [changes, lint-run]
if: always()
steps:
- name: Check results
run: |
if [ "${{ needs.changes.outputs.code }}" != "true" ]; then
echo "Docs-only change, skipping lint"
exit 0
fi
if [ "${{ needs.lint-run.result }}" == "success" ]; then
echo "Lint passed"
else
echo "Lint failed"
exit 1
fi

View File

@@ -5,10 +5,6 @@ on:
- cron: '0 6 * * *' # daily at 6am UTC
workflow_dispatch:
concurrency:
group: nightly-publish
cancel-in-progress: false
jobs:
check:
name: Check for new commits
@@ -18,15 +14,14 @@ jobs:
outputs:
has_changes: ${{ steps.check.outputs.has_changes }}
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Check for recent commits
- name: Check for commits in last 24h
id: check
run: |
# 25h window absorbs cron-vs-commit timing skew at the boundary.
RECENT=$(git log --since="25 hours ago" --oneline | head -1)
RECENT=$(git log --since="24 hours ago" --oneline | head -1)
if [ -n "$RECENT" ]; then
echo "has_changes=true" >> "$GITHUB_OUTPUT"
else
@@ -41,44 +36,36 @@ jobs:
permissions:
contents: read
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install uv
uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6
with:
version: "0.11.3"
python-version: "3.12"
enable-cache: false
uses: astral-sh/setup-uv@v4
- name: Stamp nightly versions
run: |
DATE=$(date +%Y%m%d)
# All workspace packages share the same base version and are released together.
BASE=$(python -c "
import re
print(re.search(r'__version__\s*=\s*\"(.*?)\"', open('lib/crewai/src/crewai/__init__.py').read()).group(1))
")
NIGHTLY="${BASE}.dev${DATE}"
echo "Nightly version: ${NIGHTLY}"
for init_file in \
lib/crewai/src/crewai/__init__.py \
lib/crewai-core/src/crewai_core/__init__.py \
lib/crewai-tools/src/crewai_tools/__init__.py \
lib/crewai-files/src/crewai_files/__init__.py \
lib/cli/src/crewai_cli/__init__.py; do
lib/crewai-files/src/crewai_files/__init__.py; do
CURRENT=$(python -c "
import re
text = open('$init_file').read()
print(re.search(r'__version__\s*=\s*\"(.*?)\"\s*$', text, re.MULTILINE).group(1))
")
NIGHTLY="${CURRENT}.dev${DATE}"
sed -i "s/__version__ = .*/__version__ = \"${NIGHTLY}\"/" "$init_file"
echo "Stamped $init_file -> $NIGHTLY"
echo "$init_file: $CURRENT -> $NIGHTLY"
done
# Update all cross-package dependency pins to the nightly version.
sed -i "s/\"crewai==[^\"]*\"/\"crewai==${NIGHTLY}\"/" lib/crewai-tools/pyproject.toml
sed -i "s/\"crewai-core==[^\"]*\"/\"crewai-core==${NIGHTLY}\"/" lib/crewai/pyproject.toml
sed -i "s/\"crewai-cli==[^\"]*\"/\"crewai-cli==${NIGHTLY}\"/" lib/crewai/pyproject.toml
# Update cross-package dependency pins to nightly versions
sed -i "s/\"crewai-tools==[^\"]*\"/\"crewai-tools==${NIGHTLY}\"/" lib/crewai/pyproject.toml
sed -i "s/\"crewai-files==[^\"]*\"/\"crewai-files==${NIGHTLY}\"/" lib/crewai/pyproject.toml
sed -i "s/\"crewai-core==[^\"]*\"/\"crewai-core==${NIGHTLY}\"/" lib/cli/pyproject.toml
sed -i "s/\"crewai==[^\"]*\"/\"crewai==${NIGHTLY}\"/" lib/crewai-tools/pyproject.toml
echo "Updated cross-package dependency pins to ${NIGHTLY}"
- name: Build packages
@@ -87,7 +74,7 @@ jobs:
rm dist/.gitignore
- name: Upload artifacts
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
uses: actions/upload-artifact@v4
with:
name: dist
path: dist/
@@ -98,19 +85,22 @@ jobs:
runs-on: ubuntu-latest
environment:
name: pypi
url: https://pypi.org/p/crewai
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6
uses: astral-sh/setup-uv@v6
with:
version: "0.11.3"
version: "0.8.4"
python-version: "3.12"
enable-cache: false
- name: Download artifacts
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
uses: actions/download-artifact@v4
with:
name: dist
path: dist
@@ -126,8 +116,7 @@ jobs:
continue
fi
echo "Publishing $package"
# --check-url skips files already on PyPI so manual re-runs on the same day are idempotent.
if ! uv publish --check-url https://pypi.org/simple/ "$package"; then
if ! uv publish "$package"; then
echo "Failed to publish $package"
failed=1
fi

View File

@@ -10,7 +10,7 @@ jobs:
permissions:
pull-requests: write
steps:
- uses: codelytv/pr-size-labeler@095a41fca88b8764fd9e008ad269bcdb82bb38b9 # v1
- uses: codelytv/pr-size-labeler@v1
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
xs_label: "size/XS"

View File

@@ -12,7 +12,7 @@ jobs:
pr-title:
runs-on: ubuntu-latest
steps:
- uses: amannn/action-semantic-pull-request@e32d7e603df1aa1ba07e981f2a23455dee596825 # v5
- uses: amannn/action-semantic-pull-request@v5
continue-on-error: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -24,17 +24,17 @@ jobs:
echo "tag=" >> $GITHUB_OUTPUT
fi
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
- uses: actions/checkout@v4
with:
ref: ${{ steps.release.outputs.tag || github.ref }}
- name: Set up Python
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install uv
uses: astral-sh/setup-uv@38f3f104447c67c051c4a08e39b64a148898af3a # v4
uses: astral-sh/setup-uv@v4
- name: Build packages
run: |
@@ -42,7 +42,7 @@ jobs:
rm dist/.gitignore
- name: Upload artifacts
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
uses: actions/upload-artifact@v4
with:
name: dist
path: dist/
@@ -58,19 +58,19 @@ jobs:
id-token: write
contents: read
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
- uses: actions/checkout@v4
with:
ref: ${{ inputs.release_tag || github.ref }}
- name: Install uv
uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6
uses: astral-sh/setup-uv@v6
with:
version: "0.11.3"
version: "0.8.4"
python-version: "3.12"
enable-cache: false
- name: Download artifacts
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
uses: actions/download-artifact@v4
with:
name: dist
path: dist
@@ -159,7 +159,7 @@ jobs:
- name: Notify Slack
if: success()
uses: slackapi/slack-github-action@b0fa283ad8fea605de13dc3f449259339835fc52 # v2.1.0
uses: slackapi/slack-github-action@v2.1.0
with:
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
webhook-type: incoming-webhook

View File

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

View File

@@ -6,25 +6,8 @@ permissions:
contents: read
jobs:
changes:
name: Detect changes
runs-on: ubuntu-latest
outputs:
code: ${{ steps.filter.outputs.code }}
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
- uses: dorny/paths-filter@d1c1ffe0248fe513906c8e24db8ea791d46f8590 # v3
id: filter
with:
filters: |
code:
- '!docs/**'
- '!**/*.md'
tests-matrix:
tests:
name: tests (${{ matrix.python-version }})
needs: changes
if: needs.changes.outputs.code == 'true'
runs-on: ubuntu-latest
timeout-minutes: 15
strategy:
@@ -34,13 +17,13 @@ jobs:
group: [1, 2, 3, 4, 5, 6, 7, 8]
steps:
- name: Checkout code
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch all history for proper diff
- name: Restore global uv cache
id: cache-restore
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: actions/cache/restore@v4
with:
path: |
~/.cache/uv
@@ -51,9 +34,9 @@ jobs:
uv-main-py${{ matrix.python-version }}-
- name: Install uv
uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6
uses: astral-sh/setup-uv@v6
with:
version: "0.11.3"
version: "0.8.4"
python-version: ${{ matrix.python-version }}
enable-cache: false
@@ -61,7 +44,7 @@ jobs:
run: uv sync --all-groups --all-extras
- name: Restore test durations
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: actions/cache/restore@v4
with:
path: .test_durations_py*
key: test-durations-py${{ matrix.python-version }}
@@ -108,30 +91,10 @@ jobs:
- name: Save uv caches
if: steps.cache-restore.outputs.cache-hit != 'true'
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: actions/cache/save@v4
with:
path: |
~/.cache/uv
~/.local/share/uv
.venv
key: uv-main-py${{ matrix.python-version }}-${{ hashFiles('uv.lock') }}
# Summary job to provide single status for branch protection
tests:
name: tests
runs-on: ubuntu-latest
needs: [changes, tests-matrix]
if: always()
steps:
- name: Check results
run: |
if [ "${{ needs.changes.outputs.code }}" != "true" ]; then
echo "Docs-only change, skipping tests"
exit 0
fi
if [ "${{ needs.tests-matrix.result }}" == "success" ]; then
echo "All tests passed"
else
echo "Tests failed"
exit 1
fi

View File

@@ -6,25 +6,8 @@ permissions:
contents: read
jobs:
changes:
name: Detect changes
runs-on: ubuntu-latest
outputs:
code: ${{ steps.filter.outputs.code }}
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
- uses: dorny/paths-filter@d1c1ffe0248fe513906c8e24db8ea791d46f8590 # v3
id: filter
with:
filters: |
code:
- '!docs/**'
- '!**/*.md'
type-checker-matrix:
name: type-checker (${{ matrix.python-version }})
needs: changes
if: needs.changes.outputs.code == 'true'
runs-on: ubuntu-latest
strategy:
fail-fast: false
@@ -33,11 +16,11 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
uses: actions/checkout@v4
- name: Restore global uv cache
id: cache-restore
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: actions/cache/restore@v4
with:
path: |
~/.cache/uv
@@ -48,9 +31,9 @@ jobs:
uv-main-py${{ matrix.python-version }}-
- name: Install uv
uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6
uses: astral-sh/setup-uv@v6
with:
version: "0.11.3"
version: "0.8.4"
python-version: ${{ matrix.python-version }}
enable-cache: false
@@ -62,7 +45,7 @@ jobs:
- name: Save uv caches
if: steps.cache-restore.outputs.cache-hit != 'true'
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: actions/cache/save@v4
with:
path: |
~/.cache/uv
@@ -74,18 +57,14 @@ jobs:
type-checker:
name: type-checker
runs-on: ubuntu-latest
needs: [changes, type-checker-matrix]
needs: type-checker-matrix
if: always()
steps:
- name: Check results
- name: Check matrix results
run: |
if [ "${{ needs.changes.outputs.code }}" != "true" ]; then
echo "Docs-only change, skipping type checks"
exit 0
fi
if [ "${{ needs.type-checker-matrix.result }}" == "success" ]; then
echo "All type checks passed"
if [ "${{ needs.type-checker-matrix.result }}" == "success" ] || [ "${{ needs.type-checker-matrix.result }}" == "skipped" ]; then
echo "✅ All type checks passed"
else
echo "Type checks failed"
echo "Type checks failed"
exit 1
fi

View File

@@ -23,11 +23,11 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
uses: actions/checkout@v4
- name: Restore global uv cache
id: cache-restore
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: actions/cache/restore@v4
with:
path: |
~/.cache/uv
@@ -38,9 +38,9 @@ jobs:
uv-main-py${{ matrix.python-version }}-
- name: Install uv
uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6
uses: astral-sh/setup-uv@v6
with:
version: "0.11.3"
version: "0.8.4"
python-version: ${{ matrix.python-version }}
enable-cache: false
@@ -55,14 +55,14 @@ jobs:
- name: Save durations to cache
if: always()
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: actions/cache/save@v4
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@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: actions/cache/save@v4
with:
path: |
~/.cache/uv

View File

@@ -1,108 +0,0 @@
name: Vulnerability Scan
on:
pull_request:
push:
branches: [main]
schedule:
# Run weekly on Monday at 9:00 UTC
- cron: '0 9 * * 1'
permissions:
contents: read
jobs:
pip-audit:
name: pip-audit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
persist-credentials: false
- name: Restore global uv cache
id: cache-restore
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: |
~/.cache/uv
~/.local/share/uv
.venv
key: uv-main-py3.11-${{ hashFiles('uv.lock') }}
restore-keys: |
uv-main-py3.11-
- name: Install uv
uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6
with:
version: "0.11.3"
python-version: "3.11"
enable-cache: false
- name: Install dependencies
run: uv sync --all-groups --all-extras --no-install-project
- name: Install pip-audit
run: uv pip install pip-audit
- name: Run pip-audit
run: |
pip_audit_args=(
--desc
--aliases
--skip-editable
--format json
--output pip-audit-report.json
--ignore-vuln CVE-2026-27448 # pyOpenSSL: fixes require 26.0.0, blocked by snowflake-connector-python 3.x.
--ignore-vuln CVE-2026-27459 # pyOpenSSL: same constraint as CVE-2026-27448.
--ignore-vuln PYSEC-2026-597 # nltk 3.9.4 (CVE-2026-12243): no fix available, transitive through crewai-tools[xml] -> unstructured.
--ignore-vuln GHSA-rrmf-rvhw-rf47 # torch 2.12.0 (CVE-2025-3000): local-only memory corruption in torch.jit.script; no fix available.
--ignore-vuln GHSA-f4j7-r4q5-qw2c # chromadb 1.1.1 (CVE-2026-45829): pre-auth RCE in the HTTP server; no fix available.
--ignore-vuln GHSA-xf7x-x43h-rpqh # json-repair 0.25.3: the affected schema module is absent, and CrewAI does not pass schemas.
)
uv run pip-audit "${pip_audit_args[@]}"
continue-on-error: true
- name: Display results
if: always()
run: |
if [ -f pip-audit-report.json ]; then
echo "## pip-audit Results" >> $GITHUB_STEP_SUMMARY
echo '```json' >> $GITHUB_STEP_SUMMARY
cat pip-audit-report.json | python3 -m json.tool >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
# Fail if vulnerabilities found
python3 -c "
import json, sys
with open('pip-audit-report.json') as f:
data = json.load(f)
vulns = [d for d in data.get('dependencies', []) if d.get('vulns')]
if vulns:
print(f'::error::Found vulnerabilities in {len(vulns)} package(s)')
for v in vulns:
for vuln in v['vulns']:
print(f' - {v[\"name\"]}=={v[\"version\"]}: {vuln[\"id\"]}')
sys.exit(1)
print('No known vulnerabilities found')
"
else
echo "::error::pip-audit failed to produce a report. Check the pip-audit step logs."
exit 1
fi
- name: Upload pip-audit report
if: always()
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@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: |
~/.cache/uv
~/.local/share/uv
.venv
key: uv-main-py3.11-${{ hashFiles('uv.lock') }}

3
.gitignore vendored
View File

@@ -30,6 +30,3 @@ chromadb-*.lock
.crewai/memory
blogs/*
secrets/*
UNKNOWN.egg-info/
demos/*
.crewai/*

View File

@@ -19,48 +19,11 @@ repos:
language: system
pass_filenames: true
types: [python]
exclude: ^(lib/crewai/src/crewai/cli/templates/|lib/cli/src/crewai_cli/templates/|lib/cli/tests/|lib/crewai/tests/|lib/crewai-tools/tests/|lib/crewai-files/tests/|lib/devtools/tests/)
exclude: ^(lib/crewai/src/crewai/cli/templates/|lib/crewai/tests/|lib/crewai-tools/tests/|lib/crewai-files/tests/)
- repo: https://github.com/astral-sh/uv-pre-commit
rev: 0.11.3
rev: 0.9.3
hooks:
- id: uv-lock
- repo: local
hooks:
- id: pip-audit
name: pip-audit
# 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-2026-597
--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]
- repo: https://github.com/commitizen-tools/commitizen
rev: v4.10.1
hooks:

View File

@@ -1,26 +0,0 @@
# Agent Instructions for CrewAI OSS
CrewAI is a Python based framework for building AI agents and agentic systems.
Follow these guidelines when contributing:
## Key Guidelines
1. Follow Python best practices and idiomatic patterns.
2. Maintain existing code structure and organization.
3. Write unit tests for new functionality focusing on behaivor and not
implementation.
4. Document public APIs and complex logic.
5. Suggest changes to the `docs/` folder when appropriate
6. Follow software principles such as DRY and YAGNI.
7. Keep diffs as minimal as possible.
## Changing Docs
1. Edit MDX under `docs/edge/en/*` and reference it from `docs/docs.json` if
needed.
2. Do not modify files under `docs/v*/`. Those are frozen release snapshots
managed by devtools.
3. Do not delete or rename files under `docs/images/` as frozen snapshots
may reference them.
4. If you want to preview your changes locally, use `cd docs && mintlify dev`.
To check for broken links, run `cd docs && mintlify broken-links`.

120
README.md
View File

@@ -12,8 +12,6 @@
<p align="center">
<a href="https://crewai.com">Homepage</a>
·
<a href="https://crewai.com/open-source">Open Source</a>
·
<a href="https://docs.crewai.com">Docs</a>
·
<a href="https://app.crewai.com">Start Cloud Trial</a>
@@ -55,20 +53,20 @@
### Fast and Flexible Multi-Agent Automation Framework
> CrewAI is an open-source Python framework with high-level abstractions and low-level APIs for building production-ready multi-agent workflows.
> It gives developers autonomous agent collaboration through Crews and precise, event-driven control through Flows.
> CrewAI is a lean, lightning-fast Python framework built entirely from scratch—completely **independent of LangChain or other agent frameworks**.
> It empowers developers with both high-level simplicity and precise low-level control, ideal for creating autonomous AI agents tailored to any scenario.
- **CrewAI Crews**: Optimize for autonomy and collaborative intelligence with role-based AI agents.
- **CrewAI Flows**: Build event-driven automations that combine precise workflow control, single LLM calls, and native support for Crews.
- **CrewAI Crews**: Optimize for autonomy and collaborative intelligence.
- **CrewAI Flows**: The **enterprise and production architecture** for building and deploying multi-agent systems. Enable granular, event-driven control, single LLM calls for precise task orchestration and supports Crews natively
With over 100,000 developers certified through our community courses at [learn.crewai.com](https://learn.crewai.com), CrewAI is rapidly becoming the
standard for production-ready agentic automation.
standard for enterprise-ready AI automation.
# CrewAI AMP Suite
For organizations that need a commercial control plane around CrewAI, [CrewAI AMP Suite](https://www.crewai.com/enterprise) adds managed deployment, observability, governance, security, and enterprise support.
CrewAI AMP Suite is a comprehensive bundle tailored for organizations that require secure, scalable, and easy-to-manage agent-driven automation.
You can try one part of the suite, the [Crew Control Plane, for free](https://app.crewai.com).
You can try one part of the suite the [Crew Control Plane for free](https://app.crewai.com)
## Crew Control Plane Key Features:
@@ -85,11 +83,11 @@ intelligent automations.
## Table of contents
- [Build with AI](#build-with-ai)
- [Why CrewAI?](#why-crewai)
- [Getting Started](#getting-started)
- [Key Features](#key-features)
- [Understanding Flows and Crews](#understanding-flows-and-crews)
- [CrewAI vs LangGraph](#how-crewai-compares)
- [Examples](#examples)
- [Quick Tutorial](#quick-tutorial)
- [Write Job Descriptions](#write-job-descriptions)
@@ -97,37 +95,11 @@ intelligent automations.
- [Stock Analysis](#stock-analysis)
- [Using Crews and Flows Together](#using-crews-and-flows-together)
- [Connecting Your Crew to a Model](#connecting-your-crew-to-a-model)
- [When to Use CrewAI](#when-to-use-crewai)
- [How CrewAI Compares](#how-crewai-compares)
- [Frequently Asked Questions (FAQ)](#frequently-asked-questions-faq)
- [Contribution](#contribution)
- [Telemetry](#telemetry)
- [License](#license)
- [Frequently Asked Questions (FAQ)](#frequently-asked-questions-faq)
## Build with AI
Using an AI coding agent? Teach it CrewAI best practices in one command:
**Claude Code:**
```shell
/plugin marketplace add crewAIInc/skills
/plugin install crewai-skills@crewai-plugins
/reload-plugins
```
Four skills that activate automatically when you ask relevant CrewAI questions:
| Skill | When it runs |
|-------|--------------|
| `getting-started` | Scaffolding new projects, choosing between `LLM.call()` / `Agent` / `Crew` / `Flow`, wiring `crew.py` / `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 |
**Cursor, Codex, Windsurf, and others ([skills.sh](https://skills.sh/crewaiinc/skills)):**
```shell
npx skills add crewaiinc/skills
```
This installs the official [CrewAI Skills](https://github.com/crewAIInc/skills) — structured instructions that teach coding agents how to scaffold Flows, configure Crews, design agents and tasks, and follow CrewAI patterns.
## Why CrewAI?
@@ -135,15 +107,15 @@ This installs the official [CrewAI Skills](https://github.com/crewAIInc/skills)
<img src="docs/images/asset.png" alt="CrewAI Logo" width="100%">
</div>
CrewAI unlocks the true potential of multi-agent automation, delivering speed, flexibility, and control through Crews of AI agents and event-driven Flows:
CrewAI unlocks the true potential of multi-agent automation, delivering the best-in-class combination of speed, flexibility, and control with either Crews of AI Agents or Flows of Events:
- **Purpose-built architecture**: Designed specifically for agent orchestration, with a lightweight Python core and clean primitives for real-world automation.
- **Standalone Framework**: Built from scratch, independent of LangChain or any other agent framework.
- **High Performance**: Optimized for speed and minimal resource usage, enabling faster execution.
- **Flexible Low-Level Customization**: Complete freedom to customize everything from workflows and system architecture to agent behaviors, internal prompts, and execution logic.
- **Ideal for Every Use Case**: Proven effective for simple tasks, complex workflows, and production-grade automation.
- **Flexible Low Level Customization**: Complete freedom to customize at both high and low levels - from overall workflows and system architecture to granular agent behaviors, internal prompts, and execution logic.
- **Ideal for Every Use Case**: Proven effective for both simple tasks and highly complex, real-world, enterprise-grade scenarios.
- **Robust Community**: Backed by a rapidly growing community of over **100,000 certified** developers offering comprehensive support and resources.
CrewAI empowers developers and teams to build intelligent automations that balance simplicity, flexibility, and production-grade control.
CrewAI empowers developers and enterprises to confidently build intelligent automations, bridging the gap between simplicity, flexibility, and performance.
## Getting Started
@@ -434,17 +406,16 @@ In addition to the sequential process, you can use the hierarchical process, whi
## Key Features
CrewAI gives developers a practical foundation for building agentic systems that move from prototype to production: autonomous collaboration where it helps, explicit workflow control where it matters, and Python-native customization throughout.
CrewAI stands apart as a lean, standalone, high-performance multi-AI Agent framework delivering simplicity, flexibility, and precise control—free from the complexity and limitations found in other agent frameworks.
- **Crews for autonomy**: Model teams of specialized AI agents with roles, goals, tools, and tasks.
- **Flows for control**: Build event-driven workflows with state, branching, routing, and production logic.
- **Seamless integration**: Combine Crews and Flows to create complex, real-world automations.
- **Python-native customization**: Customize prompts, tools, execution paths, state, and integrations without fighting the framework.
- **Agent-ready capabilities**: Use tools, memory, knowledge, checkpointing, async execution, and MCP/A2A support for more capable production agents.
- **Production-ready patterns**: Add deterministic steps, human input, structured outputs, and checkpointing as your system grows.
- **Thriving community**: Backed by robust documentation and over 100,000 certified developers, providing exceptional support and guidance.
- **Standalone & Lean**: Completely independent from other frameworks like LangChain, offering faster execution and lighter resource demands.
- **Flexible & Precise**: Easily orchestrate autonomous agents through intuitive [Crews](https://docs.crewai.com/concepts/crews) or precise [Flows](https://docs.crewai.com/concepts/flows), achieving perfect balance for your needs.
- **Seamless Integration**: Effortlessly combine Crews (autonomy) and Flows (precision) to create complex, real-world automations.
- **Deep Customization**: Tailor every aspect—from high-level workflows down to low-level internal prompts and agent behaviors.
- **Reliable Performance**: Consistent results across simple tasks and complex, enterprise-level automations.
- **Thriving Community**: Backed by robust documentation and over 100,000 certified developers, providing exceptional support and guidance.
Choose CrewAI to build powerful, adaptable, and production-ready AI automations.
Choose CrewAI to easily build powerful, adaptable, and production-ready AI automations.
## Examples
@@ -582,17 +553,16 @@ CrewAI supports using various LLMs through a variety of connection options. By d
Please refer to the [Connect CrewAI to LLMs](https://docs.crewai.com/how-to/LLM-Connections/) page for details on configuring your agents' connections to models.
## When to Use CrewAI
## How CrewAI Compares
Use CrewAI when you need more than a single prompt or chatbot: multi-step work, specialized agents, tool use, structured outputs, human review, or workflows that combine autonomous reasoning with explicit business logic.
**CrewAI's Advantage**: CrewAI combines autonomous agent intelligence with precise workflow control through its unique Crews and Flows architecture. The framework excels at both high-level orchestration and low-level customization, enabling complex, production-grade systems with granular control.
CrewAI is especially useful when you want to:
- **LangGraph**: While LangGraph provides a foundation for building agent workflows, its approach requires significant boilerplate code and complex state management patterns. The framework's tight coupling with LangChain can limit flexibility when implementing custom agent behaviors or integrating with external systems.
- Coordinate multiple agents with clear roles and tasks.
- Wrap agent work in deterministic, event-driven workflows.
- Keep application logic in regular Python.
- Move from experiment to production without changing frameworks.
- Add tools, memory, checkpointing, and async execution as your system grows.
_P.S. CrewAI demonstrates significant performance advantages over LangGraph, executing 5.76x faster in certain cases like this QA task example ([see comparison](https://github.com/crewAIInc/crewAI-examples/tree/main/Notebooks/CrewAI%20Flows%20%26%20Langgraph/QA%20Agent)) while achieving higher evaluation scores with faster completion times in certain coding tasks, like in this example ([detailed analysis](https://github.com/crewAIInc/crewAI-examples/blob/main/Notebooks/CrewAI%20Flows%20%26%20Langgraph/Coding%20Assistant/coding_assistant_eval.ipynb))._
- **Autogen**: While Autogen excels at creating conversational agents capable of working together, it lacks an inherent concept of process. In Autogen, orchestrating agents' interactions requires additional programming, which can become complex and cumbersome as the scale of tasks grows.
- **ChatDev**: ChatDev introduced the idea of processes into the realm of AI agents, but its implementation is quite rigid. Customizations in ChatDev are limited and not geared towards production environments, which can hinder scalability and flexibility in real-world applications.
## Contribution
@@ -604,19 +574,6 @@ CrewAI is open-source and we welcome contributions. If you're looking to contrib
- Send a pull request.
- We appreciate your input!
### Contributing to the docs
The site at [docs.crewai.com](https://docs.crewai.com) is published from
`docs/` by [Mintlify](https://www.mintlify.com/). The docs use directory-based
versioning: edits to `docs/edge/<lang>/...` (e.g.
`docs/edge/en/concepts/agents.mdx`) land under the **Edge** version selector
immediately and are frozen into a new versioned snapshot under
`docs/v<X.Y.Z>/` at the next release cut. Frozen snapshots are immutable — CI
rejects PRs that modify them without a `[docs-freeze]` title prefix. The
release CLI (`devtools release`) handles the freeze automatically; see
[`AGENTS.md`](AGENTS.md) for the full contributor guide and
[`RELEASING.md`](RELEASING.md) for the release-cut runbook.
### Installing Dependencies
```bash
@@ -701,7 +658,7 @@ CrewAI is released under the [MIT License](https://github.com/crewAIInc/crewAI/b
- [What exactly is CrewAI?](#q-what-exactly-is-crewai)
- [How do I install CrewAI?](#q-how-do-i-install-crewai)
- [Is CrewAI a standalone framework?](#q-is-crewai-a-standalone-framework)
- [Does CrewAI depend on LangChain?](#q-does-crewai-depend-on-langchain)
- [Is CrewAI open-source?](#q-is-crewai-open-source)
- [Does CrewAI collect data from users?](#q-does-crewai-collect-data-from-users)
@@ -710,6 +667,7 @@ CrewAI is released under the [MIT License](https://github.com/crewAIInc/crewAI/b
- [Can CrewAI handle complex use cases?](#q-can-crewai-handle-complex-use-cases)
- [Can I use CrewAI with local AI models?](#q-can-i-use-crewai-with-local-ai-models)
- [What makes Crews different from Flows?](#q-what-makes-crews-different-from-flows)
- [How is CrewAI better than LangChain?](#q-how-is-crewai-better-than-langchain)
- [Does CrewAI support fine-tuning or training custom models?](#q-does-crewai-support-fine-tuning-or-training-custom-models)
### Resources and Community
@@ -725,7 +683,7 @@ CrewAI is released under the [MIT License](https://github.com/crewAIInc/crewAI/b
### Q: What exactly is CrewAI?
A: CrewAI is a lean, fast Python framework built specifically for orchestrating autonomous AI agents and production-ready agentic workflows.
A: CrewAI is a standalone, lean, and fast Python framework built specifically for orchestrating autonomous AI agents. Unlike frameworks like LangChain, CrewAI does not rely on external dependencies, making it leaner, faster, and simpler.
### Q: How do I install CrewAI?
@@ -741,9 +699,9 @@ For additional tools, use:
uv pip install 'crewai[tools]'
```
### Q: Is CrewAI a standalone framework?
### Q: Does CrewAI depend on LangChain?
A: Yes. CrewAI is a standalone Python framework with its own primitives for agents, tasks, crews, flows, tools, and orchestration.
A: No. CrewAI is built entirely from the ground up, with no dependencies on LangChain or other agent frameworks. This ensures a lean, fast, and flexible experience.
### Q: Can CrewAI handle complex use cases?
@@ -757,6 +715,10 @@ A: Absolutely! CrewAI supports various language models, including local ones. To
A: Crews provide autonomous agent collaboration, ideal for tasks requiring flexible decision-making and dynamic interaction. Flows offer precise, event-driven control, ideal for managing detailed execution paths and secure state management. You can seamlessly combine both for maximum effectiveness.
### Q: How is CrewAI better than LangChain?
A: CrewAI provides simpler, more intuitive APIs, faster execution speeds, more reliable and consistent results, robust documentation, and an active community—addressing common criticisms and limitations associated with LangChain.
### Q: Is CrewAI open-source?
A: Yes, CrewAI is open-source and actively encourages community contributions and collaboration.
@@ -795,11 +757,11 @@ A: Absolutely! CrewAI agents can easily integrate with external tools, APIs, and
### Q: Is CrewAI suitable for production environments?
A: Yes, CrewAI is designed with production-grade patterns that support reliable, stable, and scalable agentic workflows.
A: Yes, CrewAI is explicitly designed with production-grade standards, ensuring reliability, stability, and scalability for enterprise deployments.
### Q: How scalable is CrewAI?
A: CrewAI is highly scalable, supporting simple automations and large-scale workflows involving numerous agents and complex tasks simultaneously.
A: CrewAI is highly scalable, supporting simple automations and large-scale enterprise workflows involving numerous agents and complex tasks simultaneously.
### Q: Does CrewAI offer debugging and monitoring tools?

View File

@@ -5,105 +5,12 @@ 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
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
from vcr.request import Request # type: ignore[import-untyped]
try:
@@ -113,42 +20,21 @@ except ModuleNotFoundError:
env_test_path = Path(__file__).parent / ".env.test"
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$")
load_dotenv(env_test_path, override=True)
load_dotenv(override=True)
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, real_request_body: Any = None, **kwargs: Any
) -> Any:
def _patched_make_vcr_request(httpx_request: Any, **kwargs: Any) -> Any:
"""Patched version of VCR's _make_vcr_request that handles binary content.
The original implementation fails on binary request bodies (like file uploads)
because it assumes all content can be decoded as UTF-8.
"""
raw_body = real_request_body if real_request_body is not None else httpx_request.read()
body: Any = raw_body
if isinstance(raw_body, bytes):
try:
body = raw_body.decode("utf-8")
except UnicodeDecodeError:
body = base64.b64encode(raw_body).decode("ascii")
raw_body = httpx_request.read()
try:
body = raw_body.decode("utf-8")
except UnicodeDecodeError:
body = base64.b64encode(raw_body).decode("ascii")
uri = str(httpx_request.url)
headers = dict(httpx_request.headers)
return Request(httpx_request.method, uri, body, headers)
@@ -168,13 +54,12 @@ _original_from_serialized_response = getattr(
)
if _original_from_serialized_response is not None:
_from_serialized: Any = _original_from_serialized_response
def _patched_from_serialized_response(
request: Any, serialized_response: Any, history: Any = None
) -> Any:
"""Patched version that ensures response._content is properly set."""
response = _from_serialized(request, serialized_response, history)
response = _original_from_serialized_response(request, serialized_response, history)
# Explicitly set _content to avoid ResponseNotRead errors
# The content was passed to the constructor but the mocked read() prevents
# proper initialization of the internal state
@@ -302,7 +187,6 @@ 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",
@@ -327,10 +211,6 @@ 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
@@ -348,11 +228,6 @@ 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)
@@ -380,8 +255,7 @@ def vcr_cassette_dir(request: Any) -> str:
for parent in test_file.parents:
if (
parent.name
in ("crewai", "crewai-tools", "crewai-files", "cli", "crewai-core")
parent.name in ("crewai", "crewai-tools", "crewai-files")
and parent.parent.name == "lib"
):
package_root = parent
@@ -403,11 +277,6 @@ 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

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

454
docs/ar/changelog.mdx Normal file
View File

@@ -0,0 +1,454 @@
---
title: "سجل التغييرات"
description: "تحديثات المنتج والتحسينات وإصلاحات الأخطاء لـ CrewAI"
icon: "clock"
mode: "wide"
---
<Update label="27 مارس 2026">
## v1.13.0rc1
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.13.0rc1)
## ما الذي تغير
### الوثائق
- تحديث سجل التغييرات والإصدار لـ v1.13.0a2
## المساهمون
@greysonlalonde
</Update>
<Update label="27 مارس 2026">
## v1.13.0a2
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.13.0a2)
## ما الذي تغير
### الميزات
- تحديث تلقائي لمستودع اختبار النشر أثناء الإصدار
- تحسين مرونة إصدار المؤسسات وتجربة المستخدم
### الوثائق
- تحديث سجل التغييرات والإصدار للإصدار v1.13.0a1
## المساهمون
@greysonlalonde
</Update>
<Update label="27 مارس 2026">
## v1.13.0a1
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.13.0a1)
## ما الذي تغير
### إصلاحات الأخطاء
- إصلاح الروابط المعطلة في سير العمل الوثائقي عن طريق تثبيت Node على LTS 22
- مسح ذاكرة التخزين المؤقت لـ uv للحزم المنشورة حديثًا في الإصدار المؤسسي
### الوثائق
- إضافة مصفوفة شاملة لأذونات RBAC ودليل النشر
- تحديث سجل التغييرات والإصدار للإصدار v1.12.2
## المساهمون
@greysonlalonde, @iris-clawd, @joaomdmoura
</Update>
<Update label="25 مارس 2026">
## v1.12.2
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.12.2)
## ما الذي تغير
### الميزات
- إضافة مرحلة إصدار المؤسسات إلى إصدار أدوات المطورين
### إصلاحات الأخطاء
- الحفاظ على قيمة إرجاع الطريقة كإخراج تدفق لـ @human_feedback مع emit
### الوثائق
- تحديث سجل التغييرات والإصدار لـ v1.12.1
- مراجعة سياسة الأمان وتعليمات الإبلاغ
## المساهمون
@alex-clawd, @greysonlalonde, @joaomdmoura, @theCyberTech
</Update>
<Update label="25 مارس 2026">
## v1.12.1
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.12.1)
## ما الذي تغير
### الميزات
- إضافة request_id إلى HumanFeedbackRequestedEvent
- إضافة Qdrant Edge كخلفية تخزين لنظام الذاكرة
- إضافة أمر docs-check لتحليل التغييرات وتوليد الوثائق مع الترجمات
- إضافة دعم اللغة العربية إلى سجل التغييرات وأدوات الإصدار
- إضافة ترجمة باللغة العربية الفصحى لجميع الوثائق
- إضافة أمر تسجيل الخروج في واجهة سطر الأوامر
- إضافة مهارات الوكيل
- تنفيذ root_scope تلقائيًا لعزل الذاكرة الهيكلية
- تنفيذ مزودين متوافقين مع OpenAI (OpenRouter، DeepSeek، Ollama، vLLM، Cerebras، Dashscope)
### إصلاحات الأخطاء
- إصلاح بيانات اعتماد غير صحيحة لدفع دفعات التتبع (404)
- حل العديد من الأخطاء في نظام تدفق HITL
- إصلاح حفظ ذاكرة الوكيل
- حل جميع أخطاء mypy الصارمة عبر حزمة crewai
- إصلاح استخدام __router_paths__ لطرق المستمع + الموجه في FlowMeta
- إصلاح خطأ القيمة عند عدم دعم الملفات
- تصحيح صياغة الحجر الصحي لـ litellm في الوثائق
- إصلاح جميع أخطاء mypy في crewai-files وإضافة جميع الحزم إلى فحوصات النوع في CI
- تثبيت الحد الأعلى لـ litellm على آخر إصدار تم اختباره (1.82.6)
### الوثائق
- تحديث سجل التغييرات والإصدار لـ v1.12.0
- إضافة CONTRIBUTING.md
- إضافة دليل لاستخدام CrewAI بدون LiteLLM
## المساهمون
@akaKuruma، @alex-clawd، @greysonlalonde، @iris-clawd، @joaomdmoura، @lorenzejay، @lucasgomide، @nicoferdi96
</Update>
<Update label="25 مارس 2026">
## v1.12.0
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.12.0)
## ما الذي تغير
### الميزات
- إضافة واجهة تخزين Qdrant Edge لنظام الذاكرة
- إضافة أمر docs-check لتحليل التغييرات وتوليد الوثائق مع الترجمات
- إضافة دعم اللغة العربية لسجل التغييرات وأدوات الإصدار
- إضافة ترجمة اللغة العربية الفصحى لجميع الوثائق
- إضافة أمر تسجيل الخروج في واجهة سطر الأوامر
- تنفيذ مهارات الوكيل
- تنفيذ نطاق الجذر التلقائي لعزل الذاكرة الهرمية
- تنفيذ موفري خدمات متوافقين مع OpenAI (OpenRouter، DeepSeek، Ollama، vLLM، Cerebras، Dashscope)
### إصلاح الأخطاء
- إصلاح بيانات الاعتماد السيئة لدفع دفعات التتبع (404)
- حل العديد من الأخطاء في نظام تدفق HITL
- حل أخطاء mypy في crewai-files وإضافة جميع الحزم إلى فحوصات نوع CI
- حل جميع أخطاء mypy الصارمة عبر حزمة crewai-tools
- حل جميع أخطاء mypy عبر حزمة crewai
- إصلاح حفظ الذاكرة في الوكيل
- إصلاح استخدام __router_paths__ لطرق المستمع + الموجه في FlowMeta
- رفع خطأ القيمة عند عدم دعم الملفات
- تصحيح صياغة الحجر الصحي لـ litellm في الوثائق
- استخدام فحص None بدلاً من isinstance للذاكرة في تعلم التغذية الراجعة البشرية
- تثبيت الحد الأعلى لـ litellm على آخر إصدار تم اختباره (1.82.6)
### الوثائق
- تحديث سجل التغييرات والإصدار لـ v1.12.0
- إضافة CONTRIBUTING.md
- إضافة دليل لاستخدام CrewAI بدون LiteLLM
### إعادة الهيكلة
- إعادة هيكلة لتجنب تكرار تنفيذ المهام المتزامنة / غير المتزامنة وبدء التشغيل في الوكيل
- تبسيط الأنابيب الداخلية من litellm (عد الرموز، ردود النداء، اكتشاف الميزات، الأخطاء)
## المساهمون
@akaKuruma، @alex-clawd، @greysonlalonde، @iris-clawd، @joaomdmoura، @lorenzejay، @nicoferdi96
</Update>
<Update label="26 مارس 2026">
## v1.12.0a3
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.12.0a3)
## ما الذي تغير
### إصلاحات الأخطاء
- إصلاح بيانات الاعتماد الخاطئة لدفع دفعات التتبع (404)
- حل العديد من الأخطاء في نظام تدفق HITL
### الوثائق
- تحديث سجل التغييرات والإصدار لـ v1.12.0a2
## المساهمون
@akaKuruma, @greysonlalonde
</Update>
<Update label="25 مارس 2026">
## v1.12.0a2
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.12.0a2)
## ما الذي تغير
### الميزات
- إضافة واجهة تخزين Qdrant Edge لنظام الذاكرة
### الوثائق
- تحديث سجل التغييرات والإصدار لـ v1.12.0a1
## المساهمون
@greysonlalonde
</Update>
<Update label="25 مارس 2026">
## v1.12.0a1
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.12.0a1)
## ما الذي تغير
### الميزات
- إضافة أمر docs-check لتحليل التغييرات وتوليد الوثائق مع الترجمات
- إضافة دعم اللغة العربية لسجل التغييرات وأدوات الإصدار
- إضافة ترجمة اللغة العربية الفصحى لجميع الوثائق
- إضافة مزودي خدمات متوافقين مع OpenAI (OpenRouter، DeepSeek، Ollama، vLLM، Cerebras، Dashscope)
- إضافة مهارات الوكيل
- إضافة أمر تسجيل الخروج في واجهة سطر الأوامر
- تنفيذ نطاق الجذر التلقائي لعزل الذاكرة الهيكلية
### إصلاح الأخطاء
- إصلاح حفظ ذاكرة الوكيل
- حل أخطاء mypy في crewai-files وإضافة جميع الحزم إلى فحوصات نوع CI
- حل جميع أخطاء mypy الصارمة عبر حزمة crewai-tools
- حل جميع أخطاء mypy عبر حزمة crewai
- إصلاح استخدام __router_paths__ لطرق المستمع + الموجه في FlowMeta
- تثبيت الحد الأعلى لـ litellm على آخر إصدار تم اختباره (1.82.6)
- رفع خطأ القيمة عند عدم دعم الملفات
- تصحيح صياغة الحجر الصحي لـ litellm في الوثائق
### الوثائق
- إضافة CONTRIBUTING.md
- إضافة دليل لاستخدام CrewAI بدون LiteLLM
- تحديث سجل التغييرات والإصدار لـ v1.11.1
### إعادة الهيكلة
- إعادة هيكلة لإزالة التكرار في تنفيذ المهام المتزامنة وغير المتزامنة وبدء التشغيل في الوكيل
- فصل الأنابيب الداخلية عن litellm (عد الرموز، ردود الفعل، اكتشاف الميزات، الأخطاء)
## المساهمون
@alex-clawd، @greysonlalonde، @iris-clawd، @lorenzejay، @nicoferdi96
</Update>
<Update label="Mar 23, 2026">
## v1.11.1
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.11.1)
## ما تغيّر
### الميزات
- إضافة مُسلسِل flow_structure() لفحص فئة Flow.
### إصلاحات الأخطاء
- إصلاح ثغرات أمنية بتحديث pypdf و tinytag و langchain-core.
- الحفاظ على تهيئة LLM الكاملة عبر استئناف HITL لمزودي غير OpenAI.
- منع اجتياز المسار في FileWriterTool.
- إصلاح انهيار lock_store عندما لا تكون حزمة redis مثبتة.
- تمرير cache_function من BaseTool إلى CrewStructuredTool.
### التوثيق
- إضافة دليل نشر الأدوات المخصصة مع الترجمات.
- تحديث سجل التغييرات والإصدار لـ v1.11.0.
- إضافة توثيق مستمعي الأحداث المفقود.
### إعادة الهيكلة
- استبدال urllib بـ requests في محمّل PDF.
- استبدال حقول callback والنموذج من نوع Any بأنواع قابلة للتسلسل.
## المساهمون
@alex-clawd, @danielfsbarreto, @dependabot[bot], @greysonlalonde, @lorenzejay, @lucasgomide, @mattatcha, @theCyberTech, @vinibrsl
</Update>
<Update label="Mar 18, 2026">
## v1.11.0
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.11.0)
## ما تغيّر
### التوثيق
- تحديث سجل التغييرات والإصدار لـ v1.11.0rc2
## المساهمون
@greysonlalonde
</Update>
<Update label="Mar 17, 2026">
## v1.11.0rc2
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.11.0rc2)
## ما تغيّر
### إصلاحات الأخطاء
- تحسين معالجة استجابات LLM والتسلسل.
- ترقية الاعتماديات الانتقالية المعرضة للخطر (authlib، PyJWT، snowflake-connector-python).
- استبدال `os.system` بـ `subprocess.run` في تثبيت pip بالوضع غير الآمن.
### التوثيق
- تحديث صفحة أداة Exa Search بتسمية ووصف وخيارات تهيئة محسّنة.
- إضافة خوادم MCP المخصصة في دليل الإرشادات.
- تحديث توثيق جامعي OTEL.
- تحديث توثيق MCP.
- تحديث سجل التغييرات والإصدار لـ v1.11.0rc1.
## المساهمون
@10ishq, @greysonlalonde, @joaomdmoura, @lucasgomide, @mattatcha, @theCyberTech, @vinibrsl
</Update>
<Update label="Mar 15, 2026">
## v1.11.0rc1
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.11.0rc1)
## ما تغيّر
### الميزات
- إضافة مصادقة رمز Plus API في a2a
- تنفيذ نمط التخطيط والتنفيذ
### إصلاحات الأخطاء
- حل مشكلة هروب صندوق حماية مفسر الكود
### التوثيق
- تحديث سجل التغييرات والإصدار لـ v1.10.2rc2
## المساهمون
@Copilot, @greysonlalonde, @lorenzejay, @theCyberTech
</Update>
<Update label="Mar 14, 2026">
## v1.10.2rc2
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.10.2rc2)
## ما تغيّر
### إصلاحات الأخطاء
- إزالة الأقفال الحصرية من عمليات التخزين للقراءة فقط
### التوثيق
- تحديث سجل التغييرات والإصدار لـ v1.10.2rc1
## المساهمون
@greysonlalonde
</Update>
<Update label="Mar 13, 2026">
## v1.10.2rc1
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.10.2rc1)
## ما تغيّر
### الميزات
- إضافة أمر الإصدار وتشغيل نشر PyPI
### إصلاحات الأخطاء
- إصلاح القفل الآمن عبر العمليات والخيوط للإدخال/الإخراج غير المحمي
- نشر contextvars عبر جميع حدود الخيوط والمنفذين
- نشر ContextVars إلى خيوط المهام غير المتزامنة
### التوثيق
- تحديث سجل التغييرات والإصدار لـ v1.10.2a1
## المساهمون
@danglies007, @greysonlalonde
</Update>
<Update label="Mar 11, 2026">
## v1.10.2a1
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.10.2a1)
## ما تغيّر
### الميزات
- إضافة دعم البحث عن الأدوات وتوفير الرموز وحقن الأدوات المناسبة ديناميكيًا أثناء التنفيذ لـ Anthropic.
- تقديم المزيد من أدوات Brave Search.
- إنشاء إجراء للإصدارات الليلية.
### إصلاحات الأخطاء
- إصلاح LockException تحت التنفيذ المتزامن متعدد العمليات.
- حل مشكلات تجميع نتائج الأدوات المتوازية في رسالة مستخدم واحدة.
- معالجة حلول أدوات MCP والقضاء على جميع الاتصالات المشتركة القابلة للتغيير.
- تحديث معالجة معاملات LLM في دالة human_feedback.
- إضافة طرق list/dict المفقودة إلى LockedListProxy و LockedDictProxy.
- نشر سياق contextvars إلى خيوط استدعاء الأدوات المتوازية.
- ترقية اعتمادية gitpython إلى >=3.1.41 لحل ثغرة اجتياز مسار CVE.
### إعادة الهيكلة
- إعادة هيكلة فئات الذاكرة لتكون قابلة للتسلسل.
### التوثيق
- تحديث سجل التغييرات والإصدار لـ v1.10.1.
## المساهمون
@akaKuruma, @github-actions[bot], @giulio-leone, @greysonlalonde, @joaomdmoura, @jonathansampson, @lorenzejay, @lucasgomide, @mattatcha
</Update>
<Update label="Mar 04, 2026">
## v1.10.1
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.10.1)
## ما تغيّر
### الميزات
- ترقية Gemini GenAI
### إصلاحات الأخطاء
- ضبط قيمة مستمع المنفذ لتجنب التكرار
- تجميع أجزاء استجابة الدوال المتوازية في كائن Content واحد في Gemini
- إظهار مخرجات التفكير من نماذج التفكير في Gemini
- تحميل أدوات MCP والمنصة عندما تكون أدوات الوكيل None
- دعم بيئات Jupyter مع حلقات أحداث قيد التشغيل في A2A
- استخدام معرّف مجهول للتتبعات المؤقتة
- تمرير ترويسة plus بشكل مشروط
- تخطي تسجيل معالج الإشارة في الخيوط غير الرئيسية لقياس الأداء عن بعد
- حقن أخطاء الأدوات كملاحظات وحل تعارضات الأسماء
- ترقية pypdf من 4.x إلى 6.7.4 لحل تنبيهات Dependabot
- حل تنبيهات أمان Dependabot الحرجة والعالية
### التوثيق
- تحديث توثيق بث webhook
- ضبط لغة التوثيق من AOP إلى AMP
### المساهمون
@Vidit-Ostwal, @greysonlalonde, @heitorado, @joaomdmoura, @lorenzejay, @lucasgomide, @mplachta
</Update>

View File

@@ -0,0 +1,558 @@
---
title: "إدارة HITL للتدفقات"
description: "مراجعة بشرية بمستوى المؤسسات للتدفقات مع إشعارات البريد الإلكتروني أولاً وقواعد التوجيه وإمكانيات الاستجابة التلقائية"
icon: "users-gear"
mode: "wide"
---
<Note>
تتطلب ميزات إدارة Flow HITL مزيّن `@human_feedback`، المتاح في **CrewAI الإصدار 1.8.0 أو أحدث**. تنطبق هذه الميزات تحديدًا على **التدفقات (Flows)**، وليس الأطقم (Crews).
</Note>
يوفر CrewAI Enterprise نظامًا شاملًا لإدارة الإنسان في الحلقة (HITL) للتدفقات يحوّل سير عمل الذكاء الاصطناعي إلى عمليات تعاونية بين الإنسان والذكاء الاصطناعي. تستخدم المنصة **بنية البريد الإلكتروني أولاً** التي تمكّن أي شخص لديه عنوان بريد إلكتروني من الرد على طلبات المراجعة — بدون الحاجة لحساب على المنصة.
## نظرة عامة
<CardGroup cols={3}>
<Card title="تصميم البريد الإلكتروني أولاً" icon="envelope">
يمكن للمستجيبين الرد مباشرة على رسائل الإشعار لتقديم الملاحظات
</Card>
<Card title="توجيه مرن" icon="route">
توجيه الطلبات إلى بريد إلكتروني محدد بناءً على أنماط الطرق أو حالة التدفق
</Card>
<Card title="استجابة تلقائية" icon="clock">
تهيئة استجابات احتياطية تلقائية عندما لا يرد أي شخص في الوقت المحدد
</Card>
</CardGroup>
### الفوائد الرئيسية
- **نموذج ذهني بسيط**: عناوين البريد الإلكتروني عالمية؛ لا حاجة لإدارة مستخدمين أو أدوار المنصة
- **مستجيبون خارجيون**: يمكن لأي شخص لديه بريد إلكتروني الرد، حتى غير مستخدمي المنصة
- **تعيين ديناميكي**: سحب بريد المعيّن مباشرة من حالة التدفق (مثل `sales_rep_email`)
- **تهيئة مخفضة**: إعدادات أقل للتهيئة، وقت أسرع للقيمة
- **البريد الإلكتروني كقناة رئيسية**: يفضل معظم المستخدمين الرد عبر البريد الإلكتروني بدلاً من تسجيل الدخول إلى لوحة التحكم
## إعداد نقاط المراجعة البشرية في التدفقات
هيّئ نقاط تفتيش المراجعة البشرية داخل تدفقاتك باستخدام مزيّن `@human_feedback`. عندما يصل التنفيذ إلى نقطة مراجعة، يتوقف النظام ويُخطر المعيّن عبر البريد الإلكتروني وينتظر الاستجابة.
```python
from crewai.flow.flow import Flow, start, listen, or_
from crewai.flow.human_feedback import human_feedback, HumanFeedbackResult
class ContentApprovalFlow(Flow):
@start()
def generate_content(self):
return "Generated marketing copy for Q1 campaign..."
@human_feedback(
message="Please review this content for brand compliance:",
emit=["approved", "rejected", "needs_revision"],
)
@listen(or_("generate_content", "needs_revision"))
def review_content(self):
return "Marketing copy for review..."
@listen("approved")
def publish_content(self, result: HumanFeedbackResult):
print(f"Publishing approved content. Reviewer notes: {result.feedback}")
@listen("rejected")
def archive_content(self, result: HumanFeedbackResult):
print(f"Content rejected. Reason: {result.feedback}")
```
للحصول على تفاصيل التنفيذ الكاملة، راجع دليل [التغذية الراجعة البشرية في التدفقات](/ar/learn/human-feedback-in-flows).
### معاملات المزيّن
| المعامل | النوع | الوصف |
|-----------|------|-------------|
| `message` | `str` | الرسالة المعروضة للمراجع البشري |
| `emit` | `list[str]` | خيارات الاستجابة الصالحة (تُعرض كأزرار في الواجهة) |
## تهيئة المنصة
الوصول إلى تهيئة HITL من: **النشر** ← **الإعدادات** ← **تهيئة الإنسان في الحلقة**
<Frame>
<img src="/images/enterprise/hitl-settings-overview.png" alt="HITL Configuration Settings" />
</Frame>
### إشعارات البريد الإلكتروني
تبديل لتفعيل أو تعطيل إشعارات البريد الإلكتروني لطلبات HITL.
| الإعداد | الافتراضي | الوصف |
|---------|---------|-------------|
| إشعارات البريد الإلكتروني | مفعّل | إرسال رسائل عند طلب الملاحظات |
<Note>
عند التعطيل، يجب على المستجيبين استخدام واجهة لوحة التحكم أو يجب تهيئة webhooks لأنظمة إشعارات مخصصة.
</Note>
### هدف SLA
تعيين وقت استجابة مستهدف لأغراض التتبع والمقاييس.
| الإعداد | الوصف |
|---------|-------------|
| هدف SLA (دقائق) | وقت الاستجابة المستهدف. يُستخدم لمقاييس لوحة التحكم وتتبع SLA |
اتركه فارغًا لتعطيل تتبع SLA.
## إشعارات واستجابات البريد الإلكتروني
يستخدم نظام HITL بنية البريد الإلكتروني أولاً حيث يمكن للمستجيبين الرد مباشرة على رسائل الإشعار.
### كيف تعمل استجابات البريد الإلكتروني
<Steps>
<Step title="إرسال الإشعار">
عند إنشاء طلب HITL، يُرسل بريد إلكتروني إلى المستجيب المعيّن مع محتوى المراجعة والسياق.
</Step>
<Step title="عنوان الرد">
يتضمن البريد عنوان رد خاص مع رمز موقّع للمصادقة.
</Step>
<Step title="رد المستخدم">
يرد المستجيب ببساطة على البريد بملاحظاته — بدون حاجة لتسجيل الدخول.
</Step>
<Step title="التحقق من الرمز">
تستقبل المنصة الرد، وتتحقق من الرمز الموقّع، وتطابق بريد المرسل.
</Step>
<Step title="استئناف التدفق">
تُسجل الملاحظات ويستمر التدفق مع مدخلات الإنسان.
</Step>
</Steps>
### تنسيق الاستجابة
يمكن للمستجيبين الرد بـ:
- **خيار emit**: إذا تطابق الرد مع خيار `emit` (مثل "approved")، يُستخدم مباشرة
- **نص حر**: أي نص استجابة يُمرر إلى التدفق كملاحظات
- **نص عادي**: يُستخدم السطر الأول من نص الرد كملاحظات
### رسائل التأكيد
بعد معالجة الرد، يستلم المستجيب رسالة تأكيد تشير إلى ما إذا تم إرسال الملاحظات بنجاح أو حدث خطأ.
### أمان رمز البريد
- الرموز موقّعة تشفيريًا للأمان
- تنتهي صلاحية الرموز بعد 7 أيام
- يجب أن يتطابق بريد المرسل مع البريد المصرّح به في الرمز
- تُرسل رسائل تأكيد/خطأ بعد المعالجة
## قواعد التوجيه
توجيه طلبات HITL إلى عناوين بريد إلكتروني محددة بناءً على أنماط الطرق.
<Frame>
<img src="/images/enterprise/hitl-settings-routing-rules.png" alt="HITL Routing Rules Configuration" />
</Frame>
### هيكل القاعدة
```json
{
"name": "Approvals to Finance",
"match": {
"method_name": "approve_*"
},
"assign_to_email": "finance@company.com",
"assign_from_input": "manager_email"
}
```
### أنماط المطابقة
| النمط | الوصف | مثال المطابقة |
|---------|-------------|---------------|
| `approve_*` | حرف بدل (أي أحرف) | `approve_payment`، `approve_vendor` |
| `review_?` | حرف واحد | `review_a`، `review_1` |
| `validate_payment` | مطابقة تامة | `validate_payment` فقط |
### أولوية التعيين
1. **تعيين ديناميكي** (`assign_from_input`): إذا تم تهيئته، يسحب البريد من حالة التدفق
2. **بريد ثابت** (`assign_to_email`): يرجع إلى البريد المهيأ
3. **منشئ النشر**: إذا لم تتطابق أي قاعدة، يُستخدم بريد منشئ النشر
### مثال التعيين الديناميكي
إذا كانت حالة تدفقك تحتوي على `{"sales_rep_email": "alice@company.com"}`، هيّئ:
```json
{
"name": "Route to Sales Rep",
"match": {
"method_name": "review_*"
},
"assign_from_input": "sales_rep_email"
}
```
سيتم تعيين الطلب إلى `alice@company.com` تلقائيًا.
<Tip>
**حالة استخدام**: اسحب المعيّن من CRM أو قاعدة البيانات أو خطوة تدفق سابقة لتوجيه المراجعات ديناميكيًا إلى الشخص المناسب.
</Tip>
## الاستجابة التلقائية
الاستجابة تلقائيًا لطلبات HITL إذا لم يستجب أي شخص خلال المهلة المحددة. يضمن هذا عدم تعليق التدفقات إلى أجل غير مسمى.
### التهيئة
| الإعداد | الوصف |
|---------|-------------|
| مفعّل | تبديل لتفعيل الاستجابة التلقائية |
| المهلة (دقائق) | الوقت المنتظر قبل الاستجابة التلقائية |
| النتيجة الافتراضية | قيمة الاستجابة (يجب أن تطابق خيار `emit`) |
<Frame>
<img src="/images/enterprise/hitl-settings-auto-respond.png" alt="HITL Auto-Response Configuration" />
</Frame>
### حالات الاستخدام
- **الامتثال لـ SLA**: ضمان عدم تعليق التدفقات إلى أجل غير مسمى
- **الموافقة الافتراضية**: الموافقة التلقائية على الطلبات منخفضة المخاطر بعد انتهاء المهلة
- **التراجع السلس**: المتابعة بافتراضي آمن عندما يكون المراجعون غير متاحين
<Warning>
استخدم الاستجابة التلقائية بحذر. فعّلها فقط للمراجعات غير الحرجة حيث تكون الاستجابة الافتراضية مقبولة.
</Warning>
## عملية المراجعة
### واجهة لوحة التحكم
توفر واجهة مراجعة HITL تجربة نظيفة ومركّزة للمراجعين:
- **عرض Markdown**: تنسيق غني لمحتوى المراجعة مع تمييز الصيغة
- **لوحة السياق**: عرض حالة التدفق وتاريخ التنفيذ والمعلومات ذات الصلة
- **إدخال الملاحظات**: تقديم ملاحظات وتعليقات مفصلة مع قرارك
- **إجراءات سريعة**: أزرار خيارات emit بنقرة واحدة مع تعليقات اختيارية
<Frame>
<img src="/images/enterprise/hitl-list-pending-feedbacks.png" alt="HITL Pending Requests List" />
</Frame>
### طرق الاستجابة
يمكن للمراجعين الاستجابة عبر ثلاث قنوات:
| الطريقة | الوصف |
|--------|-------------|
| **الرد عبر البريد** | الرد مباشرة على رسالة الإشعار |
| **لوحة التحكم** | استخدام واجهة لوحة تحكم المؤسسة |
| **API/Webhook** | استجابة برمجية عبر API |
### السجل ومسار التدقيق
يتم تتبع كل تفاعل HITL بجدول زمني كامل:
- سجل القرارات (موافقة/رفض/مراجعة)
- هوية المراجع والطابع الزمني
- الملاحظات والتعليقات المقدمة
- طريقة الاستجابة (بريد/لوحة تحكم/API)
- مقاييس وقت الاستجابة
## التحليلات والمراقبة
تتبع أداء HITL مع تحليلات شاملة.
### لوحة تحكم الأداء
<Frame>
<img src="/images/enterprise/hitl-metrics.png" alt="HITL Metrics Dashboard" />
</Frame>
<CardGroup cols={2}>
<Card title="أوقات الاستجابة" icon="stopwatch">
مراقبة متوسط وميديان أوقات الاستجابة حسب المراجع أو التدفق.
</Card>
<Card title="اتجاهات الحجم" icon="chart-bar">
تحليل أنماط حجم المراجعة لتحسين قدرة الفريق.
</Card>
<Card title="توزيع القرارات" icon="chart-pie">
عرض معدلات الموافقة/الرفض عبر أنواع المراجعة المختلفة.
</Card>
<Card title="تتبع SLA" icon="chart-line">
تتبع نسبة المراجعات المكتملة ضمن أهداف SLA.
</Card>
</CardGroup>
### التدقيق والامتثال
إمكانيات تدقيق جاهزة للمؤسسات للمتطلبات التنظيمية:
- سجل قرارات كامل مع الطوابع الزمنية
- التحقق من هوية المراجع
- سجلات تدقيق غير قابلة للتغيير
- إمكانيات التصدير لتقارير الامتثال
## حالات الاستخدام الشائعة
<AccordionGroup>
<Accordion title="المراجعات الأمنية" icon="shield-halved">
**حالة الاستخدام**: أتمتة استبيانات الأمان الداخلية مع التحقق البشري
- يولّد الذكاء الاصطناعي الردود على الاستبيانات الأمنية
- يراجع فريق الأمن ويتحقق من الدقة عبر البريد الإلكتروني
- يتم تجميع الردود المعتمدة في التقديم النهائي
- مسار تدقيق كامل للامتثال
</Accordion>
<Accordion title="الموافقة على المحتوى" icon="file-lines">
**حالة الاستخدام**: محتوى تسويقي يتطلب مراجعة قانونية/العلامة التجارية
- يولّد الذكاء الاصطناعي نصوص تسويقية أو محتوى وسائل التواصل
- التوجيه إلى بريد فريق العلامة التجارية لمراجعة النبرة/الأسلوب
- النشر التلقائي عند الموافقة
</Accordion>
<Accordion title="الموافقات المالية" icon="money-bill">
**حالة الاستخدام**: تقارير النفقات، شروط العقود، تخصيصات الميزانية
- يعالج الذكاء الاصطناعي مسبقًا ويصنف الطلبات المالية
- التوجيه بناءً على عتبات المبالغ باستخدام التعيين الديناميكي
- الحفاظ على مسار تدقيق كامل للامتثال المالي
</Accordion>
<Accordion title="التعيين الديناميكي من CRM" icon="database">
**حالة الاستخدام**: توجيه المراجعات إلى مالكي الحسابات من CRM
- يجلب التدفق بريد مالك الحساب من CRM
- تخزين البريد في حالة التدفق (مثل `account_owner_email`)
- استخدام `assign_from_input` للتوجيه إلى الشخص المناسب تلقائيًا
</Accordion>
<Accordion title="ضمان الجودة" icon="magnifying-glass">
**حالة الاستخدام**: التحقق من مخرجات الذكاء الاصطناعي قبل التسليم للعميل
- يولّد الذكاء الاصطناعي محتوى أو ردود موجهة للعميل
- يراجع فريق ضمان الجودة عبر إشعار البريد الإلكتروني
- حلقات الملاحظات تحسّن أداء الذكاء الاصطناعي بمرور الوقت
</Accordion>
</AccordionGroup>
## واجهة Webhooks API
عندما تتوقف تدفقاتك للملاحظات البشرية، يمكنك تهيئة webhooks لإرسال بيانات الطلب إلى تطبيقك. يتيح هذا:
- بناء واجهات موافقة مخصصة
- التكامل مع الأدوات الداخلية (Jira، ServiceNow، لوحات تحكم مخصصة)
- توجيه الموافقات إلى أنظمة طرف ثالث
- إشعارات تطبيقات الجوال
- أنظمة القرار المؤتمتة
<Frame>
<img src="/images/enterprise/hitl-settings-webhook.png" alt="HITL Webhook Configuration" />
</Frame>
### تهيئة Webhooks
<Steps>
<Step title="الانتقال إلى الإعدادات">
اذهب إلى **النشر** ← **الإعدادات** ← **الإنسان في الحلقة**
</Step>
<Step title="توسيع قسم Webhooks">
انقر لتوسيع تهيئة **Webhooks**
</Step>
<Step title="إضافة عنوان Webhook">
أدخل عنوان webhook الخاص بك (يجب أن يكون HTTPS في الإنتاج)
</Step>
<Step title="حفظ التهيئة">
انقر على **حفظ التهيئة** للتفعيل
</Step>
</Steps>
يمكنك تهيئة webhooks متعددة. يستقبل كل webhook نشط جميع أحداث HITL.
### أحداث Webhook
ستستقبل نقطة النهاية طلبات HTTP POST لهذه الأحداث:
| نوع الحدث | متى يُطلق |
|------------|----------------|
| `new_request` | يتوقف تدفق ويطلب ملاحظات بشرية |
### حمولة Webhook
تستقبل جميع webhooks حمولة JSON بهذا الهيكل:
```json
{
"event": "new_request",
"request": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"flow_id": "flow_abc123",
"method_name": "review_article",
"message": "Please review this article for publication.",
"emit_options": ["approved", "rejected", "request_changes"],
"state": {
"article_id": 12345,
"author": "john@example.com",
"category": "technology"
},
"metadata": {},
"created_at": "2026-01-14T12:00:00Z"
},
"deployment": {
"id": 456,
"name": "Content Review Flow",
"organization_id": 789
},
"callback_url": "https://api.crewai.com/...",
"assigned_to_email": "reviewer@company.com"
}
```
### الرد على الطلبات
لإرسال الملاحظات، **أرسل POST إلى `callback_url`** المضمّن في حمولة webhook.
```http
POST {callback_url}
Content-Type: application/json
{
"feedback": "Approved. Great article!",
"source": "my_custom_app"
}
```
### الأمان
<Info>
جميع طلبات webhook موقّعة تشفيريًا باستخدام HMAC-SHA256 لضمان الأصالة ومنع التلاعب.
</Info>
#### أمان Webhook
- **توقيعات HMAC-SHA256**: يتضمن كل webhook توقيعًا تشفيريًا
- **أسرار لكل webhook**: لكل webhook سر توقيع فريد
- **مشفرة أثناء التخزين**: أسرار التوقيع مشفرة في قاعدة البيانات
- **التحقق من الطابع الزمني**: يمنع هجمات الإعادة
#### ترويسات التوقيع
يتضمن كل طلب webhook هذه الترويسات:
| الترويسة | الوصف |
|--------|-------------|
| `X-Signature` | توقيع HMAC-SHA256: `sha256=<hex_digest>` |
| `X-Timestamp` | الطابع الزمني Unix عند توقيع الطلب |
#### التحقق
تحقق بحساب:
```python
import hmac
import hashlib
expected = hmac.new(
signing_secret.encode(),
f"{timestamp}.{payload}".encode(),
hashlib.sha256
).hexdigest()
if hmac.compare_digest(expected, signature):
# توقيع صالح
```
### معالجة الأخطاء
يجب أن تعيد نقطة نهاية webhook كود حالة 2xx لتأكيد الاستلام:
| استجابتك | سلوكنا |
|---------------|--------------|
| 2xx | تم تسليم Webhook بنجاح |
| 4xx/5xx | مسجل كفشل، بدون إعادة محاولة |
| مهلة (30 ثانية) | مسجل كفشل، بدون إعادة محاولة |
## الأمان والتحكم في الوصول المبني على الأدوار
### الوصول إلى لوحة التحكم
يُتحكم في وصول HITL على مستوى النشر:
| الصلاحية | القدرة |
|------------|------------|
| `manage_human_feedback` | تهيئة إعدادات HITL، عرض جميع الطلبات |
| `respond_to_human_feedback` | الرد على الطلبات، عرض الطلبات المعيّنة |
### تصريح استجابة البريد الإلكتروني
للردود عبر البريد:
1. يشفّر رمز الرد البريد المصرّح به
2. يجب أن يتطابق بريد المرسل مع بريد الرمز
3. يجب ألا يكون الرمز منتهي الصلاحية (7 أيام افتراضيًا)
4. يجب أن يكون الطلب لا يزال معلقًا
### مسار التدقيق
يتم تسجيل جميع إجراءات HITL:
- إنشاء الطلب
- تغييرات التعيين
- إرسال الاستجابة (مع المصدر: لوحة تحكم/بريد/API)
- حالة استئناف التدفق
## استكشاف الأخطاء وإصلاحها
### عدم إرسال الرسائل
1. تحقق من تفعيل "إشعارات البريد الإلكتروني" في التهيئة
2. تحقق من مطابقة قواعد التوجيه لاسم الطريقة
3. تحقق من صلاحية بريد المعيّن
4. تحقق من احتياطي منشئ النشر إذا لم تتطابق أي قواعد توجيه
### عدم معالجة ردود البريد
1. تحقق من عدم انتهاء صلاحية الرمز (7 أيام افتراضيًا)
2. تحقق من مطابقة بريد المرسل للبريد المعيّن
3. تأكد من أن الطلب لا يزال معلقًا (لم يتم الرد عليه بعد)
### عدم استئناف التدفق
1. تحقق من حالة الطلب في لوحة التحكم
2. تحقق من إمكانية الوصول إلى callback URL
3. تأكد من أن النشر لا يزال قيد التشغيل
## أفضل الممارسات
<Tip>
**ابدأ ببساطة**: ابدأ بإشعارات البريد الإلكتروني لمنشئ النشر، ثم أضف قواعد التوجيه مع نضوج سير عملك.
</Tip>
1. **استخدم التعيين الديناميكي**: اسحب عناوين بريد المعيّنين من حالة التدفق للتوجيه المرن.
2. **هيّئ الاستجابة التلقائية**: أعد استجابة احتياطية للمراجعات غير الحرجة لمنع تعليق التدفقات.
3. **راقب أوقات الاستجابة**: استخدم التحليلات لتحديد الاختناقات وتحسين عملية المراجعة.
4. **اجعل رسائل المراجعة واضحة**: اكتب رسائل واضحة وقابلة للتنفيذ في مزيّن `@human_feedback`.
5. **اختبر تدفق البريد**: أرسل طلبات اختبار للتحقق من تسليم البريد قبل الانتقال للإنتاج.
## الموارد ذات الصلة
<CardGroup cols={2}>
<Card title="التغذية الراجعة البشرية في التدفقات" icon="code" href="/ar/learn/human-feedback-in-flows">
دليل التنفيذ لمزيّن `@human_feedback`
</Card>
<Card title="دليل سير عمل Flow HITL" icon="route" href="/ar/enterprise/guides/human-in-the-loop">
دليل خطوة بخطوة لإعداد سير عمل HITL
</Card>
<Card title="تهيئة RBAC" icon="shield-check" href="/ar/enterprise/features/rbac">
تهيئة التحكم في الوصول المبني على الأدوار لمؤسستك
</Card>
<Card title="بث Webhook" icon="bolt" href="/ar/enterprise/features/webhook-streaming">
إعداد إشعارات الأحداث في الوقت الفعلي
</Card>
</CardGroup>

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