Compare commits

...

90 Commits
1.2.1 ... main

Author SHA1 Message Date
Greyson LaLonde
38b0b125d3 feat: use json schema for tool argument serialization
Some checks failed
Check Documentation Broken Links / Check broken links (push) Has been cancelled
Notify Downstream / notify-downstream (push) Has been cancelled
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
- Replace Python representation with JsonSchema for tool arguments
  - Remove deprecated PydanticSchemaParser in favor of direct schema generation
  - Add handling for VAR_POSITIONAL and VAR_KEYWORD parameters
  - Improve tool argument schema collection
2025-12-11 15:50:19 -05:00
Vini Brasil
9bd8ad51f7 Add docs for AOP Deploy API (#4076)
Co-authored-by: Greyson LaLonde <greyson.r.lalonde@gmail.com>
2025-12-11 15:58:17 -03:00
Heitor Carvalho
0632a054ca chore: display error message from response when tool repository login fails (#4075)
Some checks failed
Notify Downstream / notify-downstream (push) Has been cancelled
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
2025-12-11 14:56:00 -03:00
Dragos Ciupureanu
feec6b440e fix: gracefully terminate the future when executing a task async
* fix: gracefully terminate the future when executing a task async

* core: add unit test

---------

Co-authored-by: Greyson LaLonde <greyson.r.lalonde@gmail.com>
2025-12-11 12:03:33 -05:00
Greyson LaLonde
e43c7debbd fix: add idx for task ordering, tests 2025-12-11 10:18:15 -05:00
Greyson LaLonde
8ef9fe2cab fix: check platform compat for windows signals 2025-12-11 08:38:19 -05:00
Alex Larionov
807f97114f fix: set rpm controller timer as daemon to prevent process hang
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Notify Downstream / notify-downstream (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
Co-authored-by: Greyson LaLonde <greyson.r.lalonde@gmail.com>
2025-12-11 02:59:55 -05:00
Greyson LaLonde
bdafe0fac7 fix: ensure token usage recording, validate response model on stream
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
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Notify Downstream / notify-downstream (push) Has been cancelled
Check Documentation Broken Links / Check broken links (push) Has been cancelled
Build uv cache / build-cache (3.13) (push) Has been cancelled
2025-12-10 20:32:10 -05:00
Greyson LaLonde
8e99d490b0 chore: add translated docs for async
* chore: add translated docs for async

* chore: add missing pages
2025-12-10 14:17:10 -05:00
Gil Feig
34b909367b Add docs for the agent handler connector (#4012)
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
Notify Downstream / notify-downstream (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
* Add docs for the agent handler connector

* Fix links

* Update docs
2025-12-09 15:49:52 -08:00
Greyson LaLonde
22684b513e chore: add docs on native async
Some checks failed
Mark stale issues and pull requests / stale (push) Has been cancelled
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Check Documentation Broken Links / Check broken links (push) Has been cancelled
Notify Downstream / notify-downstream (push) Has been cancelled
2025-12-08 20:49:18 -05:00
Lorenze Jay
3e3b9df761 feat: bump versions to 1.7.0 (#4051)
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
Notify Downstream / notify-downstream (push) Has been cancelled
* feat: bump versions to 1.7.0

* bump
2025-12-08 16:42:12 -08:00
Greyson LaLonde
177294f588 fix: ensure nonetypes are not passed to otel (#4052)
* fix: ensure nonetypes are not passed to otel

* fix: ensure attribute is always set in span
2025-12-08 16:27:42 -08:00
Greyson LaLonde
beef712646 fix: ensure token store file ops do not deadlock
* fix: ensure token store file ops do not deadlock
* chore: update test method reference
2025-12-08 19:04:21 -05:00
Lorenze Jay
6125b866fd supporting thinking for anthropic models (#3978)
* supporting thinking for anthropic models

* drop comments here

* thinking and tool calling support

* fix: properly mock tool use and text block types in Anthropic tests

- Updated the test for the Anthropic tool use conversation flow to include type attributes for mocked ToolUseBlock and text blocks, ensuring accurate simulation of tool interactions during testing.

* feat: add AnthropicThinkingConfig for enhanced thinking capabilities

This update introduces the AnthropicThinkingConfig class to manage thinking parameters for the Anthropic completion model. The LLM and AnthropicCompletion classes have been updated to utilize this new configuration. Additionally, new test cassettes have been added to validate the functionality of thinking blocks across interactions.
2025-12-08 15:34:54 -08:00
Greyson LaLonde
f2f994612c fix: ensure otel span is closed
Some checks failed
Notify Downstream / notify-downstream (push) Has been cancelled
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (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
2025-12-05 13:23:26 -05:00
Greyson LaLonde
7fff2b654c fix: use HuggingFaceEmbeddingFunction for embeddings, update keys and add tests (#4005)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Notify Downstream / notify-downstream (push) Has been cancelled
Check Documentation Broken Links / Check broken links (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
2025-12-04 15:05:50 -08:00
Greyson LaLonde
34e09162ba feat: async flow kickoff
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Notify Downstream / notify-downstream (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
Introduces akickoff alias to flows, improves tool decorator typing, ensures _run backward compatibility, updates docs and docstrings, adds tests, and removes duplicated logic.
2025-12-04 17:08:08 -05:00
Greyson LaLonde
24d1fad7ab feat: async crew support
native async crew execution. Improves tool decorator typing, ensures _run backward compatibility, updates docs and docstrings, adds tests, and removes duplicated logic.
2025-12-04 16:53:19 -05:00
Greyson LaLonde
9b8f31fa07 feat: async task support (#4024)
* feat: add async support for tools, add async tool tests

* chore: improve tool decorator typing

* fix: ensure _run backward compat

* chore: update docs

* chore: make docstrings a little more readable

* feat: add async execution support to agent executor

* chore: add tests

* feat: add aiosqlite dep; regenerate lockfile

* feat: add async ops to memory feat; create tests

* feat: async knowledge support; add tests

* feat: add async task support

* chore: dry out duplicate logic
2025-12-04 13:34:29 -08:00
Greyson LaLonde
d898d7c02c feat: async knowledge support (#4023)
* feat: add async support for tools, add async tool tests

* chore: improve tool decorator typing

* fix: ensure _run backward compat

* chore: update docs

* chore: make docstrings a little more readable

* feat: add async execution support to agent executor

* chore: add tests

* feat: add aiosqlite dep; regenerate lockfile

* feat: add async ops to memory feat; create tests

* feat: async knowledge support; add tests

* chore: regenerate lockfile
2025-12-04 10:27:52 -08:00
Greyson LaLonde
f04c40babf feat: async memory support
Adds async support for tools with tests, async execution in the agent executor, and async operations for memory (with aiosqlite). Improves tool decorator typing, ensures _run backward compatibility, updates docs and docstrings, adds tests, and regenerates lockfiles.
2025-12-04 12:54:49 -05:00
Lorenze Jay
c456e5c5fa Lorenze/ensure hooks work with lite agents flows (#3981)
* liteagent support hooks

* wip llm.call hooks work - needs tests for this

* fix tests

* fixed more

* more tool hooks test cassettes
2025-12-04 09:38:39 -08:00
Greyson LaLonde
633e279b51 feat: add async support for tools and agent executor; improve typing and docs
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Notify Downstream / notify-downstream (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
Introduces async tool support with new tests, adds async execution to the agent executor, improves tool decorator typing, ensures _run backward compatibility, updates docs and docstrings, and adds additional tests.
2025-12-03 20:13:03 -05:00
Greyson LaLonde
a25778974d feat: a2a extensions API and async agent card caching; fix task propagation & streaming
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Notify Downstream / notify-downstream (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
Adds initial extensions API (with registry temporarily no-op), introduces aiocache for async caching, ensures reference task IDs propagate correctly, fixes streamed response model handling, updates streaming tests, and regenerates lockfiles.
2025-12-03 16:29:48 -05:00
Greyson LaLonde
09f1ba6956 feat: native async tool support
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Notify Downstream / notify-downstream (push) Has been cancelled
Check Documentation Broken Links / Check broken links (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
- add async support for tools
- add async tool tests
- improve tool decorator typing
- fix _run backward compatibility
- update docs and improve readability of docstrings
2025-12-02 16:39:58 -05:00
Greyson LaLonde
20704742e2 feat: async llm support
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
Notify Downstream / notify-downstream (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
feat: introduce async contract to BaseLLM

feat: add async call support for:

Azure provider

Anthropic provider

OpenAI provider

Gemini provider

Bedrock provider

LiteLLM provider

chore: expand scrubbed header fields (conftest, anthropic, bedrock)

chore: update docs to cover async functionality

chore: update and harden tests to support acall; re-add uri for cassette compatibility

chore: generate missing cassette

fix: ensure acall is non-abstract and set supports_tools = true for supported Anthropic models

chore: improve Bedrock async docstring and general test robustness
2025-12-01 18:56:56 -05:00
Greyson LaLonde
59180e9c9f fix: ensure supports_tools is true for all supported anthropic models
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Notify Downstream / notify-downstream (push) Has been cancelled
2025-12-01 07:21:09 -05:00
Greyson LaLonde
3ce019b07b chore: pin dependencies in crewai, crewai-tools, devtools
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Notify Downstream / notify-downstream (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
2025-11-30 19:51:20 -05:00
Greyson LaLonde
2355ec0733 feat: create sys event types and handler
feat: add system event types and handler

chore: add tests and improve signal-related error logging
2025-11-30 17:44:40 -05:00
Greyson LaLonde
c925d2d519 chore: restructure test env, cassettes, and conftest; fix flaky tests
Some checks failed
Build uv cache / build-cache (3.10) (push) Has been cancelled
Build uv cache / build-cache (3.11) (push) Has been cancelled
Build uv cache / build-cache (3.12) (push) Has been cancelled
Build uv cache / build-cache (3.13) (push) Has been cancelled
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Notify Downstream / notify-downstream (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
Consolidates pytest config, standardizes env handling, reorganizes cassette layout, removes outdated VCR configs, improves sync with threading.Condition, updates event-waiting logic, ensures cleanup, regenerates Gemini cassettes, and reverts unintended test changes.
2025-11-29 16:55:24 -05:00
Lorenze Jay
bc4e6a3127 feat: bump versions to 1.6.1 (#3993)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Notify Downstream / notify-downstream (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
* feat: bump versions to 1.6.1

* chore: update crewAI dependency version to 1.6.1 in project templates
2025-11-28 17:57:15 -08:00
Vidit Ostwal
37526c693b Fixing ChatCompletionsClinet call (#3910)
* Fixing ChatCompletionsClinet call

* Moving from json-object -> JsonSchemaFormat

* Regex handling

* Adding additionalProperties explicitly

* fix: ensure additionalProperties is recursive

---------

Co-authored-by: Greyson LaLonde <greyson.r.lalonde@gmail.com>
Co-authored-by: Lorenze Jay <63378463+lorenzejay@users.noreply.github.com>
2025-11-28 17:33:53 -08:00
Greyson LaLonde
c59173a762 fix: ensure async methods are executable for annotations 2025-11-28 19:54:40 -05:00
Lorenze Jay
4d8eec96e8 refactor: enhance model validation and provider inference in LLM class (#3976)
* refactor: enhance model validation and provider inference in LLM class

- Updated the model validation logic to support pattern matching for new models and "latest" versions, improving flexibility for various providers.
- Refactored the `_validate_model_in_constants` method to first check hardcoded constants and then fall back to pattern matching.
- Introduced `_matches_provider_pattern` to streamline provider-specific model checks.
- Enhanced the `_infer_provider_from_model` method to utilize pattern matching for better provider inference.

This refactor aims to improve the extensibility of the LLM class, allowing it to accommodate new models without requiring constant updates to the hardcoded lists.

* feat: add new Anthropic model versions to constants

- Introduced "claude-opus-4-5-20251101" and "claude-opus-4-5" to the AnthropicModels and ANTHROPIC_MODELS lists for enhanced model support.
- Added "anthropic.claude-opus-4-5-20251101-v1:0" to BedrockModels and BEDROCK_MODELS to ensure compatibility with the latest model offerings.
- Updated test cases to ensure proper environment variable handling for model validation, improving robustness in testing scenarios.

* dont infer this way - dropped
2025-11-28 13:54:40 -08:00
Greyson LaLonde
2025a26fc3 fix: ensure parameters in RagTool.add, add typing, tests (#3979)
Some checks failed
Mark stale issues and pull requests / stale (push) Has been cancelled
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Notify Downstream / notify-downstream (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
* fix: ensure parameters in RagTool.add, add typing, tests

* feat: substitute pymupdf for pypdf, better parsing performance

---------

Co-authored-by: Lorenze Jay <63378463+lorenzejay@users.noreply.github.com>
2025-11-26 22:32:43 -08:00
Greyson LaLonde
bed9a3847a fix: remove invalid param from sse client (#3980) 2025-11-26 21:37:55 -08:00
Heitor Carvalho
5239dc9859 fix: erase 'oauth2_extra' setting on 'crewai config reset' command
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Notify Downstream / notify-downstream (push) Has been cancelled
2025-11-26 18:43:44 -05:00
Lorenze Jay
52444ad390 feat: bump versions to 1.6.0 (#3974)
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
Notify Downstream / notify-downstream (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
Build uv cache / build-cache (3.10) (push) Has been cancelled
Build uv cache / build-cache (3.11) (push) Has been cancelled
Build uv cache / build-cache (3.12) (push) Has been cancelled
Build uv cache / build-cache (3.13) (push) Has been cancelled
* feat: bump versions to 1.6.0

* bump project templates
2025-11-24 17:56:30 -08:00
Greyson LaLonde
f070595e65 fix: ensure custom rag store persist path is set if passed
Co-authored-by: Lorenze Jay <63378463+lorenzejay@users.noreply.github.com>
2025-11-24 20:03:57 -05:00
Lorenze Jay
69c5eace2d Update references from AMP to AOP in documentation (#3972)
- Changed "AMP" to "AOP" in multiple locations across JSON and MDX files to reflect the correct terminology for the Agent Operations Platform.
- Updated the introduction sections in English, Korean, and Portuguese to ensure consistency in the platform's naming.
2025-11-24 16:43:30 -08:00
Vidit Ostwal
d88ac338d5 Adding drop parameters in ChatCompletionsClient
* Adding drop parameters

* Adding test case

* Just some spacing addition

* Adding drop params to maintain consistency

* Changing variable name

---------

Co-authored-by: Greyson LaLonde <greyson.r.lalonde@gmail.com>
2025-11-24 19:16:36 -05:00
Lorenze Jay
4ae8c36815 feat: enhance flow event state management (#3952)
* feat: enhance flow event state management

- Added `state` attribute to `FlowFinishedEvent` to capture the flow's state as a JSON-serialized dictionary.
- Updated flow event emissions to include the serialized state, improving traceability and debugging capabilities during flow execution.

* fix: improve state serialization in Flow class

- Enhanced the `_copy_and_serialize_state` method to handle exceptions during JSON serialization of Pydantic models, ensuring robustness in state management.
- Updated test assertions to access the state as a dictionary, aligning with the new state structure.

---------

Co-authored-by: Greyson LaLonde <greyson.r.lalonde@gmail.com>
2025-11-24 15:55:49 -08:00
Greyson LaLonde
b049b73f2e fix: ensure fuzzy returns are more strict, show type warning 2025-11-24 17:35:12 -05:00
Greyson LaLonde
d2b9c54931 fix: re-add openai response_format param, add test 2025-11-24 17:13:20 -05:00
Greyson LaLonde
a928cde6ee fix: rag tool embeddings config
* fix: ensure config is not flattened, add tests

* chore: refactor inits to model_validator

* chore: refactor rag tool config parsing

* chore: add initial docs

* chore: add additional validation aliases for provider env vars

* chore: add solid docs

* chore: move imports to top

* fix: revert circular import

* fix: lazy import qdrant-client

* fix: allow collection name config

* chore: narrow model names for google

* chore: update additional docs

* chore: add backward compat on model name aliases

* chore: add tests for config changes
2025-11-24 16:51:28 -05:00
João Moura
9c84475691 Update AMP to AOP (#3941)
Co-authored-by: Lorenze Jay <63378463+lorenzejay@users.noreply.github.com>
2025-11-24 13:15:24 -08:00
Greyson LaLonde
f3c5d1e351 feat: add streaming result support to flows and crews
* feat: add streaming result support to flows and crews
* docs: add streaming execution documentation and integration tests
2025-11-24 15:43:48 -05:00
Mark McDonald
a978267fa2 feat: Add gemini-3-pro-preview (#3950)
* Add gemini-3-pro-preview

Also refactors the tool support check for better forward compatibility.

* Add cassette for Gemini 3 Pro

---------

Co-authored-by: Greyson LaLonde <greyson.r.lalonde@gmail.com>
2025-11-24 14:49:29 -05:00
Heitor Carvalho
b759654e7d feat: support CLI login with Entra ID (#3943) 2025-11-24 15:35:59 -03:00
Greyson LaLonde
9da1f0c0aa fix: ensure flow execution start panel is not shown on plot 2025-11-24 12:50:18 -05:00
Greyson LaLonde
a559cedbd1 chore: ensure proper cassettes for agent tests
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Notify Downstream / notify-downstream (push) Has been cancelled
* chore: ensure proper cassettes for agent tests
* chore: tweak eval test to avoid race condition
2025-11-24 12:29:11 -05:00
Gil Feig
bcc3e358cb feat: Add Merge Agent Handler tool (#3911)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Notify Downstream / notify-downstream (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
* feat: Add Merge Agent Handler tool

* Fix linting issues

* Empty
2025-11-20 16:58:41 -08:00
Greyson LaLonde
d160f0874a chore: don't fail on cleanup error
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Notify Downstream / notify-downstream (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
2025-11-19 01:28:25 -05:00
Lorenze Jay
9fcf55198f feat: bump versions to 1.5.0 (#3924)
Some checks failed
Update Test Durations / update-durations (3.13) (push) Has been cancelled
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Check Documentation Broken Links / Check broken links (push) Has been cancelled
Notify Downstream / notify-downstream (push) Has been cancelled
Update Test Durations / update-durations (3.10) (push) Has been cancelled
Update Test Durations / update-durations (3.11) (push) Has been cancelled
Update Test Durations / update-durations (3.12) (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
* feat: bump versions to 1.5.0

* chore: update crewAI tools dependency to version 1.5.0 in project templates
2025-11-15 18:00:11 -08:00
Lorenze Jay
f46a846ddc chore: remove unused hooks test file (#3923)
- Deleted the `__init__.py` file from the tests/hooks directory as it contained no tests or functionality. This cleanup helps maintain a tidy test structure.
2025-11-15 17:51:42 -08:00
Greyson LaLonde
b546982690 fix: ensure instrumentation flags 2025-11-15 20:48:40 -05:00
Greyson LaLonde
d7bdac12a2 feat: a2a trust remote completion status flag
Some checks failed
Notify Downstream / notify-downstream (push) Has been cancelled
Update Test Durations / update-durations (3.10) (push) Has been cancelled
Update Test Durations / update-durations (3.11) (push) Has been cancelled
Update Test Durations / update-durations (3.12) (push) Has been cancelled
Update Test Durations / update-durations (3.13) (push) Has been cancelled
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Check Documentation Broken Links / Check broken links (push) Has been cancelled
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
- add trust_remote_completion_status flag to A2AConfig, Adds configuration flag to control whether to trust A2A agent completion status. Resolves #3899
- update docs
2025-11-13 13:43:09 -05:00
Lorenze Jay
528d812263 Lorenze/feat hooks (#3902)
* feat: implement LLM call hooks and enhance agent execution context

- Introduced LLM call hooks to allow modification of messages and responses during LLM interactions.
- Added support for before and after hooks in the CrewAgentExecutor, enabling dynamic adjustments to the execution flow.
- Created LLMCallHookContext for comprehensive access to the executor state, facilitating in-place modifications.
- Added validation for hook callables to ensure proper functionality.
- Enhanced tests for LLM hooks and tool hooks to verify their behavior and error handling capabilities.
- Updated LiteAgent and CrewAgentExecutor to accommodate the new crew context in their execution processes.

* feat: implement LLM call hooks and enhance agent execution context

- Introduced LLM call hooks to allow modification of messages and responses during LLM interactions.
- Added support for before and after hooks in the CrewAgentExecutor, enabling dynamic adjustments to the execution flow.
- Created LLMCallHookContext for comprehensive access to the executor state, facilitating in-place modifications.
- Added validation for hook callables to ensure proper functionality.
- Enhanced tests for LLM hooks and tool hooks to verify their behavior and error handling capabilities.
- Updated LiteAgent and CrewAgentExecutor to accommodate the new crew context in their execution processes.

* fix verbose

* feat: introduce crew-scoped hook decorators and refactor hook registration

- Added decorators for before and after LLM and tool calls to enhance flexibility in modifying execution behavior.
- Implemented a centralized hook registration mechanism within CrewBase to automatically register crew-scoped hooks.
- Removed the obsolete base.py file as its functionality has been integrated into the new decorators and registration system.
- Enhanced tests for the new hook decorators to ensure proper registration and execution flow.
- Updated existing hook handling to accommodate the new decorator-based approach, improving code organization and maintainability.

* feat: enhance hook management with clear and unregister functions

- Introduced functions to unregister specific before and after hooks for both LLM and tool calls, improving flexibility in hook management.
- Added clear functions to remove all registered hooks of each type, facilitating easier state management and cleanup.
- Implemented a convenience function to clear all global hooks in one call, streamlining the process for testing and execution context resets.
- Enhanced tests to verify the functionality of unregistering and clearing hooks, ensuring robust behavior in various scenarios.

* refactor: enhance hook type management for LLM and tool hooks

- Updated hook type definitions to use generic protocols for better type safety and flexibility.
- Replaced Callable type annotations with specific BeforeLLMCallHookType and AfterLLMCallHookType for clarity.
- Improved the registration and retrieval functions for before and after hooks to align with the new type definitions.
- Enhanced the setup functions to handle hook execution results, allowing for blocking of LLM calls based on hook logic.
- Updated related tests to ensure proper functionality and type adherence across the hook management system.

* feat: add execution and tool hooks documentation

- Introduced new documentation for execution hooks, LLM call hooks, and tool call hooks to provide comprehensive guidance on their usage and implementation in CrewAI.
- Updated existing documentation to include references to the new hooks, enhancing the learning resources available for users.
- Ensured consistency across multiple languages (English, Portuguese, Korean) for the new documentation, improving accessibility for a wider audience.
- Added examples and troubleshooting sections to assist users in effectively utilizing hooks for agent operations.

---------

Co-authored-by: Greyson LaLonde <greyson.r.lalonde@gmail.com>
2025-11-13 10:11:50 -08:00
Greyson LaLonde
ffd717c51a fix: custom tool docs links, add mintlify broken links action (#3903)
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
Notify Downstream / notify-downstream (push) Has been cancelled
* fix: update docs links to point to correct endpoints

* fix: update all broken doc links
2025-11-12 22:55:10 -08:00
Heitor Carvalho
fbe4aa4bd1 feat: fetch and store more data about okta authorization server (#3894)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Notify Downstream / notify-downstream (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
2025-11-12 15:28:00 -03:00
Lorenze Jay
c205d2e8de feat: implement before and after LLM call hooks in CrewAgentExecutor (#3893)
- Added support for before and after LLM call hooks to allow modification of messages and responses during LLM interactions.
- Introduced LLMCallHookContext to provide hooks with access to the executor state, enabling in-place modifications of messages.
- Updated get_llm_response function to utilize the new hooks, ensuring that modifications persist across iterations.
- Enhanced tests to verify the functionality of the hooks and their error handling capabilities, ensuring robust execution flow.
2025-11-12 08:38:13 -08:00
Daniel Barreto
fcb5b19b2e Enhance schema description of QdrantVectorSearchTool (#3891)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Notify Downstream / notify-downstream (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
2025-11-11 14:33:33 -08:00
Rip&Tear
01f0111d52 dependabot.yml creation (#3868)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Notify Downstream / notify-downstream (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
* dependabot.yml creation

* Configure dependabot for pip package updates

Co-authored-by: matt <matt@crewai.com>

* Fix Dependabot package ecosystem

* Refactor: Use uv package-ecosystem in dependabot

Co-authored-by: matt <matt@crewai.com>

* fix: ensure dependabot uses uv ecosystem

---------

Co-authored-by: Greyson LaLonde <greyson.r.lalonde@gmail.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: matt <matt@crewai.com>
2025-11-11 12:14:16 +08:00
Lorenze Jay
6b52587c67 feat: expose messages to TaskOutput and LiteAgentOutputs (#3880)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Notify Downstream / notify-downstream (push) Has been cancelled
* feat: add messages to task and agent outputs

- Introduced a new  field in  and  to capture messages from the last task execution.
- Updated the  class to store the last messages and provide a property for easy access.
- Enhanced the  and  classes to include messages in their outputs.
- Added tests to ensure that messages are correctly included in task outputs and agent outputs during execution.

* using typing_extensions for 3.10 compatability

* feat: add last_messages attribute to agent for improved task tracking

- Introduced a new `last_messages` attribute in the agent class to store messages from the last task execution.
- Updated the `Crew` class to handle the new messages attribute in task outputs.
- Enhanced existing tests to ensure that the `last_messages` attribute is correctly initialized and utilized across various guardrail scenarios.

* fix: add messages field to TaskOutput in tests for consistency

- Updated multiple test cases to include the new `messages` field in the `TaskOutput` instances.
- Ensured that all relevant tests reflect the latest changes in the TaskOutput structure, maintaining consistency across the test suite.
- This change aligns with the recent addition of the `last_messages` attribute in the agent class for improved task tracking.

* feat: preserve messages in task outputs during replay

- Added functionality to the Crew class to store and retrieve messages in task outputs.
- Enhanced the replay mechanism to ensure that messages from stored task outputs are preserved and accessible.
- Introduced a new test case to verify that messages are correctly stored and replayed, ensuring consistency in task execution and output handling.
- This change improves the overall tracking and context retention of task interactions within the CrewAI framework.

* fix original test, prev was debugging
2025-11-10 17:38:30 -08:00
Lorenze Jay
629f7f34ce docs: enhance task guardrail documentation with LLM-based validation support (#3879)
- Added section on LLM-based guardrails, explaining their usage and requirements.
- Updated examples to demonstrate the implementation of multiple guardrails, including both function-based and LLM-based approaches.
- Clarified the distinction between single and multiple guardrails in task configurations.
- Improved explanations of guardrail functionality to ensure better understanding of validation processes.
2025-11-10 15:35:42 -08:00
Lorenze Jay
0f1c173d02 feat: bump versions to 1.4.1 (#3862)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Notify Downstream / notify-downstream (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
Build uv cache / build-cache (3.10) (push) Has been cancelled
Build uv cache / build-cache (3.11) (push) Has been cancelled
Build uv cache / build-cache (3.12) (push) Has been cancelled
Build uv cache / build-cache (3.13) (push) Has been cancelled
* feat: bump versions to 1.4.1

* chore: update crewAI tools dependency to version 1.4.1 in project templates
2025-11-07 11:19:07 -08:00
Greyson LaLonde
19c5b9a35e fix: properly handle agent max iterations
fixes #3847
2025-11-07 13:54:11 -05:00
Greyson LaLonde
1ed307b58c fix: route llm model syntax to litellm
* fix: route llm model syntax to litellm

* wip: add list of supported models
2025-11-07 13:34:15 -05:00
Lorenze Jay
d29867bbb6 chore: update version numbers to 1.4.0
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Notify Downstream / notify-downstream (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
2025-11-06 23:04:44 -05:00
Lorenze Jay
b2c278ed22 refactor: improve MCP tool execution handling with concurrent futures (#3854)
- Enhanced the MCP tool execution in both synchronous and asynchronous contexts by utilizing  for better event loop management.
- Updated error handling to provide clearer messages for connection issues and task cancellations.
- Added tests to validate MCP tool execution in both sync and async scenarios, ensuring robust functionality across different contexts.
2025-11-06 19:28:08 -08:00
Greyson LaLonde
f6aed9798b feat: allow non-ast plot routes 2025-11-06 21:17:29 -05:00
Greyson LaLonde
40a2d387a1 fix: keep stopwords updated 2025-11-06 21:10:25 -05:00
Lorenze Jay
6f36d7003b Lorenze/feat mcp first class support (#3850)
* WIP transport support mcp

* refactor: streamline MCP tool loading and error handling

* linted

* Self type from typing with typing_extensions in MCP transport modules

* added tests for mcp setup

* added tests for mcp setup

* docs: enhance MCP overview with detailed integration examples and structured configurations

* feat: implement MCP event handling and logging in event listener and client

- Added MCP event types and handlers for connection and tool execution events.
- Enhanced MCPClient to emit events on connection status and tool execution.
- Updated ConsoleFormatter to handle MCP event logging.
- Introduced new MCP event types for better integration and monitoring.
2025-11-06 17:45:16 -08:00
Greyson LaLonde
9e5906c52f feat: add pydantic validation dunder to BaseInterceptor
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Notify Downstream / notify-downstream (push) Has been cancelled
2025-11-06 15:27:07 -05:00
Lorenze Jay
fc521839e4 Lorenze/fix duplicating doc ids for knowledge (#3840)
* fix: update document ID handling in ChromaDB utility functions to use SHA-256 hashing and include index for uniqueness

* test: add tests for hash-based ID generation in ChromaDB utility functions

* drop idx for preventing dups, upsert should handle dups

* fix: update document ID extraction logic in ChromaDB utility functions to check for doc_id at the top level of the document

* fix: enhance document ID generation in ChromaDB utility functions to deduplicate documents and ensure unique hash-based IDs without suffixes

* fix: improve error handling and document ID generation in ChromaDB utility functions to ensure robust processing and uniqueness
2025-11-06 10:59:52 -08:00
Greyson LaLonde
e4cc9a664c fix: handle unpickleable values in flow state
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Notify Downstream / notify-downstream (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
2025-11-06 01:29:21 -05:00
Greyson LaLonde
7e6171d5bc fix: ensure lite agents course-correct on validation errors
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Notify Downstream / notify-downstream (push) Has been cancelled
* fix: ensure lite agents course-correct on validation errors

* chore: update cassettes and test expectations

* fix: ensure multiple guardrails propogate
2025-11-05 19:02:11 -05:00
Greyson LaLonde
61ad1fb112 feat: add support for llm message interceptor hooks 2025-11-05 11:38:44 -05:00
Greyson LaLonde
54710a8711 fix: hash callback args correctly to ensure caching works
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Notify Downstream / notify-downstream (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
2025-11-05 07:19:09 -05:00
Lucas Gomide
5abf976373 fix: allow adding RAG source content from valid URLs (#3831)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Notify Downstream / notify-downstream (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
2025-11-04 07:58:40 -05:00
Greyson LaLonde
329567153b fix: make plot node selection smoother
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Notify Downstream / notify-downstream (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
2025-11-03 07:49:31 -05:00
Greyson LaLonde
60332e0b19 feat: cache i18n prompts for efficient use 2025-11-03 07:39:05 -05:00
Lorenze Jay
40932af3fa feat: bump versions to 1.3.0 (#3820)
Some checks failed
Build uv cache / build-cache (3.10) (push) Has been cancelled
Build uv cache / build-cache (3.11) (push) Has been cancelled
Build uv cache / build-cache (3.12) (push) Has been cancelled
Build uv cache / build-cache (3.13) (push) Has been cancelled
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Notify Downstream / notify-downstream (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
* feat: bump versions to 1.3.0

* chore: update crew and flow templates to use crewai[tools] version 1.3.0
2025-10-31 18:54:02 -07:00
Greyson LaLonde
e134e5305b Gl/feat/a2a refactor (#3793)
* feat: agent metaclass, refactor a2a to wrappers

* feat: a2a schemas and utils

* chore: move agent class, update imports

* refactor: organize imports to avoid circularity, add a2a to console

* feat: pass response_model through call chain

* feat: add standard openapi spec serialization to tools and structured output

* feat: a2a events

* chore: add a2a to pyproject

* docs: minimal base for learn docs

* fix: adjust a2a conversation flow, allow llm to decide exit until max_retries

* fix: inject agent skills into initial prompt

* fix: format agent card as json in prompt

* refactor: simplify A2A agent prompt formatting and improve skill display

* chore: wide cleanup

* chore: cleanup logic, add auth cache, use json for messages in prompt

* chore: update docs

* fix: doc snippets formatting

* feat: optimize A2A agent card fetching and improve error reporting

* chore: move imports to top of file

* chore: refactor hasattr check

* chore: add httpx-auth, update lockfile

* feat: create base public api

* chore: cleanup modules, add docstrings, types

* fix: exclude extra fields in prompt

* chore: update docs

* tests: update to correct import

* chore: lint for ruff, add missing import

* fix: tweak openai streaming logic for response model

* tests: add reimport for test

* tests: add reimport for test

* fix: don't set a2a attr if not set

* fix: don't set a2a attr if not set

* chore: update cassettes

* tests: fix tests

* fix: use instructor and dont pass response_format for litellm

* chore: consolidate event listeners, add typing

* fix: address race condition in test, update cassettes

* tests: add correct mocks, rerun cassette for json

* tests: update cassette

* chore: regenerate cassette after new run

* fix: make token manager access-safe

* fix: make token manager access-safe

* merge

* chore: update test and cassete for output pydantic

* fix: tweak to disallow deadlock

* chore: linter

* fix: adjust event ordering for threading

* fix: use conditional for batch check

* tests: tweak for emission

* tests: simplify api + event check

* fix: ensure non-function calling llms see json formatted string

* tests: tweak message comparison

* fix: use internal instructor for litellm structure responses

---------

Co-authored-by: Mike Plachta <mike@crewai.com>
2025-10-31 18:42:03 -07:00
Greyson LaLonde
e229ef4e19 refactor: improve flow handling, typing, and logging; update UI and tests
fix: refine nested flow conditionals and ensure router methods and routes are fully parsed
fix: improve docstrings, typing, and logging coverage across all events
feat: update flow.plot feature with new UI enhancements
chore: apply Ruff linting, reorganize imports, and remove deprecated utilities/files
chore: split constants and utils, clean JS comments, and add typing for linters
tests: strengthen test coverage for flow execution paths and router logic
2025-10-31 21:15:06 -04:00
Greyson LaLonde
2e9eb8c32d fix: refactor use_stop_words to property, add check for stop words
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Notify Downstream / notify-downstream (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
2025-10-29 19:14:01 +01:00
Lucas Gomide
4ebb5114ed Fix Firecrawl tools & adding tests (#3810)
* fix: fix Firecrawl Scrape tool

* fix: fix Firecrawl Search tool

* fix: fix Firecrawl Website tool

* tests: adding tests for Firecrawl
2025-10-29 13:37:57 -04:00
Daniel Barreto
70b083945f Enhance QdrantVectorSearchTool (#3806)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Notify Downstream / notify-downstream (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
2025-10-28 13:42:40 -04:00
Tony Kipkemboi
410db1ff39 docs: migrate embedder→embedding_model and require vectordb across tool docs; add provider examples (en/ko/pt-BR) (#3804)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Notify Downstream / notify-downstream (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
* docs(tools): migrate embedder->embedding_model, require vectordb; add Chroma/Qdrant examples across en/ko/pt-BR PDF/TXT/XML/MDX/DOCX/CSV/Directory docs

* docs(observability): apply latest Datadog tweaks in ko and pt-BR
2025-10-27 13:29:21 -04:00
1019 changed files with 121332 additions and 94215 deletions

161
.env.test Normal file
View File

@@ -0,0 +1,161 @@
# =============================================================================
# Test Environment Variables
# =============================================================================
# This file contains all environment variables needed to run tests locally
# in a way that mimics the GitHub Actions CI environment.
# =============================================================================
# -----------------------------------------------------------------------------
# LLM Provider API Keys
# -----------------------------------------------------------------------------
OPENAI_API_KEY=fake-api-key
ANTHROPIC_API_KEY=fake-anthropic-key
GEMINI_API_KEY=fake-gemini-key
AZURE_API_KEY=fake-azure-key
OPENROUTER_API_KEY=fake-openrouter-key
# -----------------------------------------------------------------------------
# AWS Credentials
# -----------------------------------------------------------------------------
AWS_ACCESS_KEY_ID=fake-aws-access-key
AWS_SECRET_ACCESS_KEY=fake-aws-secret-key
AWS_DEFAULT_REGION=us-east-1
AWS_REGION_NAME=us-east-1
# -----------------------------------------------------------------------------
# Azure OpenAI Configuration
# -----------------------------------------------------------------------------
AZURE_ENDPOINT=https://fake-azure-endpoint.openai.azure.com
AZURE_OPENAI_ENDPOINT=https://fake-azure-endpoint.openai.azure.com
AZURE_OPENAI_API_KEY=fake-azure-openai-key
AZURE_API_VERSION=2024-02-15-preview
OPENAI_API_VERSION=2024-02-15-preview
# -----------------------------------------------------------------------------
# Google Cloud Configuration
# -----------------------------------------------------------------------------
#GOOGLE_CLOUD_PROJECT=fake-gcp-project
#GOOGLE_CLOUD_LOCATION=us-central1
# -----------------------------------------------------------------------------
# OpenAI Configuration
# -----------------------------------------------------------------------------
OPENAI_BASE_URL=https://api.openai.com/v1
OPENAI_API_BASE=https://api.openai.com/v1
# -----------------------------------------------------------------------------
# Search & Scraping Tool API Keys
# -----------------------------------------------------------------------------
SERPER_API_KEY=fake-serper-key
EXA_API_KEY=fake-exa-key
BRAVE_API_KEY=fake-brave-key
FIRECRAWL_API_KEY=fake-firecrawl-key
TAVILY_API_KEY=fake-tavily-key
SERPAPI_API_KEY=fake-serpapi-key
SERPLY_API_KEY=fake-serply-key
LINKUP_API_KEY=fake-linkup-key
PARALLEL_API_KEY=fake-parallel-key
# -----------------------------------------------------------------------------
# Exa Configuration
# -----------------------------------------------------------------------------
EXA_BASE_URL=https://api.exa.ai
# -----------------------------------------------------------------------------
# Web Scraping & Automation
# -----------------------------------------------------------------------------
BRIGHT_DATA_API_KEY=fake-brightdata-key
BRIGHT_DATA_ZONE=fake-zone
BRIGHTDATA_API_URL=https://api.brightdata.com
BRIGHTDATA_DEFAULT_TIMEOUT=600
BRIGHTDATA_DEFAULT_POLLING_INTERVAL=1
OXYLABS_USERNAME=fake-oxylabs-user
OXYLABS_PASSWORD=fake-oxylabs-pass
SCRAPFLY_API_KEY=fake-scrapfly-key
SCRAPEGRAPH_API_KEY=fake-scrapegraph-key
BROWSERBASE_API_KEY=fake-browserbase-key
BROWSERBASE_PROJECT_ID=fake-browserbase-project
HYPERBROWSER_API_KEY=fake-hyperbrowser-key
MULTION_API_KEY=fake-multion-key
APIFY_API_TOKEN=fake-apify-token
# -----------------------------------------------------------------------------
# Database & Vector Store Credentials
# -----------------------------------------------------------------------------
SINGLESTOREDB_URL=mysql://fake:fake@localhost:3306/fake
SINGLESTOREDB_HOST=localhost
SINGLESTOREDB_PORT=3306
SINGLESTOREDB_USER=fake-user
SINGLESTOREDB_PASSWORD=fake-password
SINGLESTOREDB_DATABASE=fake-database
SINGLESTOREDB_CONNECT_TIMEOUT=30
SNOWFLAKE_USER=fake-snowflake-user
SNOWFLAKE_PASSWORD=fake-snowflake-password
SNOWFLAKE_ACCOUNT=fake-snowflake-account
SNOWFLAKE_WAREHOUSE=fake-snowflake-warehouse
SNOWFLAKE_DATABASE=fake-snowflake-database
SNOWFLAKE_SCHEMA=fake-snowflake-schema
WEAVIATE_URL=http://localhost:8080
WEAVIATE_API_KEY=fake-weaviate-key
EMBEDCHAIN_DB_URI=sqlite:///test.db
# Databricks Credentials
DATABRICKS_HOST=https://fake-databricks.cloud.databricks.com
DATABRICKS_TOKEN=fake-databricks-token
DATABRICKS_CONFIG_PROFILE=fake-profile
# MongoDB Credentials
MONGODB_URI=mongodb://fake:fake@localhost:27017/fake
# -----------------------------------------------------------------------------
# CrewAI Platform & Enterprise
# -----------------------------------------------------------------------------
# setting CREWAI_PLATFORM_INTEGRATION_TOKEN causes these test to fail:
#=========================== short test summary info ============================
#FAILED tests/test_context.py::TestPlatformIntegrationToken::test_platform_context_manager_basic_usage - AssertionError: assert 'fake-platform-token' is None
# + where 'fake-platform-token' = get_platform_integration_token()
#FAILED tests/test_context.py::TestPlatformIntegrationToken::test_context_var_isolation_between_tests - AssertionError: assert 'fake-platform-token' is None
# + where 'fake-platform-token' = get_platform_integration_token()
#FAILED tests/test_context.py::TestPlatformIntegrationToken::test_multiple_sequential_context_managers - AssertionError: assert 'fake-platform-token' is None
# + where 'fake-platform-token' = get_platform_integration_token()
#CREWAI_PLATFORM_INTEGRATION_TOKEN=fake-platform-token
CREWAI_PERSONAL_ACCESS_TOKEN=fake-personal-token
CREWAI_PLUS_URL=https://fake.crewai.com
# -----------------------------------------------------------------------------
# Other Service API Keys
# -----------------------------------------------------------------------------
ZAPIER_API_KEY=fake-zapier-key
PATRONUS_API_KEY=fake-patronus-key
MINDS_API_KEY=fake-minds-key
HF_TOKEN=fake-hf-token
# -----------------------------------------------------------------------------
# Feature Flags/Testing Modes
# -----------------------------------------------------------------------------
CREWAI_DISABLE_TELEMETRY=true
OTEL_SDK_DISABLED=true
CREWAI_TESTING=true
CREWAI_TRACING_ENABLED=false
# -----------------------------------------------------------------------------
# Testing/CI Configuration
# -----------------------------------------------------------------------------
# VCR recording mode: "none" (default), "new_episodes", "all", "once"
PYTEST_VCR_RECORD_MODE=none
# Set to "true" by GitHub when running in GitHub Actions
# GITHUB_ACTIONS=false
# -----------------------------------------------------------------------------
# Python Configuration
# -----------------------------------------------------------------------------
PYTHONUNBUFFERED=1

11
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,11 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
- package-ecosystem: uv # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "weekly"

35
.github/workflows/docs-broken-links.yml vendored Normal file
View File

@@ -0,0 +1,35 @@
name: Check Documentation Broken Links
on:
pull_request:
paths:
- "docs/**"
- "docs.json"
push:
branches:
- main
paths:
- "docs/**"
- "docs.json"
workflow_dispatch:
jobs:
check-links:
name: Check broken links
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: "latest"
- name: Install Mintlify CLI
run: npm i -g mintlify
- name: Run broken link checker
run: |
# Auto-answer the prompt with yes command
yes "" | mintlify broken-links || test $? -eq 141
working-directory: ./docs

View File

@@ -5,18 +5,6 @@ on: [pull_request]
permissions:
contents: read
env:
OPENAI_API_KEY: fake-api-key
PYTHONUNBUFFERED: 1
BRAVE_API_KEY: fake-brave-key
SNOWFLAKE_USER: fake-snowflake-user
SNOWFLAKE_PASSWORD: fake-snowflake-password
SNOWFLAKE_ACCOUNT: fake-snowflake-account
SNOWFLAKE_WAREHOUSE: fake-snowflake-warehouse
SNOWFLAKE_DATABASE: fake-snowflake-database
SNOWFLAKE_SCHEMA: fake-snowflake-schema
EMBEDCHAIN_DB_URI: sqlite:///test.db
jobs:
tests:
name: tests (${{ matrix.python-version }})
@@ -84,26 +72,20 @@ jobs:
# fi
cd lib/crewai && uv run pytest \
--block-network \
--timeout=30 \
-vv \
--splits 8 \
--group ${{ matrix.group }} \
$DURATIONS_ARG \
--durations=10 \
-n auto \
--maxfail=3
- name: Run tool tests (group ${{ matrix.group }} of 8)
run: |
cd lib/crewai-tools && uv run pytest \
--block-network \
--timeout=30 \
-vv \
--splits 8 \
--group ${{ matrix.group }} \
--durations=10 \
-n auto \
--maxfail=3

View File

@@ -19,6 +19,7 @@ repos:
language: system
pass_filenames: true
types: [python]
exclude: ^(lib/crewai/src/crewai/cli/templates/|lib/crewai/tests/|lib/crewai-tools/tests/)
- repo: https://github.com/astral-sh/uv-pre-commit
rev: 0.9.3
hooks:

View File

@@ -62,9 +62,9 @@
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 enterprise-ready AI automation.
# CrewAI AMP Suite
# CrewAI AOP Suite
CrewAI AMP Suite is a comprehensive bundle tailored for organizations that require secure, scalable, and easy-to-manage agent-driven automation.
CrewAI AOP 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)
@@ -76,9 +76,9 @@ You can try one part of the suite the [Crew Control Plane for free](https://app.
- **Advanced Security**: Built-in robust security and compliance measures ensuring safe deployment and management.
- **Actionable Insights**: Real-time analytics and reporting to optimize performance and decision-making.
- **24/7 Support**: Dedicated enterprise support to ensure uninterrupted operation and quick resolution of issues.
- **On-premise and Cloud Deployment Options**: Deploy CrewAI AMP on-premise or in the cloud, depending on your security and compliance requirements.
- **On-premise and Cloud Deployment Options**: Deploy CrewAI AOP on-premise or in the cloud, depending on your security and compliance requirements.
CrewAI AMP is designed for enterprises seeking a powerful, reliable solution to transform complex business processes into efficient,
CrewAI AOP is designed for enterprises seeking a powerful, reliable solution to transform complex business processes into efficient,
intelligent automations.
## Table of contents
@@ -674,9 +674,9 @@ CrewAI is released under the [MIT License](https://github.com/crewAIInc/crewAI/b
### Enterprise Features
- [What additional features does CrewAI AMP offer?](#q-what-additional-features-does-crewai-amp-offer)
- [Is CrewAI AMP available for cloud and on-premise deployments?](#q-is-crewai-amp-available-for-cloud-and-on-premise-deployments)
- [Can I try CrewAI AMP for free?](#q-can-i-try-crewai-amp-for-free)
- [What additional features does CrewAI AOP offer?](#q-what-additional-features-does-crewai-amp-offer)
- [Is CrewAI AOP available for cloud and on-premise deployments?](#q-is-crewai-amp-available-for-cloud-and-on-premise-deployments)
- [Can I try CrewAI AOP for free?](#q-can-i-try-crewai-amp-for-free)
### Q: What exactly is CrewAI?
@@ -732,17 +732,17 @@ A: Check out practical examples in the [CrewAI-examples repository](https://gith
A: Contributions are warmly welcomed! Fork the repository, create your branch, implement your changes, and submit a pull request. See the Contribution section of the README for detailed guidelines.
### Q: What additional features does CrewAI AMP offer?
### Q: What additional features does CrewAI AOP offer?
A: CrewAI AMP provides advanced features such as a unified control plane, real-time observability, secure integrations, advanced security, actionable insights, and dedicated 24/7 enterprise support.
A: CrewAI AOP provides advanced features such as a unified control plane, real-time observability, secure integrations, advanced security, actionable insights, and dedicated 24/7 enterprise support.
### Q: Is CrewAI AMP available for cloud and on-premise deployments?
### Q: Is CrewAI AOP available for cloud and on-premise deployments?
A: Yes, CrewAI AMP supports both cloud-based and on-premise deployment options, allowing enterprises to meet their specific security and compliance requirements.
A: Yes, CrewAI AOP supports both cloud-based and on-premise deployment options, allowing enterprises to meet their specific security and compliance requirements.
### Q: Can I try CrewAI AMP for free?
### Q: Can I try CrewAI AOP for free?
A: Yes, you can explore part of the CrewAI AMP Suite by accessing the [Crew Control Plane](https://app.crewai.com) for free.
A: Yes, you can explore part of the CrewAI AOP Suite by accessing the [Crew Control Plane](https://app.crewai.com) for free.
### Q: Does CrewAI support fine-tuning or training custom models?
@@ -762,7 +762,7 @@ A: CrewAI is highly scalable, supporting simple automations and large-scale ente
### Q: Does CrewAI offer debugging and monitoring tools?
A: Yes, CrewAI AMP includes advanced debugging, tracing, and real-time observability features, simplifying the management and troubleshooting of your automations.
A: Yes, CrewAI AOP includes advanced debugging, tracing, and real-time observability features, simplifying the management and troubleshooting of your automations.
### Q: What programming languages does CrewAI support?

197
conftest.py Normal file
View File

@@ -0,0 +1,197 @@
"""Pytest configuration for crewAI workspace."""
from collections.abc import Generator
import os
from pathlib import Path
import tempfile
from typing import Any
from dotenv import load_dotenv
import pytest
from vcr.request import Request # type: ignore[import-untyped]
env_test_path = Path(__file__).parent / ".env.test"
load_dotenv(env_test_path, override=True)
load_dotenv(override=True)
@pytest.fixture(autouse=True, scope="function")
def cleanup_event_handlers() -> Generator[None, Any, None]:
"""Clean up event bus handlers after each test to prevent test pollution."""
yield
try:
from crewai.events.event_bus import crewai_event_bus
with crewai_event_bus._rwlock.w_locked():
crewai_event_bus._sync_handlers.clear()
crewai_event_bus._async_handlers.clear()
except Exception: # noqa: S110
pass
@pytest.fixture(autouse=True, scope="function")
def setup_test_environment() -> Generator[None, Any, None]:
"""Setup test environment for crewAI workspace."""
with tempfile.TemporaryDirectory() as temp_dir:
storage_dir = Path(temp_dir) / "crewai_test_storage"
storage_dir.mkdir(parents=True, exist_ok=True)
if not storage_dir.exists() or not storage_dir.is_dir():
raise RuntimeError(
f"Failed to create test storage directory: {storage_dir}"
)
try:
test_file = storage_dir / ".permissions_test"
test_file.touch()
test_file.unlink()
except (OSError, IOError) as e:
raise RuntimeError(
f"Test storage directory {storage_dir} is not writable: {e}"
) from e
os.environ["CREWAI_STORAGE_DIR"] = str(storage_dir)
os.environ["CREWAI_TESTING"] = "true"
try:
yield
finally:
os.environ.pop("CREWAI_TESTING", "true")
os.environ.pop("CREWAI_STORAGE_DIR", None)
os.environ.pop("CREWAI_DISABLE_TELEMETRY", "true")
os.environ.pop("OTEL_SDK_DISABLED", "true")
os.environ.pop("OPENAI_BASE_URL", "https://api.openai.com/v1")
os.environ.pop("OPENAI_API_BASE", "https://api.openai.com/v1")
HEADERS_TO_FILTER = {
"authorization": "AUTHORIZATION-XXX",
"content-security-policy": "CSP-FILTERED",
"cookie": "COOKIE-XXX",
"set-cookie": "SET-COOKIE-XXX",
"permissions-policy": "PERMISSIONS-POLICY-XXX",
"referrer-policy": "REFERRER-POLICY-XXX",
"strict-transport-security": "STS-XXX",
"x-content-type-options": "X-CONTENT-TYPE-XXX",
"x-frame-options": "X-FRAME-OPTIONS-XXX",
"x-permitted-cross-domain-policies": "X-PERMITTED-XXX",
"x-request-id": "X-REQUEST-ID-XXX",
"x-runtime": "X-RUNTIME-XXX",
"x-xss-protection": "X-XSS-PROTECTION-XXX",
"x-stainless-arch": "X-STAINLESS-ARCH-XXX",
"x-stainless-os": "X-STAINLESS-OS-XXX",
"x-stainless-read-timeout": "X-STAINLESS-READ-TIMEOUT-XXX",
"cf-ray": "CF-RAY-XXX",
"etag": "ETAG-XXX",
"Strict-Transport-Security": "STS-XXX",
"access-control-expose-headers": "ACCESS-CONTROL-XXX",
"openai-organization": "OPENAI-ORG-XXX",
"openai-project": "OPENAI-PROJECT-XXX",
"x-ratelimit-limit-requests": "X-RATELIMIT-LIMIT-REQUESTS-XXX",
"x-ratelimit-limit-tokens": "X-RATELIMIT-LIMIT-TOKENS-XXX",
"x-ratelimit-remaining-requests": "X-RATELIMIT-REMAINING-REQUESTS-XXX",
"x-ratelimit-remaining-tokens": "X-RATELIMIT-REMAINING-TOKENS-XXX",
"x-ratelimit-reset-requests": "X-RATELIMIT-RESET-REQUESTS-XXX",
"x-ratelimit-reset-tokens": "X-RATELIMIT-RESET-TOKENS-XXX",
"x-goog-api-key": "X-GOOG-API-KEY-XXX",
"api-key": "X-API-KEY-XXX",
"User-Agent": "X-USER-AGENT-XXX",
"apim-request-id:": "X-API-CLIENT-REQUEST-ID-XXX",
"azureml-model-session": "AZUREML-MODEL-SESSION-XXX",
"x-ms-client-request-id": "X-MS-CLIENT-REQUEST-ID-XXX",
"x-ms-region": "X-MS-REGION-XXX",
"apim-request-id": "APIM-REQUEST-ID-XXX",
"x-api-key": "X-API-KEY-XXX",
"anthropic-organization-id": "ANTHROPIC-ORGANIZATION-ID-XXX",
"request-id": "REQUEST-ID-XXX",
"anthropic-ratelimit-input-tokens-limit": "ANTHROPIC-RATELIMIT-INPUT-TOKENS-LIMIT-XXX",
"anthropic-ratelimit-input-tokens-remaining": "ANTHROPIC-RATELIMIT-INPUT-TOKENS-REMAINING-XXX",
"anthropic-ratelimit-input-tokens-reset": "ANTHROPIC-RATELIMIT-INPUT-TOKENS-RESET-XXX",
"anthropic-ratelimit-output-tokens-limit": "ANTHROPIC-RATELIMIT-OUTPUT-TOKENS-LIMIT-XXX",
"anthropic-ratelimit-output-tokens-remaining": "ANTHROPIC-RATELIMIT-OUTPUT-TOKENS-REMAINING-XXX",
"anthropic-ratelimit-output-tokens-reset": "ANTHROPIC-RATELIMIT-OUTPUT-TOKENS-RESET-XXX",
"anthropic-ratelimit-tokens-limit": "ANTHROPIC-RATELIMIT-TOKENS-LIMIT-XXX",
"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",
"amz-sdk-invocation-id": "AMZ-SDK-INVOCATION-ID-XXX",
"accept-encoding": "ACCEPT-ENCODING-XXX",
"x-amzn-requestid": "X-AMZN-REQUESTID-XXX",
"x-amzn-RequestId": "X-AMZN-REQUESTID-XXX",
}
def _filter_request_headers(request: Request) -> Request: # type: ignore[no-any-unimported]
"""Filter sensitive headers from request before recording."""
for header_name, replacement in HEADERS_TO_FILTER.items():
for variant in [header_name, header_name.upper(), header_name.title()]:
if variant in request.headers:
request.headers[variant] = [replacement]
request.method = request.method.upper()
return request
def _filter_response_headers(response: dict[str, Any]) -> dict[str, Any]:
"""Filter sensitive headers from response before recording."""
# Remove Content-Encoding to prevent decompression issues on replay
for encoding_header in ["Content-Encoding", "content-encoding"]:
response["headers"].pop(encoding_header, None)
for header_name, replacement in HEADERS_TO_FILTER.items():
for variant in [header_name, header_name.upper(), header_name.title()]:
if variant in response["headers"]:
response["headers"][variant] = [replacement]
return response
@pytest.fixture(scope="module")
def vcr_cassette_dir(request: Any) -> str:
"""Generate cassette directory path based on test module location.
Organizes cassettes to mirror test directory structure within each package:
lib/crewai/tests/llms/google/test_google.py -> lib/crewai/tests/cassettes/llms/google/
lib/crewai-tools/tests/tools/test_search.py -> lib/crewai-tools/tests/cassettes/tools/
"""
test_file = Path(request.fspath)
for parent in test_file.parents:
if parent.name in ("crewai", "crewai-tools") and parent.parent.name == "lib":
package_root = parent
break
else:
package_root = test_file.parent
tests_root = package_root / "tests"
test_dir = test_file.parent
if test_dir != tests_root:
relative_path = test_dir.relative_to(tests_root)
cassette_dir = tests_root / "cassettes" / relative_path
else:
cassette_dir = tests_root / "cassettes"
cassette_dir.mkdir(parents=True, exist_ok=True)
return str(cassette_dir)
@pytest.fixture(scope="module")
def vcr_config(vcr_cassette_dir: str) -> dict[str, Any]:
"""Configure VCR with organized cassette storage."""
config = {
"cassette_library_dir": vcr_cassette_dir,
"record_mode": os.getenv("PYTEST_VCR_RECORD_MODE", "once"),
"filter_headers": [(k, v) for k, v in HEADERS_TO_FILTER.items()],
"before_record_request": _filter_request_headers,
"before_record_response": _filter_response_headers,
"filter_query_parameters": ["key"],
"match_on": ["method", "scheme", "host", "port", "path"],
}
if os.getenv("GITHUB_ACTIONS") == "true":
config["record_mode"] = "none"
return config

View File

@@ -253,7 +253,8 @@
"pages": [
"en/tools/integration/overview",
"en/tools/integration/bedrockinvokeagenttool",
"en/tools/integration/crewaiautomationtool"
"en/tools/integration/crewaiautomationtool",
"en/tools/integration/mergeagenthandlertool"
]
},
{
@@ -313,7 +314,10 @@
"en/learn/multimodal-agents",
"en/learn/replay-tasks-from-latest-crew-kickoff",
"en/learn/sequential-process",
"en/learn/using-annotations"
"en/learn/using-annotations",
"en/learn/execution-hooks",
"en/learn/llm-hooks",
"en/learn/tool-hooks"
]
},
{
@@ -323,7 +327,7 @@
]
},
{
"tab": "AMP",
"tab": "AOP",
"icon": "briefcase",
"groups": [
{
@@ -737,7 +741,10 @@
"pt-BR/learn/multimodal-agents",
"pt-BR/learn/replay-tasks-from-latest-crew-kickoff",
"pt-BR/learn/sequential-process",
"pt-BR/learn/using-annotations"
"pt-BR/learn/using-annotations",
"pt-BR/learn/execution-hooks",
"pt-BR/learn/llm-hooks",
"pt-BR/learn/tool-hooks"
]
},
{
@@ -747,7 +754,7 @@
]
},
{
"tab": "AMP",
"tab": "AOP",
"icon": "briefcase",
"groups": [
{
@@ -1170,7 +1177,10 @@
"ko/learn/multimodal-agents",
"ko/learn/replay-tasks-from-latest-crew-kickoff",
"ko/learn/sequential-process",
"ko/learn/using-annotations"
"ko/learn/using-annotations",
"ko/learn/execution-hooks",
"ko/learn/llm-hooks",
"ko/learn/tool-hooks"
]
},
{

View File

@@ -1,19 +1,19 @@
---
title: "Introduction"
description: "Complete reference for the CrewAI AMP REST API"
description: "Complete reference for the CrewAI AOP REST API"
icon: "code"
mode: "wide"
---
# CrewAI AMP API
# CrewAI AOP API
Welcome to the CrewAI AMP API reference. This API allows you to programmatically interact with your deployed crews, enabling integration with your applications, workflows, and services.
Welcome to the CrewAI AOP API reference. This API allows you to programmatically interact with your deployed crews, enabling integration with your applications, workflows, and services.
## Quick Start
<Steps>
<Step title="Get Your API Credentials">
Navigate to your crew's detail page in the CrewAI AMP dashboard and copy your Bearer Token from the Status tab.
Navigate to your crew's detail page in the CrewAI AOP dashboard and copy your Bearer Token from the Status tab.
</Step>
<Step title="Discover Required Inputs">
@@ -46,7 +46,7 @@ curl -H "Authorization: Bearer YOUR_CREW_TOKEN" \
| **User Bearer Token** | User-scoped access | Limited permissions, suitable for user-specific operations |
<Tip>
You can find both token types in the Status tab of your crew's detail page in the CrewAI AMP dashboard.
You can find both token types in the Status tab of your crew's detail page in the CrewAI AOP dashboard.
</Tip>
## Base URL
@@ -82,7 +82,7 @@ The API uses standard HTTP status codes:
## Interactive Testing
<Info>
**Why no "Send" button?** Since each CrewAI AMP user has their own unique crew URL, we use **reference mode** instead of an interactive playground to avoid confusion. This shows you exactly what the requests should look like without non-functional send buttons.
**Why no "Send" button?** Since each CrewAI AOP user has their own unique crew URL, we use **reference mode** instead of an interactive playground to avoid confusion. This shows you exactly what the requests should look like without non-functional send buttons.
</Info>
Each endpoint page shows you:

View File

@@ -20,7 +20,7 @@ Think of an agent as a specialized team member with specific skills, expertise,
</Tip>
<Note type="info" title="Enterprise Enhancement: Visual Agent Builder">
CrewAI AMP includes a Visual Agent Builder that simplifies agent creation and configuration without writing code. Design your agents visually and test them in real-time.
CrewAI AOP includes a Visual Agent Builder that simplifies agent creation and configuration without writing code. Design your agents visually and test them in real-time.
![Visual Agent Builder Screenshot](/images/enterprise/crew-studio-interface.png)

View File

@@ -5,7 +5,7 @@ icon: terminal
mode: "wide"
---
<Warning>Since release 0.140.0, CrewAI AMP started a process of migrating their login provider. As such, the authentication flow via CLI was updated. Users that use Google to login, or that created their account after July 3rd, 2025 will be unable to log in with older versions of the `crewai` library.</Warning>
<Warning>Since release 0.140.0, CrewAI AOP started a process of migrating their login provider. As such, the authentication flow via CLI was updated. Users that use Google to login, or that created their account after July 3rd, 2025 will be unable to log in with older versions of the `crewai` library.</Warning>
## Overview
@@ -186,9 +186,9 @@ def crew(self) -> Crew:
### 10. Deploy
Deploy the crew or flow to [CrewAI AMP](https://app.crewai.com).
Deploy the crew or flow to [CrewAI AOP](https://app.crewai.com).
- **Authentication**: You need to be authenticated to deploy to CrewAI AMP.
- **Authentication**: You need to be authenticated to deploy to CrewAI AOP.
You can login or create an account with:
```shell Terminal
crewai login
@@ -203,7 +203,7 @@ Deploy the crew or flow to [CrewAI AMP](https://app.crewai.com).
### 11. Organization Management
Manage your CrewAI AMP organizations.
Manage your CrewAI AOP organizations.
```shell Terminal
crewai org [COMMAND] [OPTIONS]
@@ -227,17 +227,17 @@ crewai org switch <organization_id>
```
<Note>
You must be authenticated to CrewAI AMP to use these organization management commands.
You must be authenticated to CrewAI AOP to use these organization management commands.
</Note>
- **Create a deployment** (continued):
- Links the deployment to the corresponding remote GitHub repository (it usually detects this automatically).
- **Deploy the Crew**: Once you are authenticated, you can deploy your crew or flow to CrewAI AMP.
- **Deploy the Crew**: Once you are authenticated, you can deploy your crew or flow to CrewAI AOP.
```shell Terminal
crewai deploy push
```
- Initiates the deployment process on the CrewAI AMP platform.
- Initiates the deployment process on the CrewAI AOP platform.
- Upon successful initiation, it will output the Deployment created successfully! message along with the Deployment Name and a unique Deployment ID (UUID).
- **Deployment Status**: You can check the status of your deployment with:
@@ -262,7 +262,7 @@ You must be authenticated to CrewAI AMP to use these organization management com
```shell Terminal
crewai deploy remove
```
This deletes the deployment from the CrewAI AMP platform.
This deletes the deployment from the CrewAI AOP platform.
- **Help Command**: You can get help with the CLI with:
```shell Terminal
@@ -270,7 +270,7 @@ You must be authenticated to CrewAI AMP to use these organization management com
```
This shows the help message for the CrewAI Deploy CLI.
Watch this video tutorial for a step-by-step demonstration of deploying your crew to [CrewAI AMP](http://app.crewai.com) using the CLI.
Watch this video tutorial for a step-by-step demonstration of deploying your crew to [CrewAI AOP](http://app.crewai.com) using the CLI.
<iframe
className="w-full aspect-video rounded-xl"
@@ -283,7 +283,7 @@ Watch this video tutorial for a step-by-step demonstration of deploying your cre
### 11. Login
Authenticate with CrewAI AMP using a secure device code flow (no email entry required).
Authenticate with CrewAI AOP using a secure device code flow (no email entry required).
```shell Terminal
crewai login
@@ -354,7 +354,7 @@ crewai config reset
#### Available Configuration Parameters
- `enterprise_base_url`: Base URL of the CrewAI AMP instance
- `enterprise_base_url`: Base URL of the CrewAI AOP instance
- `oauth2_provider`: OAuth2 provider used for authentication (e.g., workos, okta, auth0)
- `oauth2_audience`: OAuth2 audience value, typically used to identify the target API or resource
- `oauth2_client_id`: OAuth2 client ID issued by the provider, used during authentication requests
@@ -370,7 +370,7 @@ crewai config list
Example output:
| Setting | Value | Description |
| :------------------ | :----------------------- | :---------------------------------------------------------- |
| enterprise_base_url | https://app.crewai.com | Base URL of the CrewAI AMP instance |
| enterprise_base_url | https://app.crewai.com | Base URL of the CrewAI AOP instance |
| org_name | Not set | Name of the currently active organization |
| org_uuid | Not set | UUID of the currently active organization |
| oauth2_provider | workos | OAuth2 provider (e.g., workos, okta, auth0) |
@@ -402,6 +402,77 @@ crewai config reset
After resetting configuration, re-run `crewai login` to authenticate again.
</Tip>
### 14. Trace Management
Manage trace collection preferences for your Crew and Flow executions.
```shell Terminal
crewai traces [COMMAND]
```
#### Commands:
- `enable`: Enable trace collection for crew/flow executions
```shell Terminal
crewai traces enable
```
- `disable`: Disable trace collection for crew/flow executions
```shell Terminal
crewai traces disable
```
- `status`: Show current trace collection status
```shell Terminal
crewai traces status
```
#### How Tracing Works
Trace collection is controlled by checking three settings in priority order:
1. **Explicit flag in code** (highest priority - can enable OR disable):
```python
crew = Crew(agents=[...], tasks=[...], tracing=True) # Always enable
crew = Crew(agents=[...], tasks=[...], tracing=False) # Always disable
crew = Crew(agents=[...], tasks=[...]) # Check lower priorities (default)
```
- `tracing=True` will **always enable** tracing (overrides everything)
- `tracing=False` will **always disable** tracing (overrides everything)
- `tracing=None` or omitted will check lower priority settings
2. **Environment variable** (second priority):
```env
CREWAI_TRACING_ENABLED=true
```
- Checked only if `tracing` is not explicitly set to `True` or `False` in code
- Set to `true` or `1` to enable tracing
3. **User preference** (lowest priority):
```shell Terminal
crewai traces enable
```
- Checked only if `tracing` is not set in code and `CREWAI_TRACING_ENABLED` is not set to `true`
- Running `crewai traces enable` is sufficient to enable tracing by itself
<Note>
**To enable tracing**, use any one of these methods:
- Set `tracing=True` in your Crew/Flow code, OR
- Add `CREWAI_TRACING_ENABLED=true` to your `.env` file, OR
- Run `crewai traces enable`
**To disable tracing**, use any ONE of these methods:
- Set `tracing=False` in your Crew/Flow code (overrides everything), OR
- Remove or set to `false` the `CREWAI_TRACING_ENABLED` env var, OR
- Run `crewai traces disable`
Higher priority settings override lower ones.
</Note>
<Tip>
For more information about tracing, see the [Tracing documentation](/observability/tracing).
</Tip>
<Tip>
CrewAI CLI handles authentication to the Tool Repository automatically when adding packages to your project. Just append `crewai` before any `uv` command to use it. E.g. `crewai uv add requests`. For more information, see [Tool Repository](https://docs.crewai.com/enterprise/features/tool-repository) docs.
</Tip>

View File

@@ -33,6 +33,7 @@ A crew in crewAI represents a collaborative group of agents working together to
| **Planning** *(optional)* | `planning` | Adds planning ability to the Crew. When activated before each Crew iteration, all Crew data is sent to an AgentPlanner that will plan the tasks and this plan will be added to each task description. |
| **Planning LLM** *(optional)* | `planning_llm` | The language model used by the AgentPlanner in a planning process. |
| **Knowledge Sources** _(optional)_ | `knowledge_sources` | Knowledge sources available at the crew level, accessible to all the agents. |
| **Stream** _(optional)_ | `stream` | Enable streaming output to receive real-time updates during crew execution. Returns a `CrewStreamingOutput` object that can be iterated for chunks. Defaults to `False`. |
<Tip>
**Crew Max RPM**: The `max_rpm` attribute sets the maximum number of requests per minute the crew can perform to avoid rate limits and will override individual agents' `max_rpm` settings if you set it.
@@ -306,12 +307,27 @@ print(result)
### Different Ways to Kick Off a Crew
Once your crew is assembled, initiate the workflow with the appropriate kickoff method. CrewAI provides several methods for better control over the kickoff process: `kickoff()`, `kickoff_for_each()`, `kickoff_async()`, and `kickoff_for_each_async()`.
Once your crew is assembled, initiate the workflow with the appropriate kickoff method. CrewAI provides several methods for better control over the kickoff process.
#### Synchronous Methods
- `kickoff()`: Starts the execution process according to the defined process flow.
- `kickoff_for_each()`: Executes tasks sequentially for each provided input event or item in the collection.
- `kickoff_async()`: Initiates the workflow asynchronously.
- `kickoff_for_each_async()`: Executes tasks concurrently for each provided input event or item, leveraging asynchronous processing.
#### Asynchronous Methods
CrewAI offers two approaches for async execution:
| Method | Type | Description |
|--------|------|-------------|
| `akickoff()` | Native async | True async/await throughout the entire execution chain |
| `akickoff_for_each()` | Native async | Native async execution for each input in a list |
| `kickoff_async()` | Thread-based | Wraps synchronous execution in `asyncio.to_thread` |
| `kickoff_for_each_async()` | Thread-based | Thread-based async for each input in a list |
<Note>
For high-concurrency workloads, `akickoff()` and `akickoff_for_each()` are recommended as they use native async for task execution, memory operations, and knowledge retrieval.
</Note>
```python Code
# Start the crew's task execution
@@ -324,19 +340,53 @@ results = my_crew.kickoff_for_each(inputs=inputs_array)
for result in results:
print(result)
# Example of using kickoff_async
# Example of using native async with akickoff
inputs = {'topic': 'AI in healthcare'}
async_result = await my_crew.akickoff(inputs=inputs)
print(async_result)
# Example of using native async with akickoff_for_each
inputs_array = [{'topic': 'AI in healthcare'}, {'topic': 'AI in finance'}]
async_results = await my_crew.akickoff_for_each(inputs=inputs_array)
for async_result in async_results:
print(async_result)
# Example of using thread-based kickoff_async
inputs = {'topic': 'AI in healthcare'}
async_result = await my_crew.kickoff_async(inputs=inputs)
print(async_result)
# Example of using kickoff_for_each_async
# Example of using thread-based kickoff_for_each_async
inputs_array = [{'topic': 'AI in healthcare'}, {'topic': 'AI in finance'}]
async_results = await my_crew.kickoff_for_each_async(inputs=inputs_array)
for async_result in async_results:
print(async_result)
```
These methods provide flexibility in how you manage and execute tasks within your crew, allowing for both synchronous and asynchronous workflows tailored to your needs.
These methods provide flexibility in how you manage and execute tasks within your crew, allowing for both synchronous and asynchronous workflows tailored to your needs. For detailed async examples, see the [Kickoff Crew Asynchronously](/en/learn/kickoff-async) guide.
### Streaming Crew Execution
For real-time visibility into crew execution, you can enable streaming to receive output as it's generated:
```python Code
# Enable streaming
crew = Crew(
agents=[researcher],
tasks=[task],
stream=True
)
# Iterate over streaming output
streaming = crew.kickoff(inputs={"topic": "AI"})
for chunk in streaming:
print(chunk.content, end="", flush=True)
# Access final result
result = streaming.result
```
Learn more about streaming in the [Streaming Crew Execution](/en/learn/streaming-crew-execution) guide.
### Replaying from a Specific Task

View File

@@ -20,7 +20,7 @@ CrewAI uses an event bus architecture to emit events throughout the execution li
When specific actions occur in CrewAI (like a Crew starting execution, an Agent completing a task, or a tool being used), the system emits corresponding events. You can register handlers for these events to execute custom code when they occur.
<Note type="info" title="Enterprise Enhancement: Prompt Tracing">
CrewAI AMP provides a built-in Prompt Tracing feature that leverages the event system to track, store, and visualize all prompts, completions, and associated metadata. This provides powerful debugging capabilities and transparency into your agent operations.
CrewAI AOP provides a built-in Prompt Tracing feature that leverages the event system to track, store, and visualize all prompts, completions, and associated metadata. This provides powerful debugging capabilities and transparency into your agent operations.
![Prompt Tracing Dashboard](/images/enterprise/traces-overview.png)

View File

@@ -897,6 +897,31 @@ flow = ExampleFlow()
result = flow.kickoff()
```
### Streaming Flow Execution
For real-time visibility into flow execution, you can enable streaming to receive output as it's generated:
```python
class StreamingFlow(Flow):
stream = True # Enable streaming
@start()
def research(self):
# Your flow implementation
pass
# Iterate over streaming output
flow = StreamingFlow()
streaming = flow.kickoff()
for chunk in streaming:
print(chunk.content, end="", flush=True)
# Access final result
result = streaming.result
```
Learn more about streaming in the [Streaming Flow Execution](/en/learn/streaming-flow-execution) guide.
### Using the CLI
Starting from version 0.103.0, you can run flows using the `crewai run` command:

View File

@@ -388,8 +388,8 @@ crew = Crew(
agents=[sales_agent, tech_agent, support_agent],
tasks=[...],
embedder={ # Fallback embedder for agents without their own
"provider": "google",
"config": {"model": "text-embedding-004"}
"provider": "google-generativeai",
"config": {"model_name": "gemini-embedding-001"}
}
)
@@ -629,9 +629,9 @@ agent = Agent(
backstory="Expert researcher",
knowledge_sources=[knowledge_source],
embedder={
"provider": "google",
"provider": "google-generativeai",
"config": {
"model": "models/text-embedding-004",
"model_name": "gemini-embedding-001",
"api_key": "your-google-key"
}
}
@@ -739,7 +739,7 @@ class KnowledgeMonitorListener(BaseEventListener):
knowledge_monitor = KnowledgeMonitorListener()
```
For more information on using events, see the [Event Listeners](https://docs.crewai.com/concepts/event-listener) documentation.
For more information on using events, see the [Event Listeners](/en/concepts/event-listener) documentation.
### Custom Knowledge Sources

View File

@@ -283,11 +283,54 @@ In this section, you'll find detailed examples that help you select, configure,
)
```
**Extended Thinking (Claude Sonnet 4 and Beyond):**
CrewAI supports Anthropic's Extended Thinking feature, which allows Claude to think through problems in a more human-like way before responding. This is particularly useful for complex reasoning, analysis, and problem-solving tasks.
```python Code
from crewai import LLM
# Enable extended thinking with default settings
llm = LLM(
model="anthropic/claude-sonnet-4",
thinking={"type": "enabled"},
max_tokens=10000
)
# Configure thinking with budget control
llm = LLM(
model="anthropic/claude-sonnet-4",
thinking={
"type": "enabled",
"budget_tokens": 5000 # Limit thinking tokens
},
max_tokens=10000
)
```
**Thinking Configuration Options:**
- `type`: Set to `"enabled"` to activate extended thinking mode
- `budget_tokens` (optional): Maximum tokens to use for thinking (helps control costs)
**Models Supporting Extended Thinking:**
- `claude-sonnet-4` and newer models
- `claude-3-7-sonnet` (with extended thinking capabilities)
**When to Use Extended Thinking:**
- Complex reasoning and multi-step problem solving
- Mathematical calculations and proofs
- Code analysis and debugging
- Strategic planning and decision making
- Research and analytical tasks
**Note:** Extended thinking consumes additional tokens but can significantly improve response quality for complex tasks.
**Supported Environment Variables:**
- `ANTHROPIC_API_KEY`: Your Anthropic API key (required)
**Features:**
- Native tool use support for Claude 3+ models
- Extended Thinking support for Claude Sonnet 4+
- Streaming support for real-time responses
- Automatic system message handling
- Stop sequences for controlled output
@@ -305,6 +348,7 @@ In this section, you'll find detailed examples that help you select, configure,
| Model | Context Window | Best For |
|------------------------------|----------------|-----------------------------------------------|
| claude-sonnet-4 | 200,000 tokens | Latest with extended thinking capabilities |
| claude-3-7-sonnet | 200,000 tokens | Advanced reasoning and agentic tasks |
| claude-3-5-sonnet-20241022 | 200,000 tokens | Latest Sonnet with best performance |
| claude-3-5-haiku | 200,000 tokens | Fast, compact model for quick responses |
@@ -1035,7 +1079,7 @@ CrewAI supports streaming responses from LLMs, allowing your application to rece
```
<Tip>
[Click here](https://docs.crewai.com/concepts/event-listener#event-listeners) for more details
[Click here](/en/concepts/event-listener#event-listeners) for more details
</Tip>
</Tab>
@@ -1089,6 +1133,50 @@ CrewAI supports streaming responses from LLMs, allowing your application to rece
</Tab>
</Tabs>
## Async LLM Calls
CrewAI supports asynchronous LLM calls for improved performance and concurrency in your AI workflows. Async calls allow you to run multiple LLM requests concurrently without blocking, making them ideal for high-throughput applications and parallel agent operations.
<Tabs>
<Tab title="Basic Usage">
Use the `acall` method for asynchronous LLM requests:
```python
import asyncio
from crewai import LLM
async def main():
llm = LLM(model="openai/gpt-4o")
# Single async call
response = await llm.acall("What is the capital of France?")
print(response)
asyncio.run(main())
```
The `acall` method supports all the same parameters as the synchronous `call` method, including messages, tools, and callbacks.
</Tab>
<Tab title="With Streaming">
Combine async calls with streaming for real-time concurrent responses:
```python
import asyncio
from crewai import LLM
async def stream_async():
llm = LLM(model="openai/gpt-4o", stream=True)
response = await llm.acall("Write a short story about AI")
print(response)
asyncio.run(stream_async())
```
</Tab>
</Tabs>
## Structured LLM Calls
CrewAI supports structured responses from LLM calls by allowing you to define a `response_format` using a Pydantic model. This enables the framework to automatically parse and validate the output, making it easier to integrate the response into your application without manual post-processing.
@@ -1200,6 +1288,52 @@ Learn how to get the most out of your LLM configuration:
)
```
</Accordion>
<Accordion title="Transport Interceptors">
CrewAI provides message interceptors for several providers, allowing you to hook into request/response cycles at the transport layer.
**Supported Providers:**
- ✅ OpenAI
- ✅ Anthropic
**Basic Usage:**
```python
import httpx
from crewai import LLM
from crewai.llms.hooks import BaseInterceptor
class CustomInterceptor(BaseInterceptor[httpx.Request, httpx.Response]):
"""Custom interceptor to modify requests and responses."""
def on_outbound(self, request: httpx.Request) -> httpx.Request:
"""Print request before sending to the LLM provider."""
print(request)
return request
def on_inbound(self, response: httpx.Response) -> httpx.Response:
"""Process response after receiving from the LLM provider."""
print(f"Status: {response.status_code}")
print(f"Response time: {response.elapsed}")
return response
# Use the interceptor with an LLM
llm = LLM(
model="openai/gpt-4o",
interceptor=CustomInterceptor()
)
```
**Important Notes:**
- Both methods must return the received object or type of object.
- Modifying received objects may result in unexpected behavior or application crashes.
- Not all providers support interceptors - check the supported providers list above
<Info>
Interceptors operate at the transport layer. This is particularly useful for:
- Message transformation and filtering
- Debugging API interactions
</Info>
</Accordion>
</AccordionGroup>
## Common Issues and Solutions

View File

@@ -341,7 +341,7 @@ crew = Crew(
embedder={
"provider": "openai",
"config": {
"model": "text-embedding-3-small" # or "text-embedding-3-large"
"model_name": "text-embedding-3-small" # or "text-embedding-3-large"
}
}
)
@@ -353,7 +353,7 @@ crew = Crew(
"provider": "openai",
"config": {
"api_key": "your-openai-api-key", # Optional: override env var
"model": "text-embedding-3-large",
"model_name": "text-embedding-3-large",
"dimensions": 1536, # Optional: reduce dimensions for smaller storage
"organization_id": "your-org-id" # Optional: for organization accounts
}
@@ -375,7 +375,7 @@ crew = Crew(
"api_base": "https://your-resource.openai.azure.com/",
"api_type": "azure",
"api_version": "2023-05-15",
"model": "text-embedding-3-small",
"model_name": "text-embedding-3-small",
"deployment_id": "your-deployment-name" # Azure deployment name
}
}
@@ -390,10 +390,10 @@ Use Google's text embedding models for integration with Google Cloud services.
crew = Crew(
memory=True,
embedder={
"provider": "google",
"provider": "google-generativeai",
"config": {
"api_key": "your-google-api-key",
"model": "text-embedding-004" # or "text-embedding-preview-0409"
"model_name": "gemini-embedding-001" # or "text-embedding-005", "text-multilingual-embedding-002"
}
}
)
@@ -461,7 +461,7 @@ crew = Crew(
"provider": "cohere",
"config": {
"api_key": "your-cohere-api-key",
"model": "embed-english-v3.0" # or "embed-multilingual-v3.0"
"model_name": "embed-english-v3.0" # or "embed-multilingual-v3.0"
}
}
)
@@ -478,7 +478,7 @@ crew = Crew(
"provider": "voyageai",
"config": {
"api_key": "your-voyage-api-key",
"model": "voyage-large-2", # or "voyage-code-2" for code
"model": "voyage-3", # or "voyage-3-lite", "voyage-code-3"
"input_type": "document" # or "query"
}
}
@@ -515,8 +515,7 @@ crew = Crew(
"provider": "huggingface",
"config": {
"api_key": "your-hf-token", # Optional for public models
"model": "sentence-transformers/all-MiniLM-L6-v2",
"api_url": "https://api-inference.huggingface.co" # or your custom endpoint
"model": "sentence-transformers/all-MiniLM-L6-v2"
}
}
)
@@ -912,10 +911,10 @@ crew = Crew(
crew = Crew(
memory=True,
embedder={
"provider": "google",
"provider": "google-generativeai",
"config": {
"api_key": "your-api-key",
"model": "text-embedding-004"
"model_name": "gemini-embedding-001"
}
}
)

View File

@@ -14,7 +14,7 @@ Tasks provide all necessary details for execution, such as a description, the ag
Tasks within CrewAI can be collaborative, requiring multiple agents to work together. This is managed through the task properties and orchestrated by the Crew's process, enhancing teamwork and efficiency.
<Note type="info" title="Enterprise Enhancement: Visual Task Builder">
CrewAI AMP includes a Visual Task Builder in Crew Studio that simplifies complex task creation and chaining. Design your task flows visually and test them in real-time without writing code.
CrewAI AOP includes a Visual Task Builder in Crew Studio that simplifies complex task creation and chaining. Design your task flows visually and test them in real-time without writing code.
![Task Builder Screenshot](/images/enterprise/crew-studio-interface.png)
@@ -60,6 +60,7 @@ crew = Crew(
| **Output Pydantic** _(optional)_ | `output_pydantic` | `Optional[Type[BaseModel]]` | A Pydantic model for task output. |
| **Callback** _(optional)_ | `callback` | `Optional[Any]` | Function/object to be executed after task completion. |
| **Guardrail** _(optional)_ | `guardrail` | `Optional[Callable]` | Function to validate task output before proceeding to next task. |
| **Guardrails** _(optional)_ | `guardrails` | `Optional[List[Callable] | List[str]]` | List of guardrails to validate task output before proceeding to next task. |
| **Guardrail Max Retries** _(optional)_ | `guardrail_max_retries` | `Optional[int]` | Maximum number of retries when guardrail validation fails. Defaults to 3. |
<Note type="warning" title="Deprecated: max_retries">
@@ -223,6 +224,7 @@ By default, the `TaskOutput` will only include the `raw` output. A `TaskOutput`
| **JSON Dict** | `json_dict` | `Optional[Dict[str, Any]]` | A dictionary representing the JSON output of the task. |
| **Agent** | `agent` | `str` | The agent that executed the task. |
| **Output Format** | `output_format` | `OutputFormat` | The format of the task output, with options including RAW, JSON, and Pydantic. The default is RAW. |
| **Messages** | `messages` | `list[LLMMessage]` | The messages from the last task execution. |
### Task Methods and Properties
@@ -341,7 +343,11 @@ Task guardrails provide a way to validate and transform task outputs before they
are passed to the next task. This feature helps ensure data quality and provides
feedback to agents when their output doesn't meet specific criteria.
Guardrails are implemented as Python functions that contain custom validation logic, giving you complete control over the validation process and ensuring reliable, deterministic results.
CrewAI supports two types of guardrails:
1. **Function-based guardrails**: Python functions with custom validation logic, giving you complete control over the validation process and ensuring reliable, deterministic results.
2. **LLM-based guardrails**: String descriptions that use the agent's LLM to validate outputs based on natural language criteria. These are ideal for complex or subjective validation requirements.
### Function-Based Guardrails
@@ -355,12 +361,12 @@ def validate_blog_content(result: TaskOutput) -> Tuple[bool, Any]:
"""Validate blog content meets requirements."""
try:
# Check word count
word_count = len(result.split())
word_count = len(result.raw.split())
if word_count > 200:
return (False, "Blog content exceeds 200 words")
# Additional validation logic here
return (True, result.strip())
return (True, result.raw.strip())
except Exception as e:
return (False, "Unexpected error during validation")
@@ -372,6 +378,147 @@ blog_task = Task(
)
```
### LLM-Based Guardrails (String Descriptions)
Instead of writing custom validation functions, you can use string descriptions that leverage LLM-based validation. When you provide a string to the `guardrail` or `guardrails` parameter, CrewAI automatically creates an `LLMGuardrail` that uses the agent's LLM to validate the output based on your description.
**Requirements**:
- The task must have an `agent` assigned (the guardrail uses the agent's LLM)
- Provide a clear, descriptive string explaining the validation criteria
```python Code
from crewai import Task
# Single LLM-based guardrail
blog_task = Task(
description="Write a blog post about AI",
expected_output="A blog post under 200 words",
agent=blog_agent,
guardrail="The blog post must be under 200 words and contain no technical jargon"
)
```
LLM-based guardrails are particularly useful for:
- **Complex validation logic** that's difficult to express programmatically
- **Subjective criteria** like tone, style, or quality assessments
- **Natural language requirements** that are easier to describe than code
The LLM guardrail will:
1. Analyze the task output against your description
2. Return `(True, output)` if the output complies with the criteria
3. Return `(False, feedback)` with specific feedback if validation fails
**Example with detailed validation criteria**:
```python Code
research_task = Task(
description="Research the latest developments in quantum computing",
expected_output="A comprehensive research report",
agent=researcher_agent,
guardrail="""
The research report must:
- Be at least 1000 words long
- Include at least 5 credible sources
- Cover both technical and practical applications
- Be written in a professional, academic tone
- Avoid speculation or unverified claims
"""
)
```
### Multiple Guardrails
You can apply multiple guardrails to a task using the `guardrails` parameter. Multiple guardrails are executed sequentially, with each guardrail receiving the output from the previous one. This allows you to chain validation and transformation steps.
The `guardrails` parameter accepts:
- A list of guardrail functions or string descriptions
- A single guardrail function or string (same as `guardrail`)
**Note**: If `guardrails` is provided, it takes precedence over `guardrail`. The `guardrail` parameter will be ignored when `guardrails` is set.
```python Code
from typing import Tuple, Any
from crewai import TaskOutput, Task
def validate_word_count(result: TaskOutput) -> Tuple[bool, Any]:
"""Validate word count is within limits."""
word_count = len(result.raw.split())
if word_count < 100:
return (False, f"Content too short: {word_count} words. Need at least 100 words.")
if word_count > 500:
return (False, f"Content too long: {word_count} words. Maximum is 500 words.")
return (True, result.raw)
def validate_no_profanity(result: TaskOutput) -> Tuple[bool, Any]:
"""Check for inappropriate language."""
profanity_words = ["badword1", "badword2"] # Example list
content_lower = result.raw.lower()
for word in profanity_words:
if word in content_lower:
return (False, f"Inappropriate language detected: {word}")
return (True, result.raw)
def format_output(result: TaskOutput) -> Tuple[bool, Any]:
"""Format and clean the output."""
formatted = result.raw.strip()
# Capitalize first letter
formatted = formatted[0].upper() + formatted[1:] if formatted else formatted
return (True, formatted)
# Apply multiple guardrails sequentially
blog_task = Task(
description="Write a blog post about AI",
expected_output="A well-formatted blog post between 100-500 words",
agent=blog_agent,
guardrails=[
validate_word_count, # First: validate length
validate_no_profanity, # Second: check content
format_output # Third: format the result
],
guardrail_max_retries=3
)
```
In this example, the guardrails execute in order:
1. `validate_word_count` checks the word count
2. `validate_no_profanity` checks for inappropriate language (using the output from step 1)
3. `format_output` formats the final result (using the output from step 2)
If any guardrail fails, the error is sent back to the agent, and the task is retried up to `guardrail_max_retries` times.
**Mixing function-based and LLM-based guardrails**:
You can combine both function-based and string-based guardrails in the same list:
```python Code
from typing import Tuple, Any
from crewai import TaskOutput, Task
def validate_word_count(result: TaskOutput) -> Tuple[bool, Any]:
"""Validate word count is within limits."""
word_count = len(result.raw.split())
if word_count < 100:
return (False, f"Content too short: {word_count} words. Need at least 100 words.")
if word_count > 500:
return (False, f"Content too long: {word_count} words. Maximum is 500 words.")
return (True, result.raw)
# Mix function-based and LLM-based guardrails
blog_task = Task(
description="Write a blog post about AI",
expected_output="A well-formatted blog post between 100-500 words",
agent=blog_agent,
guardrails=[
validate_word_count, # Function-based: precise word count check
"The content must be engaging and suitable for a general audience", # LLM-based: subjective quality check
"The writing style should be clear, concise, and free of technical jargon" # LLM-based: style validation
],
guardrail_max_retries=3
)
```
This approach combines the precision of programmatic validation with the flexibility of LLM-based assessment for subjective criteria.
### Guardrail Function Requirements
1. **Function Signature**:

View File

@@ -17,7 +17,7 @@ This includes tools from the [CrewAI Toolkit](https://github.com/joaomdmoura/cre
enabling everything from simple searches to complex interactions and effective teamwork among agents.
<Note type="info" title="Enterprise Enhancement: Tools Repository">
CrewAI AMP provides a comprehensive Tools Repository with pre-built integrations for common business systems and APIs. Deploy agents with enterprise tools in minutes instead of days.
CrewAI AOP provides a comprehensive Tools Repository with pre-built integrations for common business systems and APIs. Deploy agents with enterprise tools in minutes instead of days.
The Enterprise Tools Repository includes:
- Pre-built connectors for popular enterprise systems

View File

@@ -37,7 +37,7 @@ you can use them locally or refine them to your needs.
<Card title="Tools & Integrations" href="/en/enterprise/features/tools-and-integrations" icon="wrench">
Connect external apps and manage internal tools your agents can use.
</Card>
<Card title="Tool Repository" href="/en/enterprise/features/tool-repository" icon="toolbox">
<Card title="Tool Repository" href="/en/enterprise/guides/tool-repository#tool-repository" icon="toolbox">
Publish and install tools to enhance your crews' capabilities.
</Card>
<Card title="Agents Repository" href="/en/enterprise/features/agent-repositories" icon="people-group">

View File

@@ -7,10 +7,10 @@ mode: "wide"
## Overview
RBAC in CrewAI AMP enables secure, scalable access management through a combination of organizationlevel roles and automationlevel visibility controls.
RBAC in CrewAI AOP enables secure, scalable access management through a combination of organizationlevel roles and automationlevel visibility controls.
<Frame>
<img src="/images/enterprise/users_and_roles.png" alt="RBAC overview in CrewAI AMP" />
<img src="/images/enterprise/users_and_roles.png" alt="RBAC overview in CrewAI AOP" />
</Frame>
@@ -28,7 +28,7 @@ You can configure users and roles in Settings → Roles.
<Steps>
<Step title="Open Roles settings">
Go to <b>Settings → Roles</b> in CrewAI AMP.
Go to <b>Settings → Roles</b> in CrewAI AOP.
</Step>
<Step title="Choose a role type">
Use a predefined role (<b>Owner</b>, <b>Member</b>) or click <b>Create role</b> to define a custom one.
@@ -93,7 +93,7 @@ The organization owner always has access. In private mode, only whitelisted user
</Tip>
<Frame>
<img src="/images/enterprise/visibility.png" alt="Automation Visibility settings in CrewAI AMP" />
<img src="/images/enterprise/visibility.png" alt="Automation Visibility settings in CrewAI AOP" />
</Frame>

View File

@@ -189,10 +189,10 @@ Tools & Integrations is the central hub for connecting thirdparty apps and ma
## Internal Tools
Create custom tools locally, publish them on CrewAI AMP Tool Repository and use them in your agents.
Create custom tools locally, publish them on CrewAI AOP Tool Repository and use them in your agents.
<Tip>
Before running the commands below, make sure you log in to your CrewAI AMP account by running this command:
Before running the commands below, make sure you log in to your CrewAI AOP account by running this command:
```bash
crewai login
```
@@ -210,13 +210,13 @@ Tools & Integrations is the central hub for connecting thirdparty apps and ma
```
</Step>
<Step title="Publish">
Publish the tool to the CrewAI AMP Tool Repository.
Publish the tool to the CrewAI AOP Tool Repository.
```bash
crewai tool publish
```
</Step>
<Step title="Install">
Install the tool from the CrewAI AMP Tool Repository.
Install the tool from the CrewAI AOP Tool Repository.
```bash
crewai tool install your-tool
```
@@ -241,7 +241,7 @@ Tools & Integrations is the central hub for connecting thirdparty apps and ma
## Related
<CardGroup cols={2}>
<Card title="Tool Repository" href="/en/enterprise/features/tool-repository" icon="toolbox">
<Card title="Tool Repository" href="/en/enterprise/guides/tool-repository#tool-repository" icon="toolbox">
Create, publish, and version custom tools for your organization.
</Card>
<Card title="Webhook Automation" href="/en/enterprise/guides/webhook-automation" icon="bolt">

View File

@@ -11,7 +11,7 @@ Traces provide comprehensive visibility into your crew executions, helping you m
## What are Traces?
Traces in CrewAI AMP are detailed execution records that capture every aspect of your crew's operation, from initial inputs to final outputs. They record:
Traces in CrewAI AOP are detailed execution records that capture every aspect of your crew's operation, from initial inputs to final outputs. They record:
- Agent thoughts and reasoning
- Task execution details
@@ -28,7 +28,7 @@ Traces in CrewAI AMP are detailed execution records that capture every aspect of
<Steps>
<Step title="Navigate to the Traces Tab">
Once in your CrewAI AMP dashboard, click on the **Traces** to view all execution records.
Once in your CrewAI AOP dashboard, click on the **Traces** to view all execution records.
</Step>
<Step title="Select an Execution">
@@ -153,5 +153,5 @@ CrewAI batches trace uploads to reduce overhead on high-volume runs:
This yields more stable tracing under load while preserving detailed task/agent telemetry.
<Card title="Need Help?" icon="headset" href="mailto:support@crewai.com">
Contact our support team for assistance with trace analysis or any other CrewAI AMP features.
Contact our support team for assistance with trace analysis or any other CrewAI AOP features.
</Card>

View File

@@ -8,7 +8,7 @@ mode: "wide"
## Overview
Enterprise Event Streaming lets you receive real-time webhook updates about your crews and flows deployed to
CrewAI AMP, such as model calls, tool usage, and flow steps.
CrewAI AOP, such as model calls, tool usage, and flow steps.
## Usage

View File

@@ -1,11 +1,11 @@
---
title: "Triggers Overview"
description: "Understand how CrewAI AMP triggers work, how to manage them, and where to find integration-specific playbooks"
description: "Understand how CrewAI AOP triggers work, how to manage them, and where to find integration-specific playbooks"
icon: "face-smile"
mode: "wide"
---
CrewAI AMP triggers connect your automations to real-time events across the tools your teams already use. Instead of polling systems or relying on manual kickoffs, triggers listen for changes—new emails, calendar updates, CRM status changes—and immediately launch the crew or flow you specify.
CrewAI AOP triggers connect your automations to real-time events across the tools your teams already use. Instead of polling systems or relying on manual kickoffs, triggers listen for changes—new emails, calendar updates, CRM status changes—and immediately launch the crew or flow you specify.
<Frame>
![Automation Triggers Overview](/images/enterprise/crew_connectors.png)

View File

@@ -19,8 +19,8 @@ This guide walks you through connecting Azure OpenAI with Crew Studio for seamle
</Frame>
</Step>
<Step title="Configure CrewAI AMP Connection">
4. In another tab, open `CrewAI AMP > LLM Connections`. Name your LLM Connection, select Azure as the provider, and choose the same model you selected in Azure.
<Step title="Configure CrewAI AOP Connection">
4. In another tab, open `CrewAI AOP > LLM Connections`. Name your LLM Connection, select Azure as the provider, and choose the same model you selected in Azure.
5. On the same page, add environment variables from step 3:
- One named `AZURE_DEPLOYMENT_TARGET_URL` (using the Target URI). The URL should look like this: https://your-deployment.openai.azure.com/openai/deployments/gpt-4o/chat/completions?api-version=2024-08-01-preview
- Another named `AZURE_API_KEY` (using the Key).
@@ -28,7 +28,7 @@ This guide walks you through connecting Azure OpenAI with Crew Studio for seamle
</Step>
<Step title="Set Default Configuration">
7. In `CrewAI AMP > Settings > Defaults > Crew Studio LLM Settings`, set the new LLM Connection and model as defaults.
7. In `CrewAI AOP > Settings > Defaults > Crew Studio LLM Settings`, set the new LLM Connection and model as defaults.
</Step>
<Step title="Configure Network Access">

View File

@@ -7,7 +7,7 @@ mode: "wide"
## Overview
[CrewAI AMP](https://app.crewai.com) streamlines the process of **creating**, **deploying**, and **managing** your AI agents in production environments.
[CrewAI AOP](https://app.crewai.com) streamlines the process of **creating**, **deploying**, and **managing** your AI agents in production environments.
## Getting Started

View File

@@ -1,11 +1,11 @@
---
title: "Open Telemetry Logs"
description: "Understand how to capture telemetry logs from your CrewAI AMP deployments"
description: "Understand how to capture telemetry logs from your CrewAI AOP deployments"
icon: "magnifying-glass-chart"
mode: "wide"
---
CrewAI AMP provides a powerful way to capture telemetry logs from your deployments. This allows you to monitor the performance of your agents and workflows, and to debug issues that may arise.
CrewAI AOP provides a powerful way to capture telemetry logs from your deployments. This allows you to monitor the performance of your agents and workflows, and to debug issues that may arise.
## Prerequisites

View File

@@ -1,12 +1,12 @@
---
title: "Deploy Crew"
description: "Deploying a Crew on CrewAI AMP"
description: "Deploying a Crew on CrewAI AOP"
icon: "rocket"
mode: "wide"
---
<Note>
After creating a crew locally or through Crew Studio, the next step is deploying it to the CrewAI AMP platform. This guide covers multiple deployment methods to help you choose the best approach for your workflow.
After creating a crew locally or through Crew Studio, the next step is deploying it to the CrewAI AOP platform. This guide covers multiple deployment methods to help you choose the best approach for your workflow.
</Note>
## Prerequisites
@@ -39,10 +39,10 @@ The CLI provides the fastest way to deploy locally developed crews to the Enterp
</Step>
<Step title="Authenticate with the Enterprise Platform">
First, you need to authenticate your CLI with the CrewAI AMP platform:
First, you need to authenticate your CLI with the CrewAI AOP platform:
```bash
# If you already have a CrewAI AMP account, or want to create one:
# If you already have a CrewAI AOP account, or want to create one:
crewai login
```
@@ -124,7 +124,7 @@ The CrewAI CLI offers several commands to manage your deployments:
## Option 2: Deploy Directly via Web Interface
You can also deploy your crews directly through the CrewAI AMP web interface by connecting your GitHub account. This approach doesn't require using the CLI on your local machine.
You can also deploy your crews directly through the CrewAI AOP web interface by connecting your GitHub account. This approach doesn't require using the CLI on your local machine.
<Steps>
@@ -134,9 +134,9 @@ You can also deploy your crews directly through the CrewAI AMP web interface by
</Step>
<Step title="Connecting GitHub to CrewAI AMP">
<Step title="Connecting GitHub to CrewAI AOP">
1. Log in to [CrewAI AMP](https://app.crewai.com)
1. Log in to [CrewAI AOP](https://app.crewai.com)
2. Click on the button "Connect GitHub"
<Frame>
@@ -187,10 +187,101 @@ You can also deploy your crews directly through the CrewAI AMP web interface by
</Steps>
## Option 3: Redeploy Using API (CI/CD Integration)
For automated deployments in CI/CD pipelines, you can use the CrewAI API to trigger redeployments of existing crews. This is particularly useful for GitHub Actions, Jenkins, or other automation workflows.
<Steps>
<Step title="Get Your Personal Access Token">
Navigate to your CrewAI AOP account settings to generate an API token:
1. Go to [app.crewai.com](https://app.crewai.com)
2. Click on **Settings** → **Account** → **Personal Access Token**
3. Generate a new token and copy it securely
4. Store this token as a secret in your CI/CD system
</Step>
<Step title="Find Your Automation UUID">
Locate the unique identifier for your deployed crew:
1. Go to **Automations** in your CrewAI AOP dashboard
2. Select your existing automation/crew
3. Click on **Additional Details**
4. Copy the **UUID** - this identifies your specific crew deployment
</Step>
<Step title="Trigger Redeployment via API">
Use the Deploy API endpoint to trigger a redeployment:
```bash
curl -i -X POST \
-H "Authorization: Bearer YOUR_PERSONAL_ACCESS_TOKEN" \
https://app.crewai.com/crewai_plus/api/v1/crews/YOUR-AUTOMATION-UUID/deploy
# HTTP/2 200
# content-type: application/json
#
# {
# "uuid": "your-automation-uuid",
# "status": "Deploy Enqueued",
# "public_url": "https://your-crew-deployment.crewai.com",
# "token": "your-bearer-token"
# }
```
<Info>
If your automation was first created connected to Git, the API will automatically pull the latest changes from your repository before redeploying.
</Info>
</Step>
<Step title="GitHub Actions Integration Example">
Here's a GitHub Actions workflow with more complex deployment triggers:
```yaml
name: Deploy CrewAI Automation
on:
push:
branches: [ main ]
pull_request:
types: [ labeled ]
release:
types: [ published ]
jobs:
deploy:
runs-on: ubuntu-latest
if: |
(github.event_name == 'push' && github.ref == 'refs/heads/main') ||
(github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'deploy')) ||
(github.event_name == 'release')
steps:
- name: Trigger CrewAI Redeployment
run: |
curl -X POST \
-H "Authorization: Bearer ${{ secrets.CREWAI_PAT }}" \
https://app.crewai.com/crewai_plus/api/v1/crews/${{ secrets.CREWAI_AUTOMATION_UUID }}/deploy
```
<Tip>
Add `CREWAI_PAT` and `CREWAI_AUTOMATION_UUID` as repository secrets. For PR deployments, add a "deploy" label to trigger the workflow.
</Tip>
</Step>
</Steps>
## ⚠️ Environment Variable Security Requirements
<Warning>
**Important**: CrewAI AMP has security restrictions on environment variable names that can cause deployment failures if not followed.
**Important**: CrewAI AOP has security restrictions on environment variable names that can cause deployment failures if not followed.
</Warning>
### Blocked Environment Variable Patterns

View File

@@ -1,6 +1,6 @@
---
title: "Enable Crew Studio"
description: "Enabling Crew Studio on CrewAI AMP"
description: "Enabling Crew Studio on CrewAI AOP"
icon: "comments"
mode: "wide"
---
@@ -24,7 +24,7 @@ With Crew Studio, you can:
- Select appropriate tools
- Configure necessary inputs
- Generate downloadable code for customization
- Deploy directly to the CrewAI AMP platform
- Deploy directly to the CrewAI AOP platform
## Configuration Steps
@@ -32,7 +32,7 @@ Before you can start using Crew Studio, you need to configure your LLM connectio
<Steps>
<Step title="Set Up LLM Connection">
Go to the **LLM Connections** tab in your CrewAI AMP dashboard and create a new LLM connection.
Go to the **LLM Connections** tab in your CrewAI AOP dashboard and create a new LLM connection.
<Note>
Feel free to use any LLM provider you want that is supported by CrewAI.
@@ -82,7 +82,7 @@ Now that you've configured your LLM connection and default settings, you're read
<Steps>
<Step title="Access Studio">
Navigate to the **Studio** section in your CrewAI AMP dashboard.
Navigate to the **Studio** section in your CrewAI AOP dashboard.
</Step>
<Step title="Start a Conversation">
@@ -110,7 +110,7 @@ Now that you've configured your LLM connection and default settings, you're read
Once you're satisfied with the configuration, you can:
- Download the generated code for local customization
- Deploy the crew directly to the CrewAI AMP platform
- Deploy the crew directly to the CrewAI AOP platform
- Modify the configuration and regenerate the crew
</Step>
@@ -162,5 +162,5 @@ Here's a typical workflow for creating a crew with Crew Studio:
</Steps>
<Card title="Need Help?" icon="headset" href="mailto:support@crewai.com">
Contact our support team for assistance with Crew Studio or any other CrewAI AMP features.
Contact our support team for assistance with Crew Studio or any other CrewAI AOP features.
</Card>

View File

@@ -15,7 +15,7 @@ Use the Gmail Trigger to kick off your deployed crews when Gmail events happen i
## Enabling the Gmail Trigger
1. Open your deployment in CrewAI AMP
1. Open your deployment in CrewAI AOP
2. Go to the **Triggers** tab
3. Locate **Gmail** and switch the toggle to enable

View File

@@ -15,7 +15,7 @@ Use the Google Calendar trigger to launch automations whenever calendar events c
## Enabling the Google Calendar Trigger
1. Open your deployment in CrewAI AMP
1. Open your deployment in CrewAI AOP
2. Go to the **Triggers** tab
3. Locate **Google Calendar** and switch the toggle to enable

View File

@@ -15,7 +15,7 @@ Trigger your automations when files are created, updated, or removed in Google D
## Enabling the Google Drive Trigger
1. Open your deployment in CrewAI AMP
1. Open your deployment in CrewAI AOP
2. Go to the **Triggers** tab
3. Locate **Google Drive** and switch the toggle to enable

View File

@@ -5,22 +5,22 @@ icon: "hubspot"
mode: "wide"
---
This guide provides a step-by-step process to set up HubSpot triggers for CrewAI AMP, enabling you to initiate crews directly from HubSpot Workflows.
This guide provides a step-by-step process to set up HubSpot triggers for CrewAI AOP, enabling you to initiate crews directly from HubSpot Workflows.
## Prerequisites
- A CrewAI AMP account
- A CrewAI AOP account
- A HubSpot account with the [HubSpot Workflows](https://knowledge.hubspot.com/workflows/create-workflows) feature
## Setup Steps
<Steps>
<Step title="Connect your HubSpot account with CrewAI AMP">
- Log in to your `CrewAI AMP account > Triggers`
<Step title="Connect your HubSpot account with CrewAI AOP">
- Log in to your `CrewAI AOP account > Triggers`
- Select `HubSpot` from the list of available triggers
- Choose the HubSpot account you want to connect with CrewAI AMP
- Follow the on-screen prompts to authorize CrewAI AMP access to your HubSpot account
- A confirmation message will appear once HubSpot is successfully connected with CrewAI AMP
- Choose the HubSpot account you want to connect with CrewAI AOP
- Follow the on-screen prompts to authorize CrewAI AOP access to your HubSpot account
- A confirmation message will appear once HubSpot is successfully connected with CrewAI AOP
</Step>
<Step title="Create a HubSpot Workflow">
- Log in to your `HubSpot account > Automations > Workflows > New workflow`

View File

@@ -1,19 +1,19 @@
---
title: "Kickoff Crew"
description: "Kickoff a Crew on CrewAI AMP"
description: "Kickoff a Crew on CrewAI AOP"
icon: "flag-checkered"
mode: "wide"
---
## Overview
Once you've deployed your crew to the CrewAI AMP platform, you can kickoff executions through the web interface or the API. This guide covers both approaches.
Once you've deployed your crew to the CrewAI AOP platform, you can kickoff executions through the web interface or the API. This guide covers both approaches.
## Method 1: Using the Web Interface
### Step 1: Navigate to Your Deployed Crew
1. Log in to [CrewAI AMP](https://app.crewai.com)
1. Log in to [CrewAI AOP](https://app.crewai.com)
2. Click on the crew name from your projects list
3. You'll be taken to the crew's detail page
@@ -83,7 +83,7 @@ Once execution is complete:
## Method 2: Using the API
You can also kickoff crews programmatically using the CrewAI AMP REST API.
You can also kickoff crews programmatically using the CrewAI AOP REST API.
### Authentication

View File

@@ -15,7 +15,7 @@ Use the Microsoft Teams trigger to start automations whenever a new chat is crea
## Enabling the Microsoft Teams Trigger
1. Open your deployment in CrewAI AMP
1. Open your deployment in CrewAI AOP
2. Go to the **Triggers** tab
3. Locate **Microsoft Teams** and switch the toggle to enable

View File

@@ -15,7 +15,7 @@ Start automations when files change inside OneDrive. You can generate audit summ
## Enabling the OneDrive Trigger
1. Open your deployment in CrewAI AMP
1. Open your deployment in CrewAI AOP
2. Go to the **Triggers** tab
3. Locate **OneDrive** and switch the toggle to enable

View File

@@ -15,7 +15,7 @@ Automate responses when Outlook delivers a new message or when an event is remov
## Enabling the Outlook Trigger
1. Open your deployment in CrewAI AMP
1. Open your deployment in CrewAI AOP
2. Go to the **Triggers** tab
3. Locate **Outlook** and switch the toggle to enable

View File

@@ -1,11 +1,11 @@
---
title: "React Component Export"
description: "Learn how to export and integrate CrewAI AMP React components into your applications"
description: "Learn how to export and integrate CrewAI AOP React components into your applications"
icon: "react"
mode: "wide"
---
This guide explains how to export CrewAI AMP crews as React components and integrate them into your own applications.
This guide explains how to export CrewAI AOP crews as React components and integrate them into your own applications.
## Exporting a React Component

View File

@@ -5,7 +5,7 @@ icon: "salesforce"
mode: "wide"
---
CrewAI AMP can be triggered from Salesforce to automate customer relationship management workflows and enhance your sales operations.
CrewAI AOP can be triggered from Salesforce to automate customer relationship management workflows and enhance your sales operations.
## Overview
@@ -31,7 +31,7 @@ Salesforce is a leading customer relationship management (CRM) platform that hel
To set up Salesforce triggers:
1. **Contact Support**: Reach out to CrewAI AMP support for assistance with Salesforce trigger setup
1. **Contact Support**: Reach out to CrewAI AOP support for assistance with Salesforce trigger setup
2. **Review Requirements**: Ensure you have the necessary Salesforce permissions and API access
3. **Configure Connection**: Work with the support team to establish the connection between CrewAI and your Salesforce instance
4. **Test Triggers**: Verify the triggers work correctly with your specific use cases
@@ -47,4 +47,4 @@ Common Salesforce + CrewAI trigger scenarios include:
## Next Steps
For detailed setup instructions and advanced configuration options, please contact CrewAI AMP support who can provide tailored guidance for your specific Salesforce environment and business needs.
For detailed setup instructions and advanced configuration options, please contact CrewAI AOP support who can provide tailored guidance for your specific Salesforce environment and business needs.

View File

@@ -1,17 +1,17 @@
---
title: "Team Management"
description: "Learn how to invite and manage team members in your CrewAI AMP organization"
description: "Learn how to invite and manage team members in your CrewAI AOP organization"
icon: "users"
mode: "wide"
---
As an administrator of a CrewAI AMP account, you can easily invite new team members to join your organization. This guide will walk you through the process step-by-step.
As an administrator of a CrewAI AOP account, you can easily invite new team members to join your organization. This guide will walk you through the process step-by-step.
## Inviting Team Members
<Steps>
<Step title="Access the Settings Page">
- Log in to your CrewAI AMP account
- Log in to your CrewAI AOP account
- Look for the gear icon (⚙️) in the top right corner of the dashboard
- Click on the gear icon to access the **Settings** page:
<Frame caption="Settings page">
@@ -43,7 +43,7 @@ You can add roles to your team members to control their access to different part
<Steps>
<Step title="Access the Settings Page">
- Log in to your CrewAI AMP account
- Log in to your CrewAI AOP account
- Look for the gear icon (⚙️) in the top right corner of the dashboard
- Click on the gear icon to access the **Settings** page:
<Frame>
@@ -85,4 +85,4 @@ You can add roles to your team members to control their access to different part
- **Invitation Acceptance**: Invited members will need to accept the invitation to join your organization
- **Email Notifications**: You may want to inform your team members to check their email (including spam folders) for the invitation
By following these steps, you can easily expand your team and collaborate more effectively within your CrewAI AMP organization.
By following these steps, you can easily expand your team and collaborate more effectively within your CrewAI AOP organization.

View File

@@ -20,11 +20,11 @@ The repository is not a version control system. Use Git to track code changes an
Before using the Tool Repository, ensure you have:
- A [CrewAI AMP](https://app.crewai.com) account
- [CrewAI CLI](https://docs.crewai.com/concepts/cli#cli) installed
- A [CrewAI AOP](https://app.crewai.com) account
- [CrewAI CLI](/en/concepts/cli#cli) installed
- uv>=0.5.0 installed. Check out [how to upgrade](https://docs.astral.sh/uv/getting-started/installation/#upgrading-uv)
- [Git](https://git-scm.com) installed and configured
- Access permissions to publish or install tools in your CrewAI AMP organization
- Access permissions to publish or install tools in your CrewAI AOP organization
## Installing Tools
@@ -54,11 +54,11 @@ researcher = Agent(
## Adding other packages after installing a tool
After installing a tool from the CrewAI AMP Tool Repository, you need to use the `crewai uv` command to add other packages to your project.
After installing a tool from the CrewAI AOP Tool Repository, you need to use the `crewai uv` command to add other packages to your project.
Using pure `uv` commands will fail due to authentication to tool repository being handled by the CLI. By using the `crewai uv` command, you can add other packages to your project without having to worry about authentication.
Any `uv` command can be used with the `crewai uv` command, making it a powerful tool for managing your project's dependencies without the hassle of managing authentication through environment variables or other methods.
Say that you have installed a custom tool from the CrewAI AMP Tool Repository called "my-tool":
Say that you have installed a custom tool from the CrewAI AOP Tool Repository called "my-tool":
```bash
crewai tool install my-tool
@@ -112,7 +112,7 @@ By default, tools are published as private. To make a tool public:
crewai tool publish --public
```
For more details on how to build tools, see [Creating your own tools](https://docs.crewai.com/concepts/tools#creating-your-own-tools).
For more details on how to build tools, see [Creating your own tools](/en/concepts/tools#creating-your-own-tools).
## Updating Tools
@@ -131,7 +131,7 @@ crewai tool publish
To delete a tool:
1. Go to [CrewAI AMP](https://app.crewai.com)
1. Go to [CrewAI AOP](https://app.crewai.com)
2. Navigate to **Tools**
3. Select the tool
4. Click **Delete**
@@ -146,10 +146,8 @@ Every published version undergoes automated security checks, and are only availa
You can check the security check status of a tool at:
`CrewAI AMP > Tools > Your Tool > Versions`
`CrewAI AOP > Tools > Your Tool > Versions`
<Card title="Need Help?" icon="headset" href="mailto:support@crewai.com">
Contact our support team for assistance with API integration or troubleshooting.
</Card>

View File

@@ -1,12 +1,12 @@
---
title: "Update Crew"
description: "Updating a Crew on CrewAI AMP"
description: "Updating a Crew on CrewAI AOP"
icon: "pencil"
mode: "wide"
---
<Note>
After deploying your crew to CrewAI AMP, you may need to make updates to the code, security settings, or configuration.
After deploying your crew to CrewAI AOP, you may need to make updates to the code, security settings, or configuration.
This guide explains how to perform these common update operations.
</Note>
@@ -23,7 +23,7 @@ There are several reasons you might want to update your crew deployment:
When you've pushed new commits to your GitHub repository and want to update your deployment:
1. Navigate to your crew in the CrewAI AMP platform
1. Navigate to your crew in the CrewAI AOP platform
2. Click on the `Re-deploy` button on your crew details page
<Frame>
@@ -36,7 +36,7 @@ This will trigger an update that you can track using the progress bar. The syste
If you need to generate a new bearer token (for example, if you suspect the current token might have been compromised):
1. Navigate to your crew in the CrewAI AMP platform
1. Navigate to your crew in the CrewAI AOP platform
2. Find the `Bearer Token` section
3. Click the `Reset` button next to your current token

View File

@@ -1,17 +1,17 @@
---
title: "Webhook Automation"
description: "Automate CrewAI AMP workflows using webhooks with platforms like ActivePieces, Zapier, and Make.com"
description: "Automate CrewAI AOP workflows using webhooks with platforms like ActivePieces, Zapier, and Make.com"
icon: "webhook"
mode: "wide"
---
CrewAI AMP allows you to automate your workflow using webhooks. This article will guide you through the process of setting up and using webhooks to kickoff your crew execution, with a focus on integration with ActivePieces, a workflow automation platform similar to Zapier and Make.com.
CrewAI AOP allows you to automate your workflow using webhooks. This article will guide you through the process of setting up and using webhooks to kickoff your crew execution, with a focus on integration with ActivePieces, a workflow automation platform similar to Zapier and Make.com.
## Setting Up Webhooks
<Steps>
<Step title="Accessing the Kickoff Interface">
- Navigate to the CrewAI AMP dashboard
- Navigate to the CrewAI AOP dashboard
- Look for the `/kickoff` section, which is used to start the crew execution
<Frame>
<img src="/images/enterprise/kickoff-interface.png" alt="Kickoff Interface" />
@@ -44,7 +44,7 @@ CrewAI AMP allows you to automate your workflow using webhooks. This article wil
3. Add an HTTP action step
- Set the action to `Send HTTP request`
- Use `POST` as the method
- Set the URL to your CrewAI AMP kickoff endpoint
- Set the URL to your CrewAI AOP kickoff endpoint
- Add necessary headers (e.g., `Bearer Token`)
<Frame>
<img src="/images/enterprise/activepieces-headers.png" alt="ActivePieces Headers" />

View File

@@ -5,11 +5,11 @@ icon: "bolt"
mode: "wide"
---
This guide will walk you through the process of setting up Zapier triggers for CrewAI AMP, allowing you to automate workflows between CrewAI AMP and other applications.
This guide will walk you through the process of setting up Zapier triggers for CrewAI AOP, allowing you to automate workflows between CrewAI AOP and other applications.
## Prerequisites
- A CrewAI AMP account
- A CrewAI AOP account
- A Zapier account
- A Slack account (for this specific example)
@@ -32,7 +32,7 @@ This guide will walk you through the process of setting up Zapier triggers for C
- Connect your Slack account if you haven't already.
</Step>
<Step title="Configure the CrewAI AMP Action">
<Step title="Configure the CrewAI AOP Action">
- Add a new action step to your Zap.
- Choose CrewAI+ as your action app and Kickoff as the Action Event
@@ -41,8 +41,8 @@ This guide will walk you through the process of setting up Zapier triggers for C
</Frame>
</Step>
<Step title="Connect your CrewAI AMP account">
- Connect your CrewAI AMP account.
<Step title="Connect your CrewAI AOP account">
- Connect your CrewAI AOP account.
- Select the appropriate Crew for your workflow.
<Frame>
@@ -51,8 +51,8 @@ This guide will walk you through the process of setting up Zapier triggers for C
- Configure the inputs for the Crew using the data from the Slack message.
</Step>
<Step title="Format the CrewAI AMP Output">
- Add another action step to format the text output from CrewAI AMP.
<Step title="Format the CrewAI AOP Output">
- Add another action step to format the text output from CrewAI AOP.
- Use Zapier's formatting tools to convert the Markdown output to HTML.
<Frame>
@@ -67,7 +67,7 @@ This guide will walk you through the process of setting up Zapier triggers for C
- Add a final action step to send the formatted output via email.
- Choose your preferred email service (e.g., Gmail, Outlook).
- Configure the email details, including recipient, subject, and body.
- Insert the formatted CrewAI AMP output into the email body.
- Insert the formatted CrewAI AOP output into the email body.
<Frame>
<img src="/images/enterprise/zapier-7.png" alt="Zapier 7" />
@@ -97,8 +97,8 @@ This guide will walk you through the process of setting up Zapier triggers for C
## Tips for Success
- Ensure that your CrewAI AMP inputs are correctly mapped from the Slack message.
- Ensure that your CrewAI AOP inputs are correctly mapped from the Slack message.
- Test your Zap thoroughly before turning it on to catch any potential issues.
- Consider adding error handling steps to manage potential failures in the workflow.
By following these steps, you'll have successfully set up Zapier triggers for CrewAI AMP, allowing for automated workflows triggered by Slack messages and resulting in email notifications with CrewAI AMP output.
By following these steps, you'll have successfully set up Zapier triggers for CrewAI AOP, allowing for automated workflows triggered by Slack messages and resulting in email notifications with CrewAI AOP output.

View File

@@ -13,7 +13,7 @@ Enable your agents to manage tasks, projects, and team coordination through Asan
Before using the Asana integration, ensure you have:
- A [CrewAI AMP](https://app.crewai.com) account with an active subscription
- A [CrewAI AOP](https://app.crewai.com) account with an active subscription
- An Asana account with appropriate permissions
- Connected your Asana account through the [Integrations page](https://app.crewai.com/crewai_plus/connectors)
@@ -21,7 +21,7 @@ Before using the Asana integration, ensure you have:
### 1. Connect Your Asana Account
1. Navigate to [CrewAI AMP Integrations](https://app.crewai.com/crewai_plus/connectors)
1. Navigate to [CrewAI AOP Integrations](https://app.crewai.com/crewai_plus/connectors)
2. Find **Asana** in the Authentication Integrations section
3. Click **Connect** and complete the OAuth flow
4. Grant the necessary permissions for task and project management

View File

@@ -13,7 +13,7 @@ Enable your agents to manage files, folders, and documents through Box. Upload f
Before using the Box integration, ensure you have:
- A [CrewAI AMP](https://app.crewai.com) account with an active subscription
- A [CrewAI AOP](https://app.crewai.com) account with an active subscription
- A Box account with appropriate permissions
- Connected your Box account through the [Integrations page](https://app.crewai.com/crewai_plus/connectors)
@@ -21,7 +21,7 @@ Before using the Box integration, ensure you have:
### 1. Connect Your Box Account
1. Navigate to [CrewAI AMP Integrations](https://app.crewai.com/crewai_plus/connectors)
1. Navigate to [CrewAI AOP Integrations](https://app.crewai.com/crewai_plus/connectors)
2. Find **Box** in the Authentication Integrations section
3. Click **Connect** and complete the OAuth flow
4. Grant the necessary permissions for file and folder management

View File

@@ -13,7 +13,7 @@ Enable your agents to manage tasks, projects, and productivity workflows through
Before using the ClickUp integration, ensure you have:
- A [CrewAI AMP](https://app.crewai.com) account with an active subscription
- A [CrewAI AOP](https://app.crewai.com) account with an active subscription
- A ClickUp account with appropriate permissions
- Connected your ClickUp account through the [Integrations page](https://app.crewai.com/crewai_plus/connectors)
@@ -21,7 +21,7 @@ Before using the ClickUp integration, ensure you have:
### 1. Connect Your ClickUp Account
1. Navigate to [CrewAI AMP Integrations](https://app.crewai.com/crewai_plus/connectors)
1. Navigate to [CrewAI AOP Integrations](https://app.crewai.com/crewai_plus/connectors)
2. Find **ClickUp** in the Authentication Integrations section
3. Click **Connect** and complete the OAuth flow
4. Grant the necessary permissions for task and project management

View File

@@ -13,7 +13,7 @@ Enable your agents to manage repositories, issues, and releases through GitHub.
Before using the GitHub integration, ensure you have:
- A [CrewAI AMP](https://app.crewai.com) account with an active subscription
- A [CrewAI AOP](https://app.crewai.com) account with an active subscription
- A GitHub account with appropriate repository permissions
- Connected your GitHub account through the [Integrations page](https://app.crewai.com/crewai_plus/connectors)
@@ -21,7 +21,7 @@ Before using the GitHub integration, ensure you have:
### 1. Connect Your GitHub Account
1. Navigate to [CrewAI AMP Integrations](https://app.crewai.com/crewai_plus/connectors)
1. Navigate to [CrewAI AOP Integrations](https://app.crewai.com/crewai_plus/connectors)
2. Find **GitHub** in the Authentication Integrations section
3. Click **Connect** and complete the OAuth flow
4. Grant the necessary permissions for repository and issue management

View File

@@ -13,7 +13,7 @@ Enable your agents to manage emails, contacts, and drafts through Gmail. Send em
Before using the Gmail integration, ensure you have:
- A [CrewAI AMP](https://app.crewai.com) account with an active subscription
- A [CrewAI AOP](https://app.crewai.com) account with an active subscription
- A Gmail account with appropriate permissions
- Connected your Gmail account through the [Integrations page](https://app.crewai.com/crewai_plus/connectors)
@@ -21,7 +21,7 @@ Before using the Gmail integration, ensure you have:
### 1. Connect Your Gmail Account
1. Navigate to [CrewAI AMP Integrations](https://app.crewai.com/crewai_plus/connectors)
1. Navigate to [CrewAI AOP Integrations](https://app.crewai.com/crewai_plus/connectors)
2. Find **Gmail** in the Authentication Integrations section
3. Click **Connect** and complete the OAuth flow
4. Grant the necessary permissions for email and contact management

View File

@@ -13,7 +13,7 @@ Enable your agents to manage calendar events, schedules, and availability throug
Before using the Google Calendar integration, ensure you have:
- A [CrewAI AMP](https://app.crewai.com) account with an active subscription
- A [CrewAI AOP](https://app.crewai.com) account with an active subscription
- A Google account with Google Calendar access
- Connected your Google account through the [Integrations page](https://app.crewai.com/crewai_plus/connectors)
@@ -21,7 +21,7 @@ Before using the Google Calendar integration, ensure you have:
### 1. Connect Your Google Account
1. Navigate to [CrewAI AMP Integrations](https://app.crewai.com/crewai_plus/connectors)
1. Navigate to [CrewAI AOP Integrations](https://app.crewai.com/crewai_plus/connectors)
2. Find **Google Calendar** in the Authentication Integrations section
3. Click **Connect** and complete the OAuth flow
4. Grant the necessary permissions for calendar access

View File

@@ -13,7 +13,7 @@ Enable your agents to manage contacts and directory information through Google C
Before using the Google Contacts integration, ensure you have:
- A [CrewAI AMP](https://app.crewai.com) account with an active subscription
- A [CrewAI AOP](https://app.crewai.com) account with an active subscription
- A Google account with Google Contacts access
- Connected your Google account through the [Integrations page](https://app.crewai.com/crewai_plus/connectors)
@@ -21,7 +21,7 @@ Before using the Google Contacts integration, ensure you have:
### 1. Connect Your Google Account
1. Navigate to [CrewAI AMP Integrations](https://app.crewai.com/crewai_plus/connectors)
1. Navigate to [CrewAI AOP Integrations](https://app.crewai.com/crewai_plus/connectors)
2. Find **Google Contacts** in the Authentication Integrations section
3. Click **Connect** and complete the OAuth flow
4. Grant the necessary permissions for contacts and directory access

View File

@@ -13,7 +13,7 @@ Enable your agents to create, edit, and manage Google Docs documents with text m
Before using the Google Docs integration, ensure you have:
- A [CrewAI AMP](https://app.crewai.com) account with an active subscription
- A [CrewAI AOP](https://app.crewai.com) account with an active subscription
- A Google account with Google Docs access
- Connected your Google account through the [Integrations page](https://app.crewai.com/crewai_plus/connectors)
@@ -21,7 +21,7 @@ Before using the Google Docs integration, ensure you have:
### 1. Connect Your Google Account
1. Navigate to [CrewAI AMP Integrations](https://app.crewai.com/crewai_plus/connectors)
1. Navigate to [CrewAI AOP Integrations](https://app.crewai.com/crewai_plus/connectors)
2. Find **Google Docs** in the Authentication Integrations section
3. Click **Connect** and complete the OAuth flow
4. Grant the necessary permissions for document access

View File

@@ -13,7 +13,7 @@ Enable your agents to manage files and folders through Google Drive. Upload, dow
Before using the Google Drive integration, ensure you have:
- A [CrewAI AMP](https://app.crewai.com) account with an active subscription
- A [CrewAI AOP](https://app.crewai.com) account with an active subscription
- A Google account with Google Drive access
- Connected your Google account through the [Integrations page](https://app.crewai.com/crewai_plus/connectors)
@@ -21,7 +21,7 @@ Before using the Google Drive integration, ensure you have:
### 1. Connect Your Google Account
1. Navigate to [CrewAI AMP Integrations](https://app.crewai.com/crewai_plus/connectors)
1. Navigate to [CrewAI AOP Integrations](https://app.crewai.com/crewai_plus/connectors)
2. Find **Google Drive** in the Authentication Integrations section
3. Click **Connect** and complete the OAuth flow
4. Grant the necessary permissions for file and folder management

View File

@@ -13,7 +13,7 @@ Enable your agents to manage spreadsheet data through Google Sheets. Read rows,
Before using the Google Sheets integration, ensure you have:
- A [CrewAI AMP](https://app.crewai.com) account with an active subscription
- A [CrewAI AOP](https://app.crewai.com) account with an active subscription
- A Google account with Google Sheets access
- Connected your Google account through the [Integrations page](https://app.crewai.com/crewai_plus/connectors)
- Spreadsheets with proper column headers for data operations
@@ -22,7 +22,7 @@ Before using the Google Sheets integration, ensure you have:
### 1. Connect Your Google Account
1. Navigate to [CrewAI AMP Integrations](https://app.crewai.com/crewai_plus/connectors)
1. Navigate to [CrewAI AOP Integrations](https://app.crewai.com/crewai_plus/connectors)
2. Find **Google Sheets** in the Authentication Integrations section
3. Click **Connect** and complete the OAuth flow
4. Grant the necessary permissions for spreadsheet access

View File

@@ -13,7 +13,7 @@ Enable your agents to create, edit, and manage Google Slides presentations. Crea
Before using the Google Slides integration, ensure you have:
- A [CrewAI AMP](https://app.crewai.com) account with an active subscription
- A [CrewAI AOP](https://app.crewai.com) account with an active subscription
- A Google account with Google Slides access
- Connected your Google account through the [Integrations page](https://app.crewai.com/crewai_plus/connectors)
@@ -21,7 +21,7 @@ Before using the Google Slides integration, ensure you have:
### 1. Connect Your Google Account
1. Navigate to [CrewAI AMP Integrations](https://app.crewai.com/crewai_plus/connectors)
1. Navigate to [CrewAI AOP Integrations](https://app.crewai.com/crewai_plus/connectors)
2. Find **Google Slides** in the Authentication Integrations section
3. Click **Connect** and complete the OAuth flow
4. Grant the necessary permissions for presentations, spreadsheets, and drive access

View File

@@ -13,7 +13,7 @@ Enable your agents to manage companies and contacts within HubSpot. Create new r
Before using the HubSpot integration, ensure you have:
- A [CrewAI AMP](https://app.crewai.com) account with an active subscription.
- A [CrewAI AOP](https://app.crewai.com) account with an active subscription.
- A HubSpot account with appropriate permissions.
- Connected your HubSpot account through the [Integrations page](https://app.crewai.com/crewai_plus/connectors).
@@ -21,7 +21,7 @@ Before using the HubSpot integration, ensure you have:
### 1. Connect Your HubSpot Account
1. Navigate to [CrewAI AMP Integrations](https://app.crewai.com/crewai_plus/connectors).
1. Navigate to [CrewAI AOP Integrations](https://app.crewai.com/crewai_plus/connectors).
2. Find **HubSpot** in the Authentication Integrations section.
3. Click **Connect** and complete the OAuth flow.
4. Grant the necessary permissions for company and contact management.

View File

@@ -13,7 +13,7 @@ Enable your agents to manage issues, projects, and workflows through Jira. Creat
Before using the Jira integration, ensure you have:
- A [CrewAI AMP](https://app.crewai.com) account with an active subscription
- A [CrewAI AOP](https://app.crewai.com) account with an active subscription
- A Jira account with appropriate project permissions
- Connected your Jira account through the [Integrations page](https://app.crewai.com/crewai_plus/connectors)
@@ -21,7 +21,7 @@ Before using the Jira integration, ensure you have:
### 1. Connect Your Jira Account
1. Navigate to [CrewAI AMP Integrations](https://app.crewai.com/crewai_plus/connectors)
1. Navigate to [CrewAI AOP Integrations](https://app.crewai.com/crewai_plus/connectors)
2. Find **Jira** in the Authentication Integrations section
3. Click **Connect** and complete the OAuth flow
4. Grant the necessary permissions for issue and project management

View File

@@ -13,7 +13,7 @@ Enable your agents to manage issues, projects, and development workflows through
Before using the Linear integration, ensure you have:
- A [CrewAI AMP](https://app.crewai.com) account with an active subscription
- A [CrewAI AOP](https://app.crewai.com) account with an active subscription
- A Linear account with appropriate workspace permissions
- Connected your Linear account through the [Integrations page](https://app.crewai.com/crewai_plus/connectors)
@@ -21,7 +21,7 @@ Before using the Linear integration, ensure you have:
### 1. Connect Your Linear Account
1. Navigate to [CrewAI AMP Integrations](https://app.crewai.com/crewai_plus/connectors)
1. Navigate to [CrewAI AOP Integrations](https://app.crewai.com/crewai_plus/connectors)
2. Find **Linear** in the Authentication Integrations section
3. Click **Connect** and complete the OAuth flow
4. Grant the necessary permissions for issue and project management

View File

@@ -13,7 +13,7 @@ Enable your agents to create and manage Excel workbooks, worksheets, tables, and
Before using the Microsoft Excel integration, ensure you have:
- A [CrewAI AMP](https://app.crewai.com) account with an active subscription
- A [CrewAI AOP](https://app.crewai.com) account with an active subscription
- A Microsoft 365 account with Excel and OneDrive/SharePoint access
- Connected your Microsoft account through the [Integrations page](https://app.crewai.com/crewai_plus/connectors)
@@ -21,7 +21,7 @@ Before using the Microsoft Excel integration, ensure you have:
### 1. Connect Your Microsoft Account
1. Navigate to [CrewAI AMP Integrations](https://app.crewai.com/crewai_plus/connectors)
1. Navigate to [CrewAI AOP Integrations](https://app.crewai.com/crewai_plus/connectors)
2. Find **Microsoft Excel** in the Authentication Integrations section
3. Click **Connect** and complete the OAuth flow
4. Grant the necessary permissions for files and Excel workbook access

View File

@@ -13,7 +13,7 @@ Enable your agents to upload, download, and manage files and folders in Microsof
Before using the Microsoft OneDrive integration, ensure you have:
- A [CrewAI AMP](https://app.crewai.com) account with an active subscription
- A [CrewAI AOP](https://app.crewai.com) account with an active subscription
- A Microsoft account with OneDrive access
- Connected your Microsoft account through the [Integrations page](https://app.crewai.com/crewai_plus/connectors)
@@ -21,7 +21,7 @@ Before using the Microsoft OneDrive integration, ensure you have:
### 1. Connect Your Microsoft Account
1. Navigate to [CrewAI AMP Integrations](https://app.crewai.com/crewai_plus/connectors)
1. Navigate to [CrewAI AOP Integrations](https://app.crewai.com/crewai_plus/connectors)
2. Find **Microsoft OneDrive** in the Authentication Integrations section
3. Click **Connect** and complete the OAuth flow
4. Grant the necessary permissions for file access

View File

@@ -13,7 +13,7 @@ Enable your agents to access and manage Outlook emails, calendar events, and con
Before using the Microsoft Outlook integration, ensure you have:
- A [CrewAI AMP](https://app.crewai.com) account with an active subscription
- A [CrewAI AOP](https://app.crewai.com) account with an active subscription
- A Microsoft account with Outlook access
- Connected your Microsoft account through the [Integrations page](https://app.crewai.com/crewai_plus/connectors)
@@ -21,7 +21,7 @@ Before using the Microsoft Outlook integration, ensure you have:
### 1. Connect Your Microsoft Account
1. Navigate to [CrewAI AMP Integrations](https://app.crewai.com/crewai_plus/connectors)
1. Navigate to [CrewAI AOP Integrations](https://app.crewai.com/crewai_plus/connectors)
2. Find **Microsoft Outlook** in the Authentication Integrations section
3. Click **Connect** and complete the OAuth flow
4. Grant the necessary permissions for mail, calendar, and contact access

View File

@@ -13,7 +13,7 @@ Enable your agents to access and manage SharePoint sites, lists, and document li
Before using the Microsoft SharePoint integration, ensure you have:
- A [CrewAI AMP](https://app.crewai.com) account with an active subscription
- A [CrewAI AOP](https://app.crewai.com) account with an active subscription
- A Microsoft 365 account with SharePoint access
- Connected your Microsoft account through the [Integrations page](https://app.crewai.com/crewai_plus/connectors)
@@ -21,7 +21,7 @@ Before using the Microsoft SharePoint integration, ensure you have:
### 1. Connect Your Microsoft Account
1. Navigate to [CrewAI AMP Integrations](https://app.crewai.com/crewai_plus/connectors)
1. Navigate to [CrewAI AOP Integrations](https://app.crewai.com/crewai_plus/connectors)
2. Find **Microsoft SharePoint** in the Authentication Integrations section
3. Click **Connect** and complete the OAuth flow
4. Grant the necessary permissions for SharePoint sites and content access

View File

@@ -13,7 +13,7 @@ Enable your agents to access Teams data, send messages, create meetings, and man
Before using the Microsoft Teams integration, ensure you have:
- A [CrewAI AMP](https://app.crewai.com) account with an active subscription
- A [CrewAI AOP](https://app.crewai.com) account with an active subscription
- A Microsoft account with Teams access
- Connected your Microsoft account through the [Integrations page](https://app.crewai.com/crewai_plus/connectors)
@@ -21,7 +21,7 @@ Before using the Microsoft Teams integration, ensure you have:
### 1. Connect Your Microsoft Account
1. Navigate to [CrewAI AMP Integrations](https://app.crewai.com/crewai_plus/connectors)
1. Navigate to [CrewAI AOP Integrations](https://app.crewai.com/crewai_plus/connectors)
2. Find **Microsoft Teams** in the Authentication Integrations section
3. Click **Connect** and complete the OAuth flow
4. Grant the necessary permissions for Teams access

View File

@@ -13,7 +13,7 @@ Enable your agents to create, read, and manage Word documents and text files in
Before using the Microsoft Word integration, ensure you have:
- A [CrewAI AMP](https://app.crewai.com) account with an active subscription
- A [CrewAI AOP](https://app.crewai.com) account with an active subscription
- A Microsoft account with Word and OneDrive/SharePoint access
- Connected your Microsoft account through the [Integrations page](https://app.crewai.com/crewai_plus/connectors)
@@ -21,7 +21,7 @@ Before using the Microsoft Word integration, ensure you have:
### 1. Connect Your Microsoft Account
1. Navigate to [CrewAI AMP Integrations](https://app.crewai.com/crewai_plus/connectors)
1. Navigate to [CrewAI AOP Integrations](https://app.crewai.com/crewai_plus/connectors)
2. Find **Microsoft Word** in the Authentication Integrations section
3. Click **Connect** and complete the OAuth flow
4. Grant the necessary permissions for file access

View File

@@ -13,7 +13,7 @@ Enable your agents to manage users and create comments through Notion. Access wo
Before using the Notion integration, ensure you have:
- A [CrewAI AMP](https://app.crewai.com) account with an active subscription
- A [CrewAI AOP](https://app.crewai.com) account with an active subscription
- A Notion account with appropriate workspace permissions
- Connected your Notion account through the [Integrations page](https://app.crewai.com/crewai_plus/connectors)
@@ -21,7 +21,7 @@ Before using the Notion integration, ensure you have:
### 1. Connect Your Notion Account
1. Navigate to [CrewAI AMP Integrations](https://app.crewai.com/crewai_plus/connectors)
1. Navigate to [CrewAI AOP Integrations](https://app.crewai.com/crewai_plus/connectors)
2. Find **Notion** in the Authentication Integrations section
3. Click **Connect** and complete the OAuth flow
4. Grant the necessary permissions for user access and comment creation

View File

@@ -13,7 +13,7 @@ Enable your agents to manage customer relationships, sales processes, and data t
Before using the Salesforce integration, ensure you have:
- A [CrewAI AMP](https://app.crewai.com) account with an active subscription
- A [CrewAI AOP](https://app.crewai.com) account with an active subscription
- A Salesforce account with appropriate permissions
- Connected your Salesforce account through the [Integrations page](https://app.crewai.com/integrations)
@@ -21,7 +21,7 @@ Before using the Salesforce integration, ensure you have:
### 1. Connect Your Salesforce Account
1. Navigate to [CrewAI AMP Integrations](https://app.crewai.com/crewai_plus/connectors)
1. Navigate to [CrewAI AOP 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

View File

@@ -13,7 +13,7 @@ Enable your agents to manage e-commerce operations through Shopify. Handle custo
Before using the Shopify integration, ensure you have:
- A [CrewAI AMP](https://app.crewai.com) account with an active subscription
- A [CrewAI AOP](https://app.crewai.com) account with an active subscription
- A Shopify store with appropriate admin permissions
- Connected your Shopify store through the [Integrations page](https://app.crewai.com/integrations)
@@ -21,7 +21,7 @@ Before using the Shopify integration, ensure you have:
### 1. Connect Your Shopify Store
1. Navigate to [CrewAI AMP Integrations](https://app.crewai.com/crewai_plus/connectors)
1. Navigate to [CrewAI AOP Integrations](https://app.crewai.com/crewai_plus/connectors)
2. Find **Shopify** in the Authentication Integrations section
3. Click **Connect** and complete the OAuth flow
4. Grant the necessary permissions for store and product management

View File

@@ -13,7 +13,7 @@ Enable your agents to manage team communication through Slack. Send messages, se
Before using the Slack integration, ensure you have:
- A [CrewAI AMP](https://app.crewai.com) account with an active subscription
- A [CrewAI AOP](https://app.crewai.com) account with an active subscription
- A Slack workspace with appropriate permissions
- Connected your Slack workspace through the [Integrations page](https://app.crewai.com/integrations)
@@ -21,7 +21,7 @@ Before using the Slack integration, ensure you have:
### 1. Connect Your Slack Workspace
1. Navigate to [CrewAI AMP Integrations](https://app.crewai.com/crewai_plus/connectors)
1. Navigate to [CrewAI AOP Integrations](https://app.crewai.com/crewai_plus/connectors)
2. Find **Slack** in the Authentication Integrations section
3. Click **Connect** and complete the OAuth flow
4. Grant the necessary permissions for team communication

View File

@@ -13,7 +13,7 @@ Enable your agents to manage payments, subscriptions, and customer billing throu
Before using the Stripe integration, ensure you have:
- A [CrewAI AMP](https://app.crewai.com) account with an active subscription
- A [CrewAI AOP](https://app.crewai.com) account with an active subscription
- A Stripe account with appropriate API permissions
- Connected your Stripe account through the [Integrations page](https://app.crewai.com/integrations)
@@ -21,7 +21,7 @@ Before using the Stripe integration, ensure you have:
### 1. Connect Your Stripe Account
1. Navigate to [CrewAI AMP Integrations](https://app.crewai.com/crewai_plus/connectors)
1. Navigate to [CrewAI AOP Integrations](https://app.crewai.com/crewai_plus/connectors)
2. Find **Stripe** in the Authentication Integrations section
3. Click **Connect** and complete the OAuth flow
4. Grant the necessary permissions for payment processing

View File

@@ -13,7 +13,7 @@ Enable your agents to manage customer support operations through Zendesk. Create
Before using the Zendesk integration, ensure you have:
- A [CrewAI AMP](https://app.crewai.com) account with an active subscription
- A [CrewAI AOP](https://app.crewai.com) account with an active subscription
- A Zendesk account with appropriate API permissions
- Connected your Zendesk account through the [Integrations page](https://app.crewai.com/integrations)
@@ -21,7 +21,7 @@ Before using the Zendesk integration, ensure you have:
### 1. Connect Your Zendesk Account
1. Navigate to [CrewAI AMP Integrations](https://app.crewai.com/crewai_plus/connectors)
1. Navigate to [CrewAI AOP Integrations](https://app.crewai.com/crewai_plus/connectors)
2. Find **Zendesk** in the Authentication Integrations section
3. Click **Connect** and complete the OAuth flow
4. Grant the necessary permissions for ticket and user management

View File

@@ -1,5 +1,5 @@
---
title: "CrewAI AMP"
title: "CrewAI AOP"
description: "Deploy, monitor, and scale your AI agent workflows"
icon: "globe"
mode: "wide"
@@ -7,13 +7,13 @@ mode: "wide"
## Introduction
CrewAI AMP(Agent Management Platform) provides a platform for deploying, monitoring, and scaling your crews and agents in a production environment.
CrewAI AOP(Agent Operations Platform) provides a platform for deploying, monitoring, and scaling your crews and agents in a production environment.
<Frame>
<img src="/images/enterprise/crewai-enterprise-dashboard.png" alt="CrewAI AMP Dashboard" />
<img src="/images/enterprise/crewai-enterprise-dashboard.png" alt="CrewAI AOP Dashboard" />
</Frame>
CrewAI AMP extends the power of the open-source framework with features designed for production deployments, collaboration, and scalability. Deploy your crews to a managed infrastructure and monitor their execution in real-time.
CrewAI AOP extends the power of the open-source framework with features designed for production deployments, collaboration, and scalability. Deploy your crews to a managed infrastructure and monitor their execution in real-time.
## Key Features

View File

@@ -1,6 +1,6 @@
---
title: FAQs
description: "Frequently asked questions about CrewAI AMP"
description: "Frequently asked questions about CrewAI AOP"
icon: "circle-question"
mode: "wide"
---
@@ -49,7 +49,7 @@ mode: "wide"
To integrate human input into agent execution, set the `human_input` flag in the task definition. When enabled, the agent prompts the user for input before delivering its final answer. This input can provide extra context, clarify ambiguities, or validate the agent's output.
For detailed implementation guidance, see our [Human-in-the-Loop guide](/en/how-to/human-in-the-loop).
For detailed implementation guidance, see our [Human-in-the-Loop guide](/en/enterprise/guides/human-in-the-loop).
</Accordion>
<Accordion title="What advanced customization options are available for tailoring and enhancing agent behavior and capabilities in CrewAI?">
@@ -142,7 +142,7 @@ mode: "wide"
<Accordion title="How can I create custom tools for my CrewAI agents?">
You can create custom tools by subclassing the `BaseTool` class provided by CrewAI or by using the tool decorator. Subclassing involves defining a new class that inherits from `BaseTool`, specifying the name, description, and the `_run` method for operational logic. The tool decorator allows you to create a `Tool` object directly with the required attributes and a functional logic.
<Card href="https://docs.crewai.com/how-to/create-custom-tools" icon="code">CrewAI Tools Guide</Card>
<Card href="/en/learn/create-custom-tools" icon="code">CrewAI Tools Guide</Card>
</Accordion>
<Accordion title="How can you control the maximum number of requests per minute that the entire crew can perform?">

View File

@@ -167,7 +167,7 @@ We recommend using the `YAML` template scaffolding for a structured approach to
<Note type="info">
For teams and organizations, CrewAI offers enterprise deployment options that eliminate setup complexity:
### CrewAI AMP (SaaS)
### CrewAI AOP (SaaS)
- Zero installation required - just sign up for free at [app.crewai.com](https://app.crewai.com)
- Automatic updates and maintenance
- Managed infrastructure and scaling

View File

@@ -0,0 +1,295 @@
---
title: Agent-to-Agent (A2A) Protocol
description: Enable CrewAI agents to delegate tasks to remote A2A-compliant agents for specialized handling
icon: network-wired
mode: "wide"
---
## A2A Agent Delegation
CrewAI supports the Agent-to-Agent (A2A) protocol, allowing agents to delegate tasks to remote specialized agents. The agent's LLM automatically decides whether to handle a task directly or delegate to an A2A agent based on the task requirements.
<Note>
A2A delegation requires the `a2a-sdk` package. Install with: `uv add 'crewai[a2a]'` or `pip install 'crewai[a2a]'`
</Note>
## How It Works
When an agent is configured with A2A capabilities:
1. The LLM analyzes each task
2. It decides to either:
- Handle the task directly using its own capabilities
- Delegate to a remote A2A agent for specialized handling
3. If delegating, the agent communicates with the remote A2A agent through the protocol
4. Results are returned to the CrewAI workflow
## Basic Configuration
Configure an agent for A2A delegation by setting the `a2a` parameter:
```python Code
from crewai import Agent, Crew, Task
from crewai.a2a import A2AConfig
agent = Agent(
role="Research Coordinator",
goal="Coordinate research tasks efficiently",
backstory="Expert at delegating to specialized research agents",
llm="gpt-4o",
a2a=A2AConfig(
endpoint="https://example.com/.well-known/agent-card.json",
timeout=120,
max_turns=10
)
)
task = Task(
description="Research the latest developments in quantum computing",
expected_output="A comprehensive research report",
agent=agent
)
crew = Crew(agents=[agent], tasks=[task], verbose=True)
result = crew.kickoff()
```
## Configuration Options
The `A2AConfig` class accepts the following parameters:
<ParamField path="endpoint" type="str" required>
The A2A agent endpoint URL (typically points to `.well-known/agent-card.json`)
</ParamField>
<ParamField path="auth" type="AuthScheme" default="None">
Authentication scheme for the A2A agent. Supports Bearer tokens, OAuth2, API keys, and HTTP authentication.
</ParamField>
<ParamField path="timeout" type="int" default="120">
Request timeout in seconds
</ParamField>
<ParamField path="max_turns" type="int" default="10">
Maximum number of conversation turns with the A2A agent
</ParamField>
<ParamField path="response_model" type="type[BaseModel]" default="None">
Optional Pydantic model for requesting structured output from an A2A agent. A2A protocol does not
enforce this, so an A2A agent does not need to honor this request.
</ParamField>
<ParamField path="fail_fast" type="bool" default="True">
Whether to raise an error immediately if agent connection fails. When `False`, the agent continues with available agents and informs the LLM about unavailable ones.
</ParamField>
<ParamField path="trust_remote_completion_status" type="bool" default="False">
When `True`, returns the A2A agent's result directly when it signals completion. When `False`, allows the server agent to review the result and potentially continue the conversation.
</ParamField>
## Authentication
For A2A agents that require authentication, use one of the provided auth schemes:
<Tabs>
<Tab title="Bearer Token">
```python Code
from crewai.a2a import A2AConfig
from crewai.a2a.auth import BearerTokenAuth
agent = Agent(
role="Secure Coordinator",
goal="Coordinate tasks with secured agents",
backstory="Manages secure agent communications",
llm="gpt-4o",
a2a=A2AConfig(
endpoint="https://secure-agent.example.com/.well-known/agent-card.json",
auth=BearerTokenAuth(token="your-bearer-token"),
timeout=120
)
)
```
</Tab>
<Tab title="API Key">
```python Code
from crewai.a2a import A2AConfig
from crewai.a2a.auth import APIKeyAuth
agent = Agent(
role="API Coordinator",
goal="Coordinate with API-based agents",
backstory="Manages API-authenticated communications",
llm="gpt-4o",
a2a=A2AConfig(
endpoint="https://api-agent.example.com/.well-known/agent-card.json",
auth=APIKeyAuth(
api_key="your-api-key",
location="header", # or "query" or "cookie"
name="X-API-Key"
),
timeout=120
)
)
```
</Tab>
<Tab title="OAuth2">
```python Code
from crewai.a2a import A2AConfig
from crewai.a2a.auth import OAuth2ClientCredentials
agent = Agent(
role="OAuth Coordinator",
goal="Coordinate with OAuth-secured agents",
backstory="Manages OAuth-authenticated communications",
llm="gpt-4o",
a2a=A2AConfig(
endpoint="https://oauth-agent.example.com/.well-known/agent-card.json",
auth=OAuth2ClientCredentials(
token_url="https://auth.example.com/oauth/token",
client_id="your-client-id",
client_secret="your-client-secret",
scopes=["read", "write"]
),
timeout=120
)
)
```
</Tab>
<Tab title="HTTP Basic">
```python Code
from crewai.a2a import A2AConfig
from crewai.a2a.auth import HTTPBasicAuth
agent = Agent(
role="Basic Auth Coordinator",
goal="Coordinate with basic auth agents",
backstory="Manages basic authentication communications",
llm="gpt-4o",
a2a=A2AConfig(
endpoint="https://basic-agent.example.com/.well-known/agent-card.json",
auth=HTTPBasicAuth(
username="your-username",
password="your-password"
),
timeout=120
)
)
```
</Tab>
</Tabs>
## Multiple A2A Agents
Configure multiple A2A agents for delegation by passing a list:
```python Code
from crewai.a2a import A2AConfig
from crewai.a2a.auth import BearerTokenAuth
agent = Agent(
role="Multi-Agent Coordinator",
goal="Coordinate with multiple specialized agents",
backstory="Expert at delegating to the right specialist",
llm="gpt-4o",
a2a=[
A2AConfig(
endpoint="https://research.example.com/.well-known/agent-card.json",
timeout=120
),
A2AConfig(
endpoint="https://data.example.com/.well-known/agent-card.json",
auth=BearerTokenAuth(token="data-token"),
timeout=90
)
]
)
```
The LLM will automatically choose which A2A agent to delegate to based on the task requirements.
## Error Handling
Control how agent connection failures are handled using the `fail_fast` parameter:
```python Code
from crewai.a2a import A2AConfig
# Fail immediately on connection errors (default)
agent = Agent(
role="Research Coordinator",
goal="Coordinate research tasks",
backstory="Expert at delegation",
llm="gpt-4o",
a2a=A2AConfig(
endpoint="https://research.example.com/.well-known/agent-card.json",
fail_fast=True
)
)
# Continue with available agents
agent = Agent(
role="Multi-Agent Coordinator",
goal="Coordinate with multiple agents",
backstory="Expert at working with available resources",
llm="gpt-4o",
a2a=[
A2AConfig(
endpoint="https://primary.example.com/.well-known/agent-card.json",
fail_fast=False
),
A2AConfig(
endpoint="https://backup.example.com/.well-known/agent-card.json",
fail_fast=False
)
]
)
```
When `fail_fast=False`:
- If some agents fail, the LLM is informed which agents are unavailable and can delegate to working agents
- If all agents fail, the LLM receives a notice about unavailable agents and handles the task directly
- Connection errors are captured and included in the context for better decision-making
## Best Practices
<CardGroup cols={2}>
<Card title="Set Appropriate Timeouts" icon="clock">
Configure timeouts based on expected A2A agent response times. Longer-running tasks may need higher timeout values.
</Card>
<Card title="Limit Conversation Turns" icon="comments">
Use `max_turns` to prevent excessive back-and-forth. The agent will automatically conclude conversations before hitting the limit.
</Card>
<Card title="Use Resilient Error Handling" icon="shield-check">
Set `fail_fast=False` for production environments with multiple agents to gracefully handle connection failures and maintain workflow continuity.
</Card>
<Card title="Secure Your Credentials" icon="lock">
Store authentication tokens and credentials as environment variables, not in code.
</Card>
<Card title="Monitor Delegation Decisions" icon="eye">
Use verbose mode to observe when the LLM chooses to delegate versus handle tasks directly.
</Card>
</CardGroup>
## Supported Authentication Methods
- **Bearer Token** - Simple token-based authentication
- **OAuth2 Client Credentials** - OAuth2 flow for machine-to-machine communication
- **OAuth2 Authorization Code** - OAuth2 flow requiring user authorization
- **API Key** - Key-based authentication (header, query param, or cookie)
- **HTTP Basic** - Username/password authentication
- **HTTP Digest** - Digest authentication (requires `httpx-auth` package)
## Learn More
For more information about the A2A protocol and reference implementations:
- [A2A Protocol Documentation](https://a2a-protocol.org)
- [A2A Sample Implementations](https://github.com/a2aproject/a2a-samples)
- [A2A Python SDK](https://github.com/a2aproject/a2a-python)

View File

@@ -66,5 +66,55 @@ def my_cache_strategy(arguments: dict, result: str) -> bool:
cached_tool.cache_function = my_cache_strategy
```
### Creating Async Tools
CrewAI supports async tools for non-blocking I/O operations. This is useful when your tool needs to make HTTP requests, database queries, or other I/O-bound operations.
#### Using the `@tool` Decorator with Async Functions
The simplest way to create an async tool is using the `@tool` decorator with an async function:
```python Code
import aiohttp
from crewai.tools import tool
@tool("Async Web Fetcher")
async def fetch_webpage(url: str) -> str:
"""Fetch content from a webpage asynchronously."""
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return await response.text()
```
#### Subclassing `BaseTool` with Async Support
For more control, subclass `BaseTool` and implement both `_run` (sync) and `_arun` (async) methods:
```python Code
import requests
import aiohttp
from crewai.tools import BaseTool
from pydantic import BaseModel, Field
class WebFetcherInput(BaseModel):
"""Input schema for WebFetcher."""
url: str = Field(..., description="The URL to fetch")
class WebFetcherTool(BaseTool):
name: str = "Web Fetcher"
description: str = "Fetches content from a URL"
args_schema: type[BaseModel] = WebFetcherInput
def _run(self, url: str) -> str:
"""Synchronous implementation."""
return requests.get(url).text
async def _arun(self, url: str) -> str:
"""Asynchronous implementation for non-blocking I/O."""
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return await response.text()
```
By adhering to these guidelines and incorporating new functionalities and collaboration tools into your tool creation and management processes,
you can leverage the full capabilities of the CrewAI framework, enhancing both the development experience and the efficiency of your AI agents.

View File

@@ -0,0 +1,522 @@
---
title: Execution Hooks Overview
description: Understanding and using execution hooks in CrewAI for fine-grained control over agent operations
mode: "wide"
---
Execution Hooks provide fine-grained control over the runtime behavior of your CrewAI agents. Unlike kickoff hooks that run before and after crew execution, execution hooks intercept specific operations during agent execution, allowing you to modify behavior, implement safety checks, and add comprehensive monitoring.
## Types of Execution Hooks
CrewAI provides two main categories of execution hooks:
### 1. [LLM Call Hooks](/learn/llm-hooks)
Control and monitor language model interactions:
- **Before LLM Call**: Modify prompts, validate inputs, implement approval gates
- **After LLM Call**: Transform responses, sanitize outputs, update conversation history
**Use Cases:**
- Iteration limiting
- Cost tracking and token usage monitoring
- Response sanitization and content filtering
- Human-in-the-loop approval for LLM calls
- Adding safety guidelines or context
- Debug logging and request/response inspection
[View LLM Hooks Documentation →](/learn/llm-hooks)
### 2. [Tool Call Hooks](/learn/tool-hooks)
Control and monitor tool execution:
- **Before Tool Call**: Modify inputs, validate parameters, block dangerous operations
- **After Tool Call**: Transform results, sanitize outputs, log execution details
**Use Cases:**
- Safety guardrails for destructive operations
- Human approval for sensitive actions
- Input validation and sanitization
- Result caching and rate limiting
- Tool usage analytics
- Debug logging and monitoring
[View Tool Hooks Documentation →](/learn/tool-hooks)
## Hook Registration Methods
### 1. Decorator-Based Hooks (Recommended)
The cleanest and most Pythonic way to register hooks:
```python
from crewai.hooks import before_llm_call, after_llm_call, before_tool_call, after_tool_call
@before_llm_call
def limit_iterations(context):
"""Prevent infinite loops by limiting iterations."""
if context.iterations > 10:
return False # Block execution
return None
@after_llm_call
def sanitize_response(context):
"""Remove sensitive data from LLM responses."""
if "API_KEY" in context.response:
return context.response.replace("API_KEY", "[REDACTED]")
return None
@before_tool_call
def block_dangerous_tools(context):
"""Block destructive operations."""
if context.tool_name == "delete_database":
return False # Block execution
return None
@after_tool_call
def log_tool_result(context):
"""Log tool execution."""
print(f"Tool {context.tool_name} completed")
return None
```
### 2. Crew-Scoped Hooks
Apply hooks only to specific crew instances:
```python
from crewai import CrewBase
from crewai.project import crew
from crewai.hooks import before_llm_call_crew, after_tool_call_crew
@CrewBase
class MyProjCrew:
@before_llm_call_crew
def validate_inputs(self, context):
# Only applies to this crew
print(f"LLM call in {self.__class__.__name__}")
return None
@after_tool_call_crew
def log_results(self, context):
# Crew-specific logging
print(f"Tool result: {context.tool_result[:50]}...")
return None
@crew
def crew(self) -> Crew:
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential
)
```
## Hook Execution Flow
### LLM Call Flow
```
Agent needs to call LLM
[Before LLM Call Hooks Execute]
├→ Hook 1: Validate iteration count
├→ Hook 2: Add safety context
└→ Hook 3: Log request
If any hook returns False:
├→ Block LLM call
└→ Raise ValueError
If all hooks return True/None:
├→ LLM call proceeds
└→ Response generated
[After LLM Call Hooks Execute]
├→ Hook 1: Sanitize response
├→ Hook 2: Log response
└→ Hook 3: Update metrics
Final response returned
```
### Tool Call Flow
```
Agent needs to execute tool
[Before Tool Call Hooks Execute]
├→ Hook 1: Check if tool is allowed
├→ Hook 2: Validate inputs
└→ Hook 3: Request approval if needed
If any hook returns False:
├→ Block tool execution
└→ Return error message
If all hooks return True/None:
├→ Tool execution proceeds
└→ Result generated
[After Tool Call Hooks Execute]
├→ Hook 1: Sanitize result
├→ Hook 2: Cache result
└→ Hook 3: Log metrics
Final result returned
```
## Hook Context Objects
### LLMCallHookContext
Provides access to LLM execution state:
```python
class LLMCallHookContext:
executor: CrewAgentExecutor # Full executor access
messages: list # Mutable message list
agent: Agent # Current agent
task: Task # Current task
crew: Crew # Crew instance
llm: BaseLLM # LLM instance
iterations: int # Current iteration
response: str | None # LLM response (after hooks)
```
### ToolCallHookContext
Provides access to tool execution state:
```python
class ToolCallHookContext:
tool_name: str # Tool being called
tool_input: dict # Mutable input parameters
tool: CrewStructuredTool # Tool instance
agent: Agent | None # Agent executing
task: Task | None # Current task
crew: Crew | None # Crew instance
tool_result: str | None # Tool result (after hooks)
```
## Common Patterns
### Safety and Validation
```python
@before_tool_call
def safety_check(context):
"""Block destructive operations."""
dangerous = ['delete_file', 'drop_table', 'system_shutdown']
if context.tool_name in dangerous:
print(f"🛑 Blocked: {context.tool_name}")
return False
return None
@before_llm_call
def iteration_limit(context):
"""Prevent infinite loops."""
if context.iterations > 15:
print("⛔ Maximum iterations exceeded")
return False
return None
```
### Human-in-the-Loop
```python
@before_tool_call
def require_approval(context):
"""Require approval for sensitive operations."""
sensitive = ['send_email', 'make_payment', 'post_message']
if context.tool_name in sensitive:
response = context.request_human_input(
prompt=f"Approve {context.tool_name}?",
default_message="Type 'yes' to approve:"
)
if response.lower() != 'yes':
return False
return None
```
### Monitoring and Analytics
```python
from collections import defaultdict
import time
metrics = defaultdict(lambda: {'count': 0, 'total_time': 0})
@before_tool_call
def start_timer(context):
context.tool_input['_start'] = time.time()
return None
@after_tool_call
def track_metrics(context):
start = context.tool_input.get('_start', time.time())
duration = time.time() - start
metrics[context.tool_name]['count'] += 1
metrics[context.tool_name]['total_time'] += duration
return None
# View metrics
def print_metrics():
for tool, data in metrics.items():
avg = data['total_time'] / data['count']
print(f"{tool}: {data['count']} calls, {avg:.2f}s avg")
```
### Response Sanitization
```python
import re
@after_llm_call
def sanitize_llm_response(context):
"""Remove sensitive data from LLM responses."""
if not context.response:
return None
result = context.response
result = re.sub(r'(api[_-]?key)["\']?\s*[:=]\s*["\']?[\w-]+',
r'\1: [REDACTED]', result, flags=re.IGNORECASE)
return result
@after_tool_call
def sanitize_tool_result(context):
"""Remove sensitive data from tool results."""
if not context.tool_result:
return None
result = context.tool_result
result = re.sub(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b',
'[EMAIL-REDACTED]', result)
return result
```
## Hook Management
### Clearing All Hooks
```python
from crewai.hooks import clear_all_global_hooks
# Clear all hooks at once
result = clear_all_global_hooks()
print(f"Cleared {result['total']} hooks")
# Output: {'llm_hooks': (2, 1), 'tool_hooks': (1, 2), 'total': (3, 3)}
```
### Clearing Specific Hook Types
```python
from crewai.hooks import (
clear_before_llm_call_hooks,
clear_after_llm_call_hooks,
clear_before_tool_call_hooks,
clear_after_tool_call_hooks
)
# Clear specific types
llm_before_count = clear_before_llm_call_hooks()
tool_after_count = clear_after_tool_call_hooks()
```
### Unregistering Individual Hooks
```python
from crewai.hooks import (
unregister_before_llm_call_hook,
unregister_after_tool_call_hook
)
def my_hook(context):
...
# Register
register_before_llm_call_hook(my_hook)
# Later, unregister
success = unregister_before_llm_call_hook(my_hook)
print(f"Unregistered: {success}")
```
## Best Practices
### 1. Keep Hooks Focused
Each hook should have a single, clear responsibility:
```python
# ✅ Good - focused responsibility
@before_tool_call
def validate_file_path(context):
if context.tool_name == 'read_file':
if '..' in context.tool_input.get('path', ''):
return False
return None
# ❌ Bad - too many responsibilities
@before_tool_call
def do_everything(context):
# Validation + logging + metrics + approval...
...
```
### 2. Handle Errors Gracefully
```python
@before_llm_call
def safe_hook(context):
try:
# Your logic
if some_condition:
return False
except Exception as e:
print(f"Hook error: {e}")
return None # Allow execution despite error
```
### 3. Modify Context In-Place
```python
# ✅ Correct - modify in-place
@before_llm_call
def add_context(context):
context.messages.append({"role": "system", "content": "Be concise"})
# ❌ Wrong - replaces reference
@before_llm_call
def wrong_approach(context):
context.messages = [{"role": "system", "content": "Be concise"}]
```
### 4. Use Type Hints
```python
from crewai.hooks import LLMCallHookContext, ToolCallHookContext
def my_llm_hook(context: LLMCallHookContext) -> bool | None:
# IDE autocomplete and type checking
return None
def my_tool_hook(context: ToolCallHookContext) -> str | None:
return None
```
### 5. Clean Up in Tests
```python
import pytest
from crewai.hooks import clear_all_global_hooks
@pytest.fixture(autouse=True)
def clean_hooks():
"""Reset hooks before each test."""
yield
clear_all_global_hooks()
```
## When to Use Which Hook
### Use LLM Hooks When:
- Implementing iteration limits
- Adding context or safety guidelines to prompts
- Tracking token usage and costs
- Sanitizing or transforming responses
- Implementing approval gates for LLM calls
- Debugging prompt/response interactions
### Use Tool Hooks When:
- Blocking dangerous or destructive operations
- Validating tool inputs before execution
- Implementing approval gates for sensitive actions
- Caching tool results
- Tracking tool usage and performance
- Sanitizing tool outputs
- Rate limiting tool calls
### Use Both When:
Building comprehensive observability, safety, or approval systems that need to monitor all agent operations.
## Alternative Registration Methods
### Programmatic Registration (Advanced)
For dynamic hook registration or when you need to register hooks programmatically:
```python
from crewai.hooks import (
register_before_llm_call_hook,
register_after_tool_call_hook
)
def my_hook(context):
return None
# Register programmatically
register_before_llm_call_hook(my_hook)
# Useful for:
# - Loading hooks from configuration
# - Conditional hook registration
# - Plugin systems
```
**Note:** For most use cases, decorators are cleaner and more maintainable.
## Performance Considerations
1. **Keep Hooks Fast**: Hooks execute on every call - avoid heavy computation
2. **Cache When Possible**: Store expensive validations or lookups
3. **Be Selective**: Use crew-scoped hooks when global hooks aren't needed
4. **Monitor Hook Overhead**: Profile hook execution time in production
5. **Lazy Import**: Import heavy dependencies only when needed
## Debugging Hooks
### Enable Debug Logging
```python
import logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
@before_llm_call
def debug_hook(context):
logger.debug(f"LLM call: {context.agent.role}, iteration {context.iterations}")
return None
```
### Hook Execution Order
Hooks execute in registration order. If a before hook returns `False`, subsequent hooks don't execute:
```python
# Register order matters!
register_before_tool_call_hook(hook1) # Executes first
register_before_tool_call_hook(hook2) # Executes second
register_before_tool_call_hook(hook3) # Executes third
# If hook2 returns False:
# - hook1 executed
# - hook2 executed and returned False
# - hook3 NOT executed
# - Tool call blocked
```
## Related Documentation
- [LLM Call Hooks →](/learn/llm-hooks) - Detailed LLM hook documentation
- [Tool Call Hooks →](/learn/tool-hooks) - Detailed tool hook documentation
- [Before and After Kickoff Hooks →](/learn/before-and-after-kickoff-hooks) - Crew lifecycle hooks
- [Human-in-the-Loop →](/learn/human-in-the-loop) - Human input patterns
## Conclusion
Execution hooks provide powerful control over agent runtime behavior. Use them to implement safety guardrails, approval workflows, comprehensive monitoring, and custom business logic. Combined with proper error handling, type safety, and performance considerations, hooks enable production-ready, secure, and observable agent systems.

View File

@@ -97,7 +97,7 @@ project_crew = Crew(
```
<Tip>
For more details on creating and customizing a manager agent, check out the [Custom Manager Agent documentation](https://docs.crewai.com/how-to/custom-manager-agent#custom-manager-agent).
For more details on creating and customizing a manager agent, check out the [Custom Manager Agent documentation](/en/learn/custom-manager-agent).
</Tip>

View File

@@ -7,17 +7,28 @@ mode: "wide"
## Introduction
CrewAI provides the ability to kickoff a crew asynchronously, allowing you to start the crew execution in a non-blocking manner.
CrewAI provides the ability to kickoff a crew asynchronously, allowing you to start the crew execution in a non-blocking manner.
This feature is particularly useful when you want to run multiple crews concurrently or when you need to perform other tasks while the crew is executing.
## Asynchronous Crew Execution
CrewAI offers two approaches for async execution:
To kickoff a crew asynchronously, use the `kickoff_async()` method. This method initiates the crew execution in a separate thread, allowing the main thread to continue executing other tasks.
| Method | Type | Description |
|--------|------|-------------|
| `akickoff()` | Native async | True async/await throughout the entire execution chain |
| `kickoff_async()` | Thread-based | Wraps synchronous execution in `asyncio.to_thread` |
<Note>
For high-concurrency workloads, `akickoff()` is recommended as it uses native async for task execution, memory operations, and knowledge retrieval.
</Note>
## Native Async Execution with `akickoff()`
The `akickoff()` method provides true native async execution, using async/await throughout the entire execution chain including task execution, memory operations, and knowledge queries.
### Method Signature
```python Code
def kickoff_async(self, inputs: dict) -> CrewOutput:
async def akickoff(self, inputs: dict) -> CrewOutput:
```
### Parameters
@@ -28,23 +39,13 @@ def kickoff_async(self, inputs: dict) -> CrewOutput:
- `CrewOutput`: An object representing the result of the crew execution.
## Potential Use Cases
- **Parallel Content Generation**: Kickoff multiple independent crews asynchronously, each responsible for generating content on different topics. For example, one crew might research and draft an article on AI trends, while another crew generates social media posts about a new product launch. Each crew operates independently, allowing content production to scale efficiently.
- **Concurrent Market Research Tasks**: Launch multiple crews asynchronously to conduct market research in parallel. One crew might analyze industry trends, while another examines competitor strategies, and yet another evaluates consumer sentiment. Each crew independently completes its task, enabling faster and more comprehensive insights.
- **Independent Travel Planning Modules**: Execute separate crews to independently plan different aspects of a trip. One crew might handle flight options, another handles accommodation, and a third plans activities. Each crew works asynchronously, allowing various components of the trip to be planned simultaneously and independently for faster results.
## Example: Single Asynchronous Crew Execution
Here's an example of how to kickoff a crew asynchronously using asyncio and awaiting the result:
### Example: Native Async Crew Execution
```python Code
import asyncio
from crewai import Crew, Agent, Task
# Create an agent with code execution enabled
# Create an agent
coding_agent = Agent(
role="Python Data Analyst",
goal="Analyze data and provide insights using Python",
@@ -52,37 +53,165 @@ coding_agent = Agent(
allow_code_execution=True
)
# Create a task that requires code execution
# Create a task
data_analysis_task = Task(
description="Analyze the given dataset and calculate the average age of participants. Ages: {ages}",
agent=coding_agent,
expected_output="The average age of the participants."
)
# Create a crew and add the task
# Create a crew
analysis_crew = Crew(
agents=[coding_agent],
tasks=[data_analysis_task]
)
# Async function to kickoff the crew asynchronously
async def async_crew_execution():
result = await analysis_crew.kickoff_async(inputs={"ages": [25, 30, 35, 40, 45]})
# Native async execution
async def main():
result = await analysis_crew.akickoff(inputs={"ages": [25, 30, 35, 40, 45]})
print("Crew Result:", result)
# Run the async function
asyncio.run(async_crew_execution())
asyncio.run(main())
```
## Example: Multiple Asynchronous Crew Executions
### Example: Multiple Native Async Crews
In this example, we'll show how to kickoff multiple crews asynchronously and wait for all of them to complete using `asyncio.gather()`:
Run multiple crews concurrently using `asyncio.gather()` with native async:
```python Code
import asyncio
from crewai import Crew, Agent, Task
coding_agent = Agent(
role="Python Data Analyst",
goal="Analyze data and provide insights using Python",
backstory="You are an experienced data analyst with strong Python skills.",
allow_code_execution=True
)
task_1 = Task(
description="Analyze the first dataset and calculate the average age. Ages: {ages}",
agent=coding_agent,
expected_output="The average age of the participants."
)
task_2 = Task(
description="Analyze the second dataset and calculate the average age. Ages: {ages}",
agent=coding_agent,
expected_output="The average age of the participants."
)
crew_1 = Crew(agents=[coding_agent], tasks=[task_1])
crew_2 = Crew(agents=[coding_agent], tasks=[task_2])
async def main():
results = await asyncio.gather(
crew_1.akickoff(inputs={"ages": [25, 30, 35, 40, 45]}),
crew_2.akickoff(inputs={"ages": [20, 22, 24, 28, 30]})
)
for i, result in enumerate(results, 1):
print(f"Crew {i} Result:", result)
asyncio.run(main())
```
### Example: Native Async for Multiple Inputs
Use `akickoff_for_each()` to execute your crew against multiple inputs concurrently with native async:
```python Code
import asyncio
from crewai import Crew, Agent, Task
coding_agent = Agent(
role="Python Data Analyst",
goal="Analyze data and provide insights using Python",
backstory="You are an experienced data analyst with strong Python skills.",
allow_code_execution=True
)
data_analysis_task = Task(
description="Analyze the dataset and calculate the average age. Ages: {ages}",
agent=coding_agent,
expected_output="The average age of the participants."
)
analysis_crew = Crew(
agents=[coding_agent],
tasks=[data_analysis_task]
)
async def main():
datasets = [
{"ages": [25, 30, 35, 40, 45]},
{"ages": [20, 22, 24, 28, 30]},
{"ages": [30, 35, 40, 45, 50]}
]
results = await analysis_crew.akickoff_for_each(datasets)
for i, result in enumerate(results, 1):
print(f"Dataset {i} Result:", result)
asyncio.run(main())
```
## Thread-Based Async with `kickoff_async()`
The `kickoff_async()` method provides async execution by wrapping the synchronous `kickoff()` in a thread. This is useful for simpler async integration or backward compatibility.
### Method Signature
```python Code
async def kickoff_async(self, inputs: dict) -> CrewOutput:
```
### Parameters
- `inputs` (dict): A dictionary containing the input data required for the tasks.
### Returns
- `CrewOutput`: An object representing the result of the crew execution.
### Example: Thread-Based Async Execution
```python Code
import asyncio
from crewai import Crew, Agent, Task
coding_agent = Agent(
role="Python Data Analyst",
goal="Analyze data and provide insights using Python",
backstory="You are an experienced data analyst with strong Python skills.",
allow_code_execution=True
)
data_analysis_task = Task(
description="Analyze the given dataset and calculate the average age of participants. Ages: {ages}",
agent=coding_agent,
expected_output="The average age of the participants."
)
analysis_crew = Crew(
agents=[coding_agent],
tasks=[data_analysis_task]
)
async def async_crew_execution():
result = await analysis_crew.kickoff_async(inputs={"ages": [25, 30, 35, 40, 45]})
print("Crew Result:", result)
asyncio.run(async_crew_execution())
```
### Example: Multiple Thread-Based Async Crews
```python Code
import asyncio
from crewai import Crew, Agent, Task
# Create an agent with code execution enabled
coding_agent = Agent(
role="Python Data Analyst",
goal="Analyze data and provide insights using Python",
@@ -90,7 +219,6 @@ coding_agent = Agent(
allow_code_execution=True
)
# Create tasks that require code execution
task_1 = Task(
description="Analyze the first dataset and calculate the average age of participants. Ages: {ages}",
agent=coding_agent,
@@ -103,22 +231,76 @@ task_2 = Task(
expected_output="The average age of the participants."
)
# Create two crews and add tasks
crew_1 = Crew(agents=[coding_agent], tasks=[task_1])
crew_2 = Crew(agents=[coding_agent], tasks=[task_2])
# Async function to kickoff multiple crews asynchronously and wait for all to finish
async def async_multiple_crews():
# Create coroutines for concurrent execution
result_1 = crew_1.kickoff_async(inputs={"ages": [25, 30, 35, 40, 45]})
result_2 = crew_2.kickoff_async(inputs={"ages": [20, 22, 24, 28, 30]})
# Wait for both crews to finish
results = await asyncio.gather(result_1, result_2)
for i, result in enumerate(results, 1):
print(f"Crew {i} Result:", result)
# Run the async function
asyncio.run(async_multiple_crews())
```
## Async Streaming
Both async methods support streaming when `stream=True` is set on the crew:
```python Code
import asyncio
from crewai import Crew, Agent, Task
agent = Agent(
role="Researcher",
goal="Research and summarize topics",
backstory="You are an expert researcher."
)
task = Task(
description="Research the topic: {topic}",
agent=agent,
expected_output="A comprehensive summary of the topic."
)
crew = Crew(
agents=[agent],
tasks=[task],
stream=True # Enable streaming
)
async def main():
streaming_output = await crew.akickoff(inputs={"topic": "AI trends in 2024"})
# Async iteration over streaming chunks
async for chunk in streaming_output:
print(f"Chunk: {chunk.content}")
# Access final result after streaming completes
result = streaming_output.result
print(f"Final result: {result.raw}")
asyncio.run(main())
```
## Potential Use Cases
- **Parallel Content Generation**: Kickoff multiple independent crews asynchronously, each responsible for generating content on different topics. For example, one crew might research and draft an article on AI trends, while another crew generates social media posts about a new product launch.
- **Concurrent Market Research Tasks**: Launch multiple crews asynchronously to conduct market research in parallel. One crew might analyze industry trends, while another examines competitor strategies, and yet another evaluates consumer sentiment.
- **Independent Travel Planning Modules**: Execute separate crews to independently plan different aspects of a trip. One crew might handle flight options, another handles accommodation, and a third plans activities.
## Choosing Between `akickoff()` and `kickoff_async()`
| Feature | `akickoff()` | `kickoff_async()` |
|---------|--------------|-------------------|
| Execution model | Native async/await | Thread-based wrapper |
| Task execution | Async with `aexecute_sync()` | Sync in thread pool |
| Memory operations | Async | Sync in thread pool |
| Knowledge retrieval | Async | Sync in thread pool |
| Best for | High-concurrency, I/O-bound workloads | Simple async integration |
| Streaming support | Yes | Yes |

427
docs/en/learn/llm-hooks.mdx Normal file
View File

@@ -0,0 +1,427 @@
---
title: LLM Call Hooks
description: Learn how to use LLM call hooks to intercept, modify, and control language model interactions in CrewAI
mode: "wide"
---
LLM Call Hooks provide fine-grained control over language model interactions during agent execution. These hooks allow you to intercept LLM calls, modify prompts, transform responses, implement approval gates, and add custom logging or monitoring.
## Overview
LLM hooks are executed at two critical points:
- **Before LLM Call**: Modify messages, validate inputs, or block execution
- **After LLM Call**: Transform responses, sanitize outputs, or modify conversation history
## Hook Types
### Before LLM Call Hooks
Executed before every LLM call, these hooks can:
- Inspect and modify messages sent to the LLM
- Block LLM execution based on conditions
- Implement rate limiting or approval gates
- Add context or system messages
- Log request details
**Signature:**
```python
def before_hook(context: LLMCallHookContext) -> bool | None:
# Return False to block execution
# Return True or None to allow execution
...
```
### After LLM Call Hooks
Executed after every LLM call, these hooks can:
- Modify or sanitize LLM responses
- Add metadata or formatting
- Log response details
- Update conversation history
- Implement content filtering
**Signature:**
```python
def after_hook(context: LLMCallHookContext) -> str | None:
# Return modified response string
# Return None to keep original response
...
```
## LLM Hook Context
The `LLMCallHookContext` object provides comprehensive access to execution state:
```python
class LLMCallHookContext:
executor: CrewAgentExecutor # Full executor reference
messages: list # Mutable message list
agent: Agent # Current agent
task: Task # Current task
crew: Crew # Crew instance
llm: BaseLLM # LLM instance
iterations: int # Current iteration count
response: str | None # LLM response (after hooks only)
```
### Modifying Messages
**Important:** Always modify messages in-place:
```python
# ✅ Correct - modify in-place
def add_context(context: LLMCallHookContext) -> None:
context.messages.append({"role": "system", "content": "Be concise"})
# ❌ Wrong - replaces list reference
def wrong_approach(context: LLMCallHookContext) -> None:
context.messages = [{"role": "system", "content": "Be concise"}]
```
## Registration Methods
### 1. Global Hook Registration
Register hooks that apply to all LLM calls across all crews:
```python
from crewai.hooks import register_before_llm_call_hook, register_after_llm_call_hook
def log_llm_call(context):
print(f"LLM call by {context.agent.role} at iteration {context.iterations}")
return None # Allow execution
register_before_llm_call_hook(log_llm_call)
```
### 2. Decorator-Based Registration
Use decorators for cleaner syntax:
```python
from crewai.hooks import before_llm_call, after_llm_call
@before_llm_call
def validate_iteration_count(context):
if context.iterations > 10:
print("⚠️ Exceeded maximum iterations")
return False # Block execution
return None
@after_llm_call
def sanitize_response(context):
if context.response and "API_KEY" in context.response:
return context.response.replace("API_KEY", "[REDACTED]")
return None
```
### 3. Crew-Scoped Hooks
Register hooks for a specific crew instance:
```python
@CrewBase
class MyProjCrew:
@before_llm_call_crew
def validate_inputs(self, context):
# Only applies to this crew
if context.iterations == 0:
print(f"Starting task: {context.task.description}")
return None
@after_llm_call_crew
def log_responses(self, context):
# Crew-specific response logging
print(f"Response length: {len(context.response)}")
return None
@crew
def crew(self) -> Crew:
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True
)
```
## Common Use Cases
### 1. Iteration Limiting
```python
@before_llm_call
def limit_iterations(context: LLMCallHookContext) -> bool | None:
max_iterations = 15
if context.iterations > max_iterations:
print(f"⛔ Blocked: Exceeded {max_iterations} iterations")
return False # Block execution
return None
```
### 2. Human Approval Gate
```python
@before_llm_call
def require_approval(context: LLMCallHookContext) -> bool | None:
if context.iterations > 5:
response = context.request_human_input(
prompt=f"Iteration {context.iterations}: Approve LLM call?",
default_message="Press Enter to approve, or type 'no' to block:"
)
if response.lower() == "no":
print("🚫 LLM call blocked by user")
return False
return None
```
### 3. Adding System Context
```python
@before_llm_call
def add_guardrails(context: LLMCallHookContext) -> None:
# Add safety guidelines to every LLM call
context.messages.append({
"role": "system",
"content": "Ensure responses are factual and cite sources when possible."
})
return None
```
### 4. Response Sanitization
```python
@after_llm_call
def sanitize_sensitive_data(context: LLMCallHookContext) -> str | None:
if not context.response:
return None
# Remove sensitive patterns
import re
sanitized = context.response
sanitized = re.sub(r'\b\d{3}-\d{2}-\d{4}\b', '[SSN-REDACTED]', sanitized)
sanitized = re.sub(r'\b\d{4}[- ]?\d{4}[- ]?\d{4}[- ]?\d{4}\b', '[CARD-REDACTED]', sanitized)
return sanitized
```
### 5. Cost Tracking
```python
import tiktoken
@before_llm_call
def track_token_usage(context: LLMCallHookContext) -> None:
encoding = tiktoken.get_encoding("cl100k_base")
total_tokens = sum(
len(encoding.encode(msg.get("content", "")))
for msg in context.messages
)
print(f"📊 Input tokens: ~{total_tokens}")
return None
@after_llm_call
def track_response_tokens(context: LLMCallHookContext) -> None:
if context.response:
encoding = tiktoken.get_encoding("cl100k_base")
tokens = len(encoding.encode(context.response))
print(f"📊 Response tokens: ~{tokens}")
return None
```
### 6. Debug Logging
```python
@before_llm_call
def debug_request(context: LLMCallHookContext) -> None:
print(f"""
🔍 LLM Call Debug:
- Agent: {context.agent.role}
- Task: {context.task.description[:50]}...
- Iteration: {context.iterations}
- Message Count: {len(context.messages)}
- Last Message: {context.messages[-1] if context.messages else 'None'}
""")
return None
@after_llm_call
def debug_response(context: LLMCallHookContext) -> None:
if context.response:
print(f"✅ Response Preview: {context.response[:100]}...")
return None
```
## Hook Management
### Unregistering Hooks
```python
from crewai.hooks import (
unregister_before_llm_call_hook,
unregister_after_llm_call_hook
)
# Unregister specific hook
def my_hook(context):
...
register_before_llm_call_hook(my_hook)
# Later...
unregister_before_llm_call_hook(my_hook) # Returns True if found
```
### Clearing Hooks
```python
from crewai.hooks import (
clear_before_llm_call_hooks,
clear_after_llm_call_hooks,
clear_all_llm_call_hooks
)
# Clear specific hook type
count = clear_before_llm_call_hooks()
print(f"Cleared {count} before hooks")
# Clear all LLM hooks
before_count, after_count = clear_all_llm_call_hooks()
print(f"Cleared {before_count} before and {after_count} after hooks")
```
### Listing Registered Hooks
```python
from crewai.hooks import (
get_before_llm_call_hooks,
get_after_llm_call_hooks
)
# Get current hooks
before_hooks = get_before_llm_call_hooks()
after_hooks = get_after_llm_call_hooks()
print(f"Registered: {len(before_hooks)} before, {len(after_hooks)} after")
```
## Advanced Patterns
### Conditional Hook Execution
```python
@before_llm_call
def conditional_blocking(context: LLMCallHookContext) -> bool | None:
# Only block for specific agents
if context.agent.role == "researcher" and context.iterations > 10:
return False
# Only block for specific tasks
if "sensitive" in context.task.description.lower() and context.iterations > 5:
return False
return None
```
### Context-Aware Modifications
```python
@before_llm_call
def adaptive_prompting(context: LLMCallHookContext) -> None:
# Add different context based on iteration
if context.iterations == 0:
context.messages.append({
"role": "system",
"content": "Start with a high-level overview."
})
elif context.iterations > 3:
context.messages.append({
"role": "system",
"content": "Focus on specific details and provide examples."
})
return None
```
### Chaining Hooks
```python
# Multiple hooks execute in registration order
@before_llm_call
def first_hook(context):
print("1. First hook executed")
return None
@before_llm_call
def second_hook(context):
print("2. Second hook executed")
return None
@before_llm_call
def blocking_hook(context):
if context.iterations > 10:
print("3. Blocking hook - execution stopped")
return False # Subsequent hooks won't execute
print("3. Blocking hook - execution allowed")
return None
```
## Best Practices
1. **Keep Hooks Focused**: Each hook should have a single responsibility
2. **Avoid Heavy Computation**: Hooks execute on every LLM call
3. **Handle Errors Gracefully**: Use try-except to prevent hook failures from breaking execution
4. **Use Type Hints**: Leverage `LLMCallHookContext` for better IDE support
5. **Document Hook Behavior**: Especially for blocking conditions
6. **Test Hooks Independently**: Unit test hooks before using in production
7. **Clear Hooks in Tests**: Use `clear_all_llm_call_hooks()` between test runs
8. **Modify In-Place**: Always modify `context.messages` in-place, never replace
## Error Handling
```python
@before_llm_call
def safe_hook(context: LLMCallHookContext) -> bool | None:
try:
# Your hook logic
if some_condition:
return False
except Exception as e:
print(f"⚠️ Hook error: {e}")
# Decide: allow or block on error
return None # Allow execution despite error
```
## Type Safety
```python
from crewai.hooks import LLMCallHookContext, BeforeLLMCallHookType, AfterLLMCallHookType
# Explicit type annotations
def my_before_hook(context: LLMCallHookContext) -> bool | None:
return None
def my_after_hook(context: LLMCallHookContext) -> str | None:
return None
# Type-safe registration
register_before_llm_call_hook(my_before_hook)
register_after_llm_call_hook(my_after_hook)
```
## Troubleshooting
### Hook Not Executing
- Verify hook is registered before crew execution
- Check if previous hook returned `False` (blocks subsequent hooks)
- Ensure hook signature matches expected type
### Message Modifications Not Persisting
- Use in-place modifications: `context.messages.append()`
- Don't replace the list: `context.messages = []`
### Response Modifications Not Working
- Return the modified string from after hooks
- Returning `None` keeps the original response
## Conclusion
LLM Call Hooks provide powerful capabilities for controlling and monitoring language model interactions in CrewAI. Use them to implement safety guardrails, approval gates, logging, cost tracking, and response sanitization. Combined with proper error handling and type safety, hooks enable robust and production-ready agent systems.

View File

@@ -394,7 +394,7 @@ Rather than repeating the strategic framework, here's a tactical checklist for i
<Step title="Validate with Enterprise Testing" icon="test-tube">
**Once you deploy your agents to production:**
- Use [CrewAI AMP platform](https://app.crewai.com) to A/B test your model selections
- Use [CrewAI AOP platform](https://app.crewai.com) to A/B test your model selections
- Run multiple iterations with real inputs to measure consistency and performance
- Compare cost vs. performance across your optimized setup
- Share results with your team for collaborative decision-making
@@ -541,7 +541,7 @@ Focus on understanding your requirements first, then select models that best mat
### Enterprise-Grade Model Validation
For teams serious about optimizing their LLM selection, the **CrewAI AMP platform** provides sophisticated testing capabilities that go far beyond basic CLI testing. The platform enables comprehensive model evaluation that helps you make data-driven decisions about your LLM strategy.
For teams serious about optimizing their LLM selection, the **CrewAI AOP platform** provides sophisticated testing capabilities that go far beyond basic CLI testing. The platform enables comprehensive model evaluation that helps you make data-driven decisions about your LLM strategy.
<Frame>
![Enterprise Testing Interface](/images/enterprise/enterprise-testing.png)

View File

@@ -0,0 +1,356 @@
---
title: Streaming Crew Execution
description: Stream real-time output from your CrewAI crew execution
icon: wave-pulse
mode: "wide"
---
## Introduction
CrewAI provides the ability to stream real-time output during crew execution, allowing you to display results as they're generated rather than waiting for the entire process to complete. This feature is particularly useful for building interactive applications, providing user feedback, and monitoring long-running processes.
## How Streaming Works
When streaming is enabled, CrewAI captures LLM responses and tool calls as they happen, packaging them into structured chunks that include context about which task and agent is executing. You can iterate over these chunks in real-time and access the final result once execution completes.
## Enabling Streaming
To enable streaming, set the `stream` parameter to `True` when creating your crew:
```python Code
from crewai import Agent, Crew, Task
# Create your agents and tasks
researcher = Agent(
role="Research Analyst",
goal="Gather comprehensive information on topics",
backstory="You are an experienced researcher with excellent analytical skills.",
)
task = Task(
description="Research the latest developments in AI",
expected_output="A detailed report on recent AI advancements",
agent=researcher,
)
# Enable streaming
crew = Crew(
agents=[researcher],
tasks=[task],
stream=True # Enable streaming output
)
```
## Synchronous Streaming
When you call `kickoff()` on a crew with streaming enabled, it returns a `CrewStreamingOutput` object that you can iterate over to receive chunks as they arrive:
```python Code
# Start streaming execution
streaming = crew.kickoff(inputs={"topic": "artificial intelligence"})
# Iterate over chunks as they arrive
for chunk in streaming:
print(chunk.content, end="", flush=True)
# Access the final result after streaming completes
result = streaming.result
print(f"\n\nFinal output: {result.raw}")
```
### Stream Chunk Information
Each chunk provides rich context about the execution:
```python Code
streaming = crew.kickoff(inputs={"topic": "AI"})
for chunk in streaming:
print(f"Task: {chunk.task_name} (index {chunk.task_index})")
print(f"Agent: {chunk.agent_role}")
print(f"Content: {chunk.content}")
print(f"Type: {chunk.chunk_type}") # TEXT or TOOL_CALL
if chunk.tool_call:
print(f"Tool: {chunk.tool_call.tool_name}")
print(f"Arguments: {chunk.tool_call.arguments}")
```
### Accessing Streaming Results
The `CrewStreamingOutput` object provides several useful properties:
```python Code
streaming = crew.kickoff(inputs={"topic": "AI"})
# Iterate and collect chunks
for chunk in streaming:
print(chunk.content, end="", flush=True)
# After iteration completes
print(f"\nCompleted: {streaming.is_completed}")
print(f"Full text: {streaming.get_full_text()}")
print(f"All chunks: {len(streaming.chunks)}")
print(f"Final result: {streaming.result.raw}")
```
## Asynchronous Streaming
For async applications, you can use either `akickoff()` (native async) or `kickoff_async()` (thread-based) with async iteration:
### Native Async with `akickoff()`
The `akickoff()` method provides true native async execution throughout the entire chain:
```python Code
import asyncio
async def stream_crew():
crew = Crew(
agents=[researcher],
tasks=[task],
stream=True
)
# Start native async streaming
streaming = await crew.akickoff(inputs={"topic": "AI"})
# Async iteration over chunks
async for chunk in streaming:
print(chunk.content, end="", flush=True)
# Access final result
result = streaming.result
print(f"\n\nFinal output: {result.raw}")
asyncio.run(stream_crew())
```
### Thread-Based Async with `kickoff_async()`
For simpler async integration or backward compatibility:
```python Code
import asyncio
async def stream_crew():
crew = Crew(
agents=[researcher],
tasks=[task],
stream=True
)
# Start thread-based async streaming
streaming = await crew.kickoff_async(inputs={"topic": "AI"})
# Async iteration over chunks
async for chunk in streaming:
print(chunk.content, end="", flush=True)
# Access final result
result = streaming.result
print(f"\n\nFinal output: {result.raw}")
asyncio.run(stream_crew())
```
<Note>
For high-concurrency workloads, `akickoff()` is recommended as it uses native async for task execution, memory operations, and knowledge retrieval. See the [Kickoff Crew Asynchronously](/en/learn/kickoff-async) guide for more details.
</Note>
## Streaming with kickoff_for_each
When executing a crew for multiple inputs with `kickoff_for_each()`, streaming works differently depending on whether you use sync or async:
### Synchronous kickoff_for_each
With synchronous `kickoff_for_each()`, you get a list of `CrewStreamingOutput` objects, one for each input:
```python Code
crew = Crew(
agents=[researcher],
tasks=[task],
stream=True
)
inputs_list = [
{"topic": "AI in healthcare"},
{"topic": "AI in finance"}
]
# Returns list of streaming outputs
streaming_outputs = crew.kickoff_for_each(inputs=inputs_list)
# Iterate over each streaming output
for i, streaming in enumerate(streaming_outputs):
print(f"\n=== Input {i + 1} ===")
for chunk in streaming:
print(chunk.content, end="", flush=True)
result = streaming.result
print(f"\n\nResult {i + 1}: {result.raw}")
```
### Asynchronous kickoff_for_each_async
With async `kickoff_for_each_async()`, you get a single `CrewStreamingOutput` that yields chunks from all crews as they arrive concurrently:
```python Code
import asyncio
async def stream_multiple_crews():
crew = Crew(
agents=[researcher],
tasks=[task],
stream=True
)
inputs_list = [
{"topic": "AI in healthcare"},
{"topic": "AI in finance"}
]
# Returns single streaming output for all crews
streaming = await crew.kickoff_for_each_async(inputs=inputs_list)
# Chunks from all crews arrive as they're generated
async for chunk in streaming:
print(f"[{chunk.task_name}] {chunk.content}", end="", flush=True)
# Access all results
results = streaming.results # List of CrewOutput objects
for i, result in enumerate(results):
print(f"\n\nResult {i + 1}: {result.raw}")
asyncio.run(stream_multiple_crews())
```
## Stream Chunk Types
Chunks can be of different types, indicated by the `chunk_type` field:
### TEXT Chunks
Standard text content from LLM responses:
```python Code
for chunk in streaming:
if chunk.chunk_type == StreamChunkType.TEXT:
print(chunk.content, end="", flush=True)
```
### TOOL_CALL Chunks
Information about tool calls being made:
```python Code
for chunk in streaming:
if chunk.chunk_type == StreamChunkType.TOOL_CALL:
print(f"\nCalling tool: {chunk.tool_call.tool_name}")
print(f"Arguments: {chunk.tool_call.arguments}")
```
## Practical Example: Building a UI with Streaming
Here's a complete example showing how to build an interactive application with streaming:
```python Code
import asyncio
from crewai import Agent, Crew, Task
from crewai.types.streaming import StreamChunkType
async def interactive_research():
# Create crew with streaming enabled
researcher = Agent(
role="Research Analyst",
goal="Provide detailed analysis on any topic",
backstory="You are an expert researcher with broad knowledge.",
)
task = Task(
description="Research and analyze: {topic}",
expected_output="A comprehensive analysis with key insights",
agent=researcher,
)
crew = Crew(
agents=[researcher],
tasks=[task],
stream=True,
verbose=False
)
# Get user input
topic = input("Enter a topic to research: ")
print(f"\n{'='*60}")
print(f"Researching: {topic}")
print(f"{'='*60}\n")
# Start streaming execution
streaming = await crew.kickoff_async(inputs={"topic": topic})
current_task = ""
async for chunk in streaming:
# Show task transitions
if chunk.task_name != current_task:
current_task = chunk.task_name
print(f"\n[{chunk.agent_role}] Working on: {chunk.task_name}")
print("-" * 60)
# Display text chunks
if chunk.chunk_type == StreamChunkType.TEXT:
print(chunk.content, end="", flush=True)
# Display tool calls
elif chunk.chunk_type == StreamChunkType.TOOL_CALL and chunk.tool_call:
print(f"\n🔧 Using tool: {chunk.tool_call.tool_name}")
# Show final result
result = streaming.result
print(f"\n\n{'='*60}")
print("Analysis Complete!")
print(f"{'='*60}")
print(f"\nToken Usage: {result.token_usage}")
asyncio.run(interactive_research())
```
## Use Cases
Streaming is particularly valuable for:
- **Interactive Applications**: Provide real-time feedback to users as agents work
- **Long-Running Tasks**: Show progress for research, analysis, or content generation
- **Debugging and Monitoring**: Observe agent behavior and decision-making in real-time
- **User Experience**: Reduce perceived latency by showing incremental results
- **Live Dashboards**: Build monitoring interfaces that display crew execution status
## Important Notes
- Streaming automatically enables LLM streaming for all agents in the crew
- You must iterate through all chunks before accessing the `.result` property
- For `kickoff_for_each_async()` with streaming, use `.results` (plural) to get all outputs
- Streaming adds minimal overhead and can actually improve perceived performance
- Each chunk includes full context (task, agent, chunk type) for rich UIs
## Error Handling
Handle errors during streaming execution:
```python Code
streaming = crew.kickoff(inputs={"topic": "AI"})
try:
for chunk in streaming:
print(chunk.content, end="", flush=True)
result = streaming.result
print(f"\nSuccess: {result.raw}")
except Exception as e:
print(f"\nError during streaming: {e}")
if streaming.is_completed:
print("Streaming completed but an error occurred")
```
By leveraging streaming, you can build more responsive and interactive applications with CrewAI, providing users with real-time visibility into agent execution and results.

View File

@@ -0,0 +1,450 @@
---
title: Streaming Flow Execution
description: Stream real-time output from your CrewAI flow execution
icon: wave-pulse
mode: "wide"
---
## Introduction
CrewAI Flows support streaming output, allowing you to receive real-time updates as your flow executes. This feature enables you to build responsive applications that display results incrementally, provide live progress updates, and create better user experiences for long-running workflows.
## How Flow Streaming Works
When streaming is enabled on a Flow, CrewAI captures and streams output from any crews or LLM calls within the flow. The stream delivers structured chunks containing the content, task context, and agent information as execution progresses.
## Enabling Streaming
To enable streaming, set the `stream` attribute to `True` on your Flow class:
```python Code
from crewai.flow.flow import Flow, listen, start
from crewai import Agent, Crew, Task
class ResearchFlow(Flow):
stream = True # Enable streaming for the entire flow
@start()
def initialize(self):
return {"topic": "AI trends"}
@listen(initialize)
def research_topic(self, data):
researcher = Agent(
role="Research Analyst",
goal="Research topics thoroughly",
backstory="Expert researcher with analytical skills",
)
task = Task(
description="Research {topic} and provide insights",
expected_output="Detailed research findings",
agent=researcher,
)
crew = Crew(
agents=[researcher],
tasks=[task],
)
return crew.kickoff(inputs=data)
```
## Synchronous Streaming
When you call `kickoff()` on a flow with streaming enabled, it returns a `FlowStreamingOutput` object that you can iterate over:
```python Code
flow = ResearchFlow()
# Start streaming execution
streaming = flow.kickoff()
# Iterate over chunks as they arrive
for chunk in streaming:
print(chunk.content, end="", flush=True)
# Access the final result after streaming completes
result = streaming.result
print(f"\n\nFinal output: {result}")
```
### Stream Chunk Information
Each chunk provides context about where it originated in the flow:
```python Code
streaming = flow.kickoff()
for chunk in streaming:
print(f"Agent: {chunk.agent_role}")
print(f"Task: {chunk.task_name}")
print(f"Content: {chunk.content}")
print(f"Type: {chunk.chunk_type}") # TEXT or TOOL_CALL
```
### Accessing Streaming Properties
The `FlowStreamingOutput` object provides useful properties and methods:
```python Code
streaming = flow.kickoff()
# Iterate and collect chunks
for chunk in streaming:
print(chunk.content, end="", flush=True)
# After iteration completes
print(f"\nCompleted: {streaming.is_completed}")
print(f"Full text: {streaming.get_full_text()}")
print(f"Total chunks: {len(streaming.chunks)}")
print(f"Final result: {streaming.result}")
```
## Asynchronous Streaming
For async applications, use `kickoff_async()` with async iteration:
```python Code
import asyncio
async def stream_flow():
flow = ResearchFlow()
# Start async streaming
streaming = await flow.kickoff_async()
# Async iteration over chunks
async for chunk in streaming:
print(chunk.content, end="", flush=True)
# Access final result
result = streaming.result
print(f"\n\nFinal output: {result}")
asyncio.run(stream_flow())
```
## Streaming with Multi-Step Flows
Streaming works seamlessly across multiple flow steps, including flows that execute multiple crews:
```python Code
from crewai.flow.flow import Flow, listen, start
from crewai import Agent, Crew, Task
class MultiStepFlow(Flow):
stream = True
@start()
def research_phase(self):
"""First crew: Research the topic."""
researcher = Agent(
role="Research Analyst",
goal="Gather comprehensive information",
backstory="Expert at finding relevant information",
)
task = Task(
description="Research AI developments in healthcare",
expected_output="Research findings on AI in healthcare",
agent=researcher,
)
crew = Crew(agents=[researcher], tasks=[task])
result = crew.kickoff()
self.state["research"] = result.raw
return result.raw
@listen(research_phase)
def analysis_phase(self, research_data):
"""Second crew: Analyze the research."""
analyst = Agent(
role="Data Analyst",
goal="Analyze information and extract insights",
backstory="Expert at identifying patterns and trends",
)
task = Task(
description="Analyze this research: {research}",
expected_output="Key insights and trends",
agent=analyst,
)
crew = Crew(agents=[analyst], tasks=[task])
return crew.kickoff(inputs={"research": research_data})
# Stream across both phases
flow = MultiStepFlow()
streaming = flow.kickoff()
current_step = ""
for chunk in streaming:
# Track which flow step is executing
if chunk.task_name != current_step:
current_step = chunk.task_name
print(f"\n\n=== {chunk.task_name} ===\n")
print(chunk.content, end="", flush=True)
result = streaming.result
print(f"\n\nFinal analysis: {result}")
```
## Practical Example: Progress Dashboard
Here's a complete example showing how to build a progress dashboard with streaming:
```python Code
import asyncio
from crewai.flow.flow import Flow, listen, start
from crewai import Agent, Crew, Task
from crewai.types.streaming import StreamChunkType
class ResearchPipeline(Flow):
stream = True
@start()
def gather_data(self):
researcher = Agent(
role="Data Gatherer",
goal="Collect relevant information",
backstory="Skilled at finding quality sources",
)
task = Task(
description="Gather data on renewable energy trends",
expected_output="Collection of relevant data points",
agent=researcher,
)
crew = Crew(agents=[researcher], tasks=[task])
result = crew.kickoff()
self.state["data"] = result.raw
return result.raw
@listen(gather_data)
def analyze_data(self, data):
analyst = Agent(
role="Data Analyst",
goal="Extract meaningful insights",
backstory="Expert at data analysis",
)
task = Task(
description="Analyze: {data}",
expected_output="Key insights and trends",
agent=analyst,
)
crew = Crew(agents=[analyst], tasks=[task])
return crew.kickoff(inputs={"data": data})
async def run_with_dashboard():
flow = ResearchPipeline()
print("="*60)
print("RESEARCH PIPELINE DASHBOARD")
print("="*60)
streaming = await flow.kickoff_async()
current_agent = ""
current_task = ""
chunk_count = 0
async for chunk in streaming:
chunk_count += 1
# Display phase transitions
if chunk.task_name != current_task:
current_task = chunk.task_name
current_agent = chunk.agent_role
print(f"\n\n📋 Phase: {current_task}")
print(f"👤 Agent: {current_agent}")
print("-" * 60)
# Display text output
if chunk.chunk_type == StreamChunkType.TEXT:
print(chunk.content, end="", flush=True)
# Display tool usage
elif chunk.chunk_type == StreamChunkType.TOOL_CALL and chunk.tool_call:
print(f"\n🔧 Tool: {chunk.tool_call.tool_name}")
# Show completion summary
result = streaming.result
print(f"\n\n{'='*60}")
print("PIPELINE COMPLETE")
print(f"{'='*60}")
print(f"Total chunks: {chunk_count}")
print(f"Final output length: {len(str(result))} characters")
asyncio.run(run_with_dashboard())
```
## Streaming with State Management
Streaming works naturally with Flow state management:
```python Code
from pydantic import BaseModel
class AnalysisState(BaseModel):
topic: str = ""
research: str = ""
insights: str = ""
class StatefulStreamingFlow(Flow[AnalysisState]):
stream = True
@start()
def research(self):
# State is available during streaming
topic = self.state.topic
print(f"Researching: {topic}")
researcher = Agent(
role="Researcher",
goal="Research topics thoroughly",
backstory="Expert researcher",
)
task = Task(
description=f"Research {topic}",
expected_output="Research findings",
agent=researcher,
)
crew = Crew(agents=[researcher], tasks=[task])
result = crew.kickoff()
self.state.research = result.raw
return result.raw
@listen(research)
def analyze(self, research):
# Access updated state
print(f"Analyzing {len(self.state.research)} chars of research")
analyst = Agent(
role="Analyst",
goal="Extract insights",
backstory="Expert analyst",
)
task = Task(
description="Analyze: {research}",
expected_output="Key insights",
agent=analyst,
)
crew = Crew(agents=[analyst], tasks=[task])
result = crew.kickoff(inputs={"research": research})
self.state.insights = result.raw
return result.raw
# Run with streaming
flow = StatefulStreamingFlow()
streaming = flow.kickoff(inputs={"topic": "quantum computing"})
for chunk in streaming:
print(chunk.content, end="", flush=True)
result = streaming.result
print(f"\n\nFinal state:")
print(f"Topic: {flow.state.topic}")
print(f"Research length: {len(flow.state.research)}")
print(f"Insights length: {len(flow.state.insights)}")
```
## Use Cases
Flow streaming is particularly valuable for:
- **Multi-Stage Workflows**: Show progress across research, analysis, and synthesis phases
- **Complex Pipelines**: Provide visibility into long-running data processing flows
- **Interactive Applications**: Build responsive UIs that display intermediate results
- **Monitoring and Debugging**: Observe flow execution and crew interactions in real-time
- **Progress Tracking**: Show users which stage of the workflow is currently executing
- **Live Dashboards**: Create monitoring interfaces for production flows
## Stream Chunk Types
Like crew streaming, flow chunks can be of different types:
### TEXT Chunks
Standard text content from LLM responses:
```python Code
for chunk in streaming:
if chunk.chunk_type == StreamChunkType.TEXT:
print(chunk.content, end="", flush=True)
```
### TOOL_CALL Chunks
Information about tool calls within the flow:
```python Code
for chunk in streaming:
if chunk.chunk_type == StreamChunkType.TOOL_CALL and chunk.tool_call:
print(f"\nTool: {chunk.tool_call.tool_name}")
print(f"Args: {chunk.tool_call.arguments}")
```
## Error Handling
Handle errors gracefully during streaming:
```python Code
flow = ResearchFlow()
streaming = flow.kickoff()
try:
for chunk in streaming:
print(chunk.content, end="", flush=True)
result = streaming.result
print(f"\nSuccess! Result: {result}")
except Exception as e:
print(f"\nError during flow execution: {e}")
if streaming.is_completed:
print("Streaming completed but flow encountered an error")
```
## Important Notes
- Streaming automatically enables LLM streaming for any crews used within the flow
- You must iterate through all chunks before accessing the `.result` property
- Streaming works with both structured and unstructured flow state
- Flow streaming captures output from all crews and LLM calls in the flow
- Each chunk includes context about which agent and task generated it
- Streaming adds minimal overhead to flow execution
## Combining with Flow Visualization
You can combine streaming with flow visualization to provide a complete picture:
```python Code
# Generate flow visualization
flow = ResearchFlow()
flow.plot("research_flow") # Creates HTML visualization
# Run with streaming
streaming = flow.kickoff()
for chunk in streaming:
print(chunk.content, end="", flush=True)
result = streaming.result
print(f"\nFlow complete! View structure at: research_flow.html")
```
By leveraging flow streaming, you can build sophisticated, responsive applications that provide users with real-time visibility into complex multi-stage workflows, making your AI automations more transparent and engaging.

View File

@@ -0,0 +1,600 @@
---
title: Tool Call Hooks
description: Learn how to use tool call hooks to intercept, modify, and control tool execution in CrewAI
mode: "wide"
---
Tool Call Hooks provide fine-grained control over tool execution during agent operations. These hooks allow you to intercept tool calls, modify inputs, transform outputs, implement safety checks, and add comprehensive logging or monitoring.
## Overview
Tool hooks are executed at two critical points:
- **Before Tool Call**: Modify inputs, validate parameters, or block execution
- **After Tool Call**: Transform results, sanitize outputs, or log execution details
## Hook Types
### Before Tool Call Hooks
Executed before every tool execution, these hooks can:
- Inspect and modify tool inputs
- Block tool execution based on conditions
- Implement approval gates for dangerous operations
- Validate parameters
- Log tool invocations
**Signature:**
```python
def before_hook(context: ToolCallHookContext) -> bool | None:
# Return False to block execution
# Return True or None to allow execution
...
```
### After Tool Call Hooks
Executed after every tool execution, these hooks can:
- Modify or sanitize tool results
- Add metadata or formatting
- Log execution results
- Implement result validation
- Transform output formats
**Signature:**
```python
def after_hook(context: ToolCallHookContext) -> str | None:
# Return modified result string
# Return None to keep original result
...
```
## Tool Hook Context
The `ToolCallHookContext` object provides comprehensive access to tool execution state:
```python
class ToolCallHookContext:
tool_name: str # Name of the tool being called
tool_input: dict[str, Any] # Mutable tool input parameters
tool: CrewStructuredTool # Tool instance reference
agent: Agent | BaseAgent | None # Agent executing the tool
task: Task | None # Current task
crew: Crew | None # Crew instance
tool_result: str | None # Tool result (after hooks only)
```
### Modifying Tool Inputs
**Important:** Always modify tool inputs in-place:
```python
# ✅ Correct - modify in-place
def sanitize_input(context: ToolCallHookContext) -> None:
context.tool_input['query'] = context.tool_input['query'].lower()
# ❌ Wrong - replaces dict reference
def wrong_approach(context: ToolCallHookContext) -> None:
context.tool_input = {'query': 'new query'}
```
## Registration Methods
### 1. Global Hook Registration
Register hooks that apply to all tool calls across all crews:
```python
from crewai.hooks import register_before_tool_call_hook, register_after_tool_call_hook
def log_tool_call(context):
print(f"Tool: {context.tool_name}")
print(f"Input: {context.tool_input}")
return None # Allow execution
register_before_tool_call_hook(log_tool_call)
```
### 2. Decorator-Based Registration
Use decorators for cleaner syntax:
```python
from crewai.hooks import before_tool_call, after_tool_call
@before_tool_call
def block_dangerous_tools(context):
dangerous_tools = ['delete_database', 'drop_table', 'rm_rf']
if context.tool_name in dangerous_tools:
print(f"⛔ Blocked dangerous tool: {context.tool_name}")
return False # Block execution
return None
@after_tool_call
def sanitize_results(context):
if context.tool_result and "password" in context.tool_result.lower():
return context.tool_result.replace("password", "[REDACTED]")
return None
```
### 3. Crew-Scoped Hooks
Register hooks for a specific crew instance:
```python
@CrewBase
class MyProjCrew:
@before_tool_call_crew
def validate_tool_inputs(self, context):
# Only applies to this crew
if context.tool_name == "web_search":
if not context.tool_input.get('query'):
print("❌ Invalid search query")
return False
return None
@after_tool_call_crew
def log_tool_results(self, context):
# Crew-specific tool logging
print(f"✅ {context.tool_name} completed")
return None
@crew
def crew(self) -> Crew:
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True
)
```
## Common Use Cases
### 1. Safety Guardrails
```python
@before_tool_call
def safety_check(context: ToolCallHookContext) -> bool | None:
# Block tools that could cause harm
destructive_tools = [
'delete_file',
'drop_table',
'remove_user',
'system_shutdown'
]
if context.tool_name in destructive_tools:
print(f"🛑 Blocked destructive tool: {context.tool_name}")
return False
# Warn on sensitive operations
sensitive_tools = ['send_email', 'post_to_social_media', 'charge_payment']
if context.tool_name in sensitive_tools:
print(f"⚠️ Executing sensitive tool: {context.tool_name}")
return None
```
### 2. Human Approval Gate
```python
@before_tool_call
def require_approval_for_actions(context: ToolCallHookContext) -> bool | None:
approval_required = [
'send_email',
'make_purchase',
'delete_file',
'post_message'
]
if context.tool_name in approval_required:
response = context.request_human_input(
prompt=f"Approve {context.tool_name}?",
default_message=f"Input: {context.tool_input}\nType 'yes' to approve:"
)
if response.lower() != 'yes':
print(f"❌ Tool execution denied: {context.tool_name}")
return False
return None
```
### 3. Input Validation and Sanitization
```python
@before_tool_call
def validate_and_sanitize_inputs(context: ToolCallHookContext) -> bool | None:
# Validate search queries
if context.tool_name == 'web_search':
query = context.tool_input.get('query', '')
if len(query) < 3:
print("❌ Search query too short")
return False
# Sanitize query
context.tool_input['query'] = query.strip().lower()
# Validate file paths
if context.tool_name == 'read_file':
path = context.tool_input.get('path', '')
if '..' in path or path.startswith('/'):
print("❌ Invalid file path")
return False
return None
```
### 4. Result Sanitization
```python
@after_tool_call
def sanitize_sensitive_data(context: ToolCallHookContext) -> str | None:
if not context.tool_result:
return None
import re
result = context.tool_result
# Remove API keys
result = re.sub(
r'(api[_-]?key|token)["\']?\s*[:=]\s*["\']?[\w-]+',
r'\1: [REDACTED]',
result,
flags=re.IGNORECASE
)
# Remove email addresses
result = re.sub(
r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b',
'[EMAIL-REDACTED]',
result
)
# Remove credit card numbers
result = re.sub(
r'\b\d{4}[- ]?\d{4}[- ]?\d{4}[- ]?\d{4}\b',
'[CARD-REDACTED]',
result
)
return result
```
### 5. Tool Usage Analytics
```python
import time
from collections import defaultdict
tool_stats = defaultdict(lambda: {'count': 0, 'total_time': 0, 'failures': 0})
@before_tool_call
def start_timer(context: ToolCallHookContext) -> None:
context.tool_input['_start_time'] = time.time()
return None
@after_tool_call
def track_tool_usage(context: ToolCallHookContext) -> None:
start_time = context.tool_input.get('_start_time', time.time())
duration = time.time() - start_time
tool_stats[context.tool_name]['count'] += 1
tool_stats[context.tool_name]['total_time'] += duration
if not context.tool_result or 'error' in context.tool_result.lower():
tool_stats[context.tool_name]['failures'] += 1
print(f"""
📊 Tool Stats for {context.tool_name}:
- Executions: {tool_stats[context.tool_name]['count']}
- Avg Time: {tool_stats[context.tool_name]['total_time'] / tool_stats[context.tool_name]['count']:.2f}s
- Failures: {tool_stats[context.tool_name]['failures']}
""")
return None
```
### 6. Rate Limiting
```python
from collections import defaultdict
from datetime import datetime, timedelta
tool_call_history = defaultdict(list)
@before_tool_call
def rate_limit_tools(context: ToolCallHookContext) -> bool | None:
tool_name = context.tool_name
now = datetime.now()
# Clean old entries (older than 1 minute)
tool_call_history[tool_name] = [
call_time for call_time in tool_call_history[tool_name]
if now - call_time < timedelta(minutes=1)
]
# Check rate limit (max 10 calls per minute)
if len(tool_call_history[tool_name]) >= 10:
print(f"🚫 Rate limit exceeded for {tool_name}")
return False
# Record this call
tool_call_history[tool_name].append(now)
return None
```
### 7. Caching Tool Results
```python
import hashlib
import json
tool_cache = {}
def cache_key(tool_name: str, tool_input: dict) -> str:
"""Generate cache key from tool name and input."""
input_str = json.dumps(tool_input, sort_keys=True)
return hashlib.md5(f"{tool_name}:{input_str}".encode()).hexdigest()
@before_tool_call
def check_cache(context: ToolCallHookContext) -> bool | None:
key = cache_key(context.tool_name, context.tool_input)
if key in tool_cache:
print(f"💾 Cache hit for {context.tool_name}")
# Note: Can't return cached result from before hook
# Would need to implement this differently
return None
@after_tool_call
def cache_result(context: ToolCallHookContext) -> None:
if context.tool_result:
key = cache_key(context.tool_name, context.tool_input)
tool_cache[key] = context.tool_result
print(f"💾 Cached result for {context.tool_name}")
return None
```
### 8. Debug Logging
```python
@before_tool_call
def debug_tool_call(context: ToolCallHookContext) -> None:
print(f"""
🔍 Tool Call Debug:
- Tool: {context.tool_name}
- Agent: {context.agent.role if context.agent else 'Unknown'}
- Task: {context.task.description[:50] if context.task else 'Unknown'}...
- Input: {context.tool_input}
""")
return None
@after_tool_call
def debug_tool_result(context: ToolCallHookContext) -> None:
if context.tool_result:
result_preview = context.tool_result[:200]
print(f"✅ Result Preview: {result_preview}...")
else:
print("⚠️ No result returned")
return None
```
## Hook Management
### Unregistering Hooks
```python
from crewai.hooks import (
unregister_before_tool_call_hook,
unregister_after_tool_call_hook
)
# Unregister specific hook
def my_hook(context):
...
register_before_tool_call_hook(my_hook)
# Later...
success = unregister_before_tool_call_hook(my_hook)
print(f"Unregistered: {success}")
```
### Clearing Hooks
```python
from crewai.hooks import (
clear_before_tool_call_hooks,
clear_after_tool_call_hooks,
clear_all_tool_call_hooks
)
# Clear specific hook type
count = clear_before_tool_call_hooks()
print(f"Cleared {count} before hooks")
# Clear all tool hooks
before_count, after_count = clear_all_tool_call_hooks()
print(f"Cleared {before_count} before and {after_count} after hooks")
```
### Listing Registered Hooks
```python
from crewai.hooks import (
get_before_tool_call_hooks,
get_after_tool_call_hooks
)
# Get current hooks
before_hooks = get_before_tool_call_hooks()
after_hooks = get_after_tool_call_hooks()
print(f"Registered: {len(before_hooks)} before, {len(after_hooks)} after")
```
## Advanced Patterns
### Conditional Hook Execution
```python
@before_tool_call
def conditional_blocking(context: ToolCallHookContext) -> bool | None:
# Only block for specific agents
if context.agent and context.agent.role == "junior_agent":
if context.tool_name in ['delete_file', 'send_email']:
print(f"❌ Junior agents cannot use {context.tool_name}")
return False
# Only block during specific tasks
if context.task and "sensitive" in context.task.description.lower():
if context.tool_name == 'web_search':
print("❌ Web search blocked for sensitive tasks")
return False
return None
```
### Context-Aware Input Modification
```python
@before_tool_call
def enhance_tool_inputs(context: ToolCallHookContext) -> None:
# Add context based on agent role
if context.agent and context.agent.role == "researcher":
if context.tool_name == 'web_search':
# Add domain restrictions for researchers
context.tool_input['domains'] = ['edu', 'gov', 'org']
# Add context based on task
if context.task and "urgent" in context.task.description.lower():
if context.tool_name == 'send_email':
context.tool_input['priority'] = 'high'
return None
```
### Tool Chain Monitoring
```python
tool_call_chain = []
@before_tool_call
def track_tool_chain(context: ToolCallHookContext) -> None:
tool_call_chain.append({
'tool': context.tool_name,
'timestamp': time.time(),
'agent': context.agent.role if context.agent else 'Unknown'
})
# Detect potential infinite loops
recent_calls = tool_call_chain[-5:]
if len(recent_calls) == 5 and all(c['tool'] == context.tool_name for c in recent_calls):
print(f"⚠️ Warning: {context.tool_name} called 5 times in a row")
return None
```
## Best Practices
1. **Keep Hooks Focused**: Each hook should have a single responsibility
2. **Avoid Heavy Computation**: Hooks execute on every tool call
3. **Handle Errors Gracefully**: Use try-except to prevent hook failures
4. **Use Type Hints**: Leverage `ToolCallHookContext` for better IDE support
5. **Document Blocking Conditions**: Make it clear when/why tools are blocked
6. **Test Hooks Independently**: Unit test hooks before using in production
7. **Clear Hooks in Tests**: Use `clear_all_tool_call_hooks()` between test runs
8. **Modify In-Place**: Always modify `context.tool_input` in-place, never replace
9. **Log Important Decisions**: Especially when blocking tool execution
10. **Consider Performance**: Cache expensive validations when possible
## Error Handling
```python
@before_tool_call
def safe_validation(context: ToolCallHookContext) -> bool | None:
try:
# Your validation logic
if not validate_input(context.tool_input):
return False
except Exception as e:
print(f"⚠️ Hook error: {e}")
# Decide: allow or block on error
return None # Allow execution despite error
```
## Type Safety
```python
from crewai.hooks import ToolCallHookContext, BeforeToolCallHookType, AfterToolCallHookType
# Explicit type annotations
def my_before_hook(context: ToolCallHookContext) -> bool | None:
return None
def my_after_hook(context: ToolCallHookContext) -> str | None:
return None
# Type-safe registration
register_before_tool_call_hook(my_before_hook)
register_after_tool_call_hook(my_after_hook)
```
## Integration with Existing Tools
### Wrapping Existing Validation
```python
def existing_validator(tool_name: str, inputs: dict) -> bool:
"""Your existing validation function."""
# Your validation logic
return True
@before_tool_call
def integrate_validator(context: ToolCallHookContext) -> bool | None:
if not existing_validator(context.tool_name, context.tool_input):
print(f"❌ Validation failed for {context.tool_name}")
return False
return None
```
### Logging to External Systems
```python
import logging
logger = logging.getLogger(__name__)
@before_tool_call
def log_to_external_system(context: ToolCallHookContext) -> None:
logger.info(f"Tool call: {context.tool_name}", extra={
'tool_name': context.tool_name,
'tool_input': context.tool_input,
'agent': context.agent.role if context.agent else None
})
return None
```
## Troubleshooting
### Hook Not Executing
- Verify hook is registered before crew execution
- Check if previous hook returned `False` (blocks execution and subsequent hooks)
- Ensure hook signature matches expected type
### Input Modifications Not Working
- Use in-place modifications: `context.tool_input['key'] = value`
- Don't replace the dict: `context.tool_input = {}`
### Result Modifications Not Working
- Return the modified string from after hooks
- Returning `None` keeps the original result
- Ensure the tool actually returned a result
### Tool Blocked Unexpectedly
- Check all before hooks for blocking conditions
- Verify hook execution order
- Add debug logging to identify which hook is blocking
## Conclusion
Tool Call Hooks provide powerful capabilities for controlling and monitoring tool execution in CrewAI. Use them to implement safety guardrails, approval gates, input validation, result sanitization, logging, and analytics. Combined with proper error handling and type safety, hooks enable secure and production-ready agent systems with comprehensive observability.

View File

@@ -60,9 +60,9 @@ Use the `#` syntax to select specific tools from a server:
"https://mcp.exa.ai/mcp?api_key=your_key#web_search_exa"
```
### CrewAI AMP Marketplace
### CrewAI AOP Marketplace
Access tools from the CrewAI AMP marketplace:
Access tools from the CrewAI AOP marketplace:
```python
# Full service with all tools
@@ -97,7 +97,7 @@ multi_source_agent = Agent(
"https://mcp.exa.ai/mcp?api_key=your_exa_key&profile=research",
"https://weather.api.com/mcp#get_current_conditions",
# CrewAI AMP marketplace
# CrewAI AOP marketplace
"crewai-amp:financial-insights",
"crewai-amp:academic-research#pubmed_search",
"crewai-amp:market-intelligence#competitor_analysis"

View File

@@ -11,9 +11,13 @@ The [Model Context Protocol](https://modelcontextprotocol.io/introduction) (MCP)
CrewAI offers **two approaches** for MCP integration:
### Simple DSL Integration** (Recommended)
### 🚀 **Simple DSL Integration** (Recommended)
Use the `mcps` field directly on agents for seamless MCP tool integration:
Use the `mcps` field directly on agents for seamless MCP tool integration. The DSL supports both **string references** (for quick setup) and **structured configurations** (for full control).
#### String-Based References (Quick Setup)
Perfect for remote HTTPS servers and CrewAI AOP marketplace:
```python
from crewai import Agent
@@ -25,13 +29,53 @@ agent = Agent(
mcps=[
"https://mcp.exa.ai/mcp?api_key=your_key", # External MCP server
"https://api.weather.com/mcp#get_forecast", # Specific tool from server
"crewai-amp:financial-data", # CrewAI AMP marketplace
"crewai-amp:financial-data", # CrewAI AOP marketplace
"crewai-amp:research-tools#pubmed_search" # Specific AMP tool
]
)
# MCP tools are now automatically available to your agent!
```
#### Structured Configurations (Full Control)
For complete control over connection settings, tool filtering, and all transport types:
```python
from crewai import Agent
from crewai.mcp import MCPServerStdio, MCPServerHTTP, MCPServerSSE
from crewai.mcp.filters import create_static_tool_filter
agent = Agent(
role="Advanced Research Analyst",
goal="Research with full control over MCP connections",
backstory="Expert researcher with advanced tool access",
mcps=[
# Stdio transport for local servers
MCPServerStdio(
command="npx",
args=["-y", "@modelcontextprotocol/server-filesystem"],
env={"API_KEY": "your_key"},
tool_filter=create_static_tool_filter(
allowed_tool_names=["read_file", "list_directory"]
),
cache_tools_list=True,
),
# HTTP/Streamable HTTP transport for remote servers
MCPServerHTTP(
url="https://api.example.com/mcp",
headers={"Authorization": "Bearer your_token"},
streamable=True,
cache_tools_list=True,
),
# SSE transport for real-time streaming
MCPServerSSE(
url="https://stream.example.com/mcp/sse",
headers={"Authorization": "Bearer your_token"},
),
]
)
```
### 🔧 **Advanced: MCPServerAdapter** (For Complex Scenarios)
For advanced use cases requiring manual connection management, the `crewai-tools` library provides the `MCPServerAdapter` class.
@@ -68,12 +112,14 @@ uv pip install 'crewai-tools[mcp]'
## Quick Start: Simple DSL Integration
The easiest way to integrate MCP servers is using the `mcps` field on your agents:
The easiest way to integrate MCP servers is using the `mcps` field on your agents. You can use either string references or structured configurations.
### Quick Start with String References
```python
from crewai import Agent, Task, Crew
# Create agent with MCP tools
# Create agent with MCP tools using string references
research_agent = Agent(
role="Research Analyst",
goal="Find and analyze information using advanced search tools",
@@ -96,13 +142,53 @@ crew = Crew(agents=[research_agent], tasks=[research_task])
result = crew.kickoff()
```
### Quick Start with Structured Configurations
```python
from crewai import Agent, Task, Crew
from crewai.mcp import MCPServerStdio, MCPServerHTTP, MCPServerSSE
# Create agent with structured MCP configurations
research_agent = Agent(
role="Research Analyst",
goal="Find and analyze information using advanced search tools",
backstory="Expert researcher with access to multiple data sources",
mcps=[
# Local stdio server
MCPServerStdio(
command="python",
args=["local_server.py"],
env={"API_KEY": "your_key"},
),
# Remote HTTP server
MCPServerHTTP(
url="https://api.research.com/mcp",
headers={"Authorization": "Bearer your_token"},
),
]
)
# Create task
research_task = Task(
description="Research the latest developments in AI agent frameworks",
expected_output="Comprehensive research report with citations",
agent=research_agent
)
# Create and run crew
crew = Crew(agents=[research_agent], tasks=[research_task])
result = crew.kickoff()
```
That's it! The MCP tools are automatically discovered and available to your agent.
## MCP Reference Formats
The `mcps` field supports various reference formats for maximum flexibility:
The `mcps` field supports both **string references** (for quick setup) and **structured configurations** (for full control). You can mix both formats in the same list.
### External MCP Servers
### String-Based References
#### External MCP Servers
```python
mcps=[
@@ -117,7 +203,7 @@ mcps=[
]
```
### CrewAI AMP Marketplace
#### CrewAI AOP Marketplace
```python
mcps=[
@@ -133,17 +219,166 @@ mcps=[
]
```
### Mixed References
### Structured Configurations
#### Stdio Transport (Local Servers)
Perfect for local MCP servers that run as processes:
```python
from crewai.mcp import MCPServerStdio
from crewai.mcp.filters import create_static_tool_filter
mcps=[
"https://external-api.com/mcp", # External server
"https://weather.service.com/mcp#forecast", # Specific external tool
"crewai-amp:financial-insights", # AMP service
"crewai-amp:data-analysis#sentiment_tool" # Specific AMP tool
MCPServerStdio(
command="npx",
args=["-y", "@modelcontextprotocol/server-filesystem"],
env={"API_KEY": "your_key"},
tool_filter=create_static_tool_filter(
allowed_tool_names=["read_file", "write_file"]
),
cache_tools_list=True,
),
# Python-based server
MCPServerStdio(
command="python",
args=["path/to/server.py"],
env={"UV_PYTHON": "3.12", "API_KEY": "your_key"},
),
]
```
#### HTTP/Streamable HTTP Transport (Remote Servers)
For remote MCP servers over HTTP/HTTPS:
```python
from crewai.mcp import MCPServerHTTP
mcps=[
# Streamable HTTP (default)
MCPServerHTTP(
url="https://api.example.com/mcp",
headers={"Authorization": "Bearer your_token"},
streamable=True,
cache_tools_list=True,
),
# Standard HTTP
MCPServerHTTP(
url="https://api.example.com/mcp",
headers={"Authorization": "Bearer your_token"},
streamable=False,
),
]
```
#### SSE Transport (Real-Time Streaming)
For remote servers using Server-Sent Events:
```python
from crewai.mcp import MCPServerSSE
mcps=[
MCPServerSSE(
url="https://stream.example.com/mcp/sse",
headers={"Authorization": "Bearer your_token"},
cache_tools_list=True,
),
]
```
### Mixed References
You can combine string references and structured configurations:
```python
from crewai.mcp import MCPServerStdio, MCPServerHTTP
mcps=[
# String references
"https://external-api.com/mcp", # External server
"crewai-amp:financial-insights", # AMP service
# Structured configurations
MCPServerStdio(
command="npx",
args=["-y", "@modelcontextprotocol/server-filesystem"],
),
MCPServerHTTP(
url="https://api.example.com/mcp",
headers={"Authorization": "Bearer token"},
),
]
```
### Tool Filtering
Structured configurations support advanced tool filtering:
```python
from crewai.mcp import MCPServerStdio
from crewai.mcp.filters import create_static_tool_filter, create_dynamic_tool_filter, ToolFilterContext
# Static filtering (allow/block lists)
static_filter = create_static_tool_filter(
allowed_tool_names=["read_file", "write_file"],
blocked_tool_names=["delete_file"],
)
# Dynamic filtering (context-aware)
def dynamic_filter(context: ToolFilterContext, tool: dict) -> bool:
# Block dangerous tools for certain agent roles
if context.agent.role == "Code Reviewer":
if "delete" in tool.get("name", "").lower():
return False
return True
mcps=[
MCPServerStdio(
command="npx",
args=["-y", "@modelcontextprotocol/server-filesystem"],
tool_filter=static_filter, # or dynamic_filter
),
]
```
## Configuration Parameters
Each transport type supports specific configuration options:
### MCPServerStdio Parameters
- **`command`** (required): Command to execute (e.g., `"python"`, `"node"`, `"npx"`, `"uvx"`)
- **`args`** (optional): List of command arguments (e.g., `["server.py"]` or `["-y", "@mcp/server"]`)
- **`env`** (optional): Dictionary of environment variables to pass to the process
- **`tool_filter`** (optional): Tool filter function for filtering available tools
- **`cache_tools_list`** (optional): Whether to cache the tool list for faster subsequent access (default: `False`)
### MCPServerHTTP Parameters
- **`url`** (required): Server URL (e.g., `"https://api.example.com/mcp"`)
- **`headers`** (optional): Dictionary of HTTP headers for authentication or other purposes
- **`streamable`** (optional): Whether to use streamable HTTP transport (default: `True`)
- **`tool_filter`** (optional): Tool filter function for filtering available tools
- **`cache_tools_list`** (optional): Whether to cache the tool list for faster subsequent access (default: `False`)
### MCPServerSSE Parameters
- **`url`** (required): Server URL (e.g., `"https://api.example.com/mcp/sse"`)
- **`headers`** (optional): Dictionary of HTTP headers for authentication or other purposes
- **`tool_filter`** (optional): Tool filter function for filtering available tools
- **`cache_tools_list`** (optional): Whether to cache the tool list for faster subsequent access (default: `False`)
### Common Parameters
All transport types support:
- **`tool_filter`**: Filter function to control which tools are available. Can be:
- `None` (default): All tools are available
- Static filter: Created with `create_static_tool_filter()` for allow/block lists
- Dynamic filter: Created with `create_dynamic_tool_filter()` for context-aware filtering
- **`cache_tools_list`**: When `True`, caches the tool list after first discovery to improve performance on subsequent connections
## Key Features
- 🔄 **Automatic Tool Discovery**: Tools are automatically discovered and integrated
@@ -152,26 +387,47 @@ mcps=[
- 🛡️ **Error Resilience**: Graceful handling of unavailable servers
- ⏱️ **Timeout Protection**: Built-in timeouts prevent hanging connections
- 📊 **Transparent Integration**: Works seamlessly with existing CrewAI features
- 🔧 **Full Transport Support**: Stdio, HTTP/Streamable HTTP, and SSE transports
- 🎯 **Advanced Filtering**: Static and dynamic tool filtering capabilities
- 🔐 **Flexible Authentication**: Support for headers, environment variables, and query parameters
## Error Handling
The MCP DSL integration is designed to be resilient:
The MCP DSL integration is designed to be resilient and handles failures gracefully:
```python
from crewai import Agent
from crewai.mcp import MCPServerStdio, MCPServerHTTP
agent = Agent(
role="Resilient Agent",
goal="Continue working despite server issues",
backstory="Agent that handles failures gracefully",
mcps=[
# String references
"https://reliable-server.com/mcp", # Will work
"https://unreachable-server.com/mcp", # Will be skipped gracefully
"https://slow-server.com/mcp", # Will timeout gracefully
"crewai-amp:working-service" # Will work
"crewai-amp:working-service", # Will work
# Structured configs
MCPServerStdio(
command="python",
args=["reliable_server.py"], # Will work
),
MCPServerHTTP(
url="https://slow-server.com/mcp", # Will timeout gracefully
),
]
)
# Agent will use tools from working servers and log warnings for failing ones
```
All connection errors are handled gracefully:
- **Connection failures**: Logged as warnings, agent continues with available tools
- **Timeout errors**: Connections timeout after 30 seconds (configurable)
- **Authentication errors**: Logged clearly for debugging
- **Invalid configurations**: Validation errors are raised at agent creation time
## Advanced: MCPServerAdapter
For complex scenarios requiring manual connection management, use the `MCPServerAdapter` class from `crewai-tools`. Using a Python context manager (`with` statement) is the recommended approach as it automatically handles starting and stopping the connection to the MCP server.

View File

@@ -93,11 +93,15 @@ After running the application, you can view the traces in [Datadog LLM Observabi
Clicking on a trace will show you the details of the trace, including total tokens used, number of LLM calls, models used, and estimated cost. Clicking into a specific span will narrow down these details, and show related input, output, and metadata.
![Datadog LLM Observability Trace View](/images/datadog-llm-observability-1.png)
<Frame>
<img src="/images/datadog-llm-observability-1.png" alt="Datadog LLM Observability Trace View" />
</Frame>
Additionally, you can view the execution graph view of the trace, which shows the control and data flow of the trace, which will scale with larger agents to show handoffs and relationships between LLM calls, tool calls, and agent interactions.
![Datadog LLM Observability Agent Execution Flow View](/images/datadog-llm-observability-2.png)
<Frame>
<img src="/images/datadog-llm-observability-2.png" alt="Datadog LLM Observability Agent Execution Flow View" />
</Frame>
## References

View File

@@ -733,9 +733,7 @@ Here's a basic configuration to route requests to OpenAI, specifically using GPT
- Collect relevant metadata to filter logs
- Enforce access permissions
Create API keys through:
- [Portkey App](https://app.portkey.ai/)
- [API Key Management API](/en/api-reference/admin-api/control-plane/api-keys/create-api-key)
Create API keys through the [Portkey App](https://app.portkey.ai/)
Example using Python SDK:
```python
@@ -758,7 +756,7 @@ Here's a basic configuration to route requests to OpenAI, specifically using GPT
)
```
For detailed key management instructions, see our [API Keys documentation](/en/api-reference/admin-api/control-plane/api-keys/create-api-key).
For detailed key management instructions, see the [Portkey documentation](https://portkey.ai/docs).
</Accordion>
<Accordion title="Step 4: Deploy & Monitor">

View File

@@ -1,6 +1,6 @@
---
title: CrewAI Tracing
description: Built-in tracing for CrewAI Crews and Flows with the CrewAI AMP platform
description: Built-in tracing for CrewAI Crews and Flows with the CrewAI AOP platform
icon: magnifying-glass-chart
mode: "wide"
---
@@ -9,7 +9,7 @@ mode: "wide"
CrewAI provides built-in tracing capabilities that allow you to monitor and debug your Crews and Flows in real-time. This guide demonstrates how to enable tracing for both **Crews** and **Flows** using CrewAI's integrated observability platform.
> **What is CrewAI Tracing?** CrewAI's built-in tracing provides comprehensive observability for your AI agents, including agent decisions, task execution timelines, tool usage, and LLM calls - all accessible through the [CrewAI AMP platform](https://app.crewai.com).
> **What is CrewAI Tracing?** CrewAI's built-in tracing provides comprehensive observability for your AI agents, including agent decisions, task execution timelines, tool usage, and LLM calls - all accessible through the [CrewAI AOP platform](https://app.crewai.com).
![CrewAI Tracing Interface](/images/crewai-tracing.png)
@@ -17,7 +17,7 @@ CrewAI provides built-in tracing capabilities that allow you to monitor and debu
Before you can use CrewAI tracing, you need:
1. **CrewAI AMP Account**: Sign up for a free account at [app.crewai.com](https://app.crewai.com)
1. **CrewAI AOP Account**: Sign up for a free account at [app.crewai.com](https://app.crewai.com)
2. **CLI Authentication**: Use the CrewAI CLI to authenticate your local environment
```bash
@@ -26,9 +26,9 @@ crewai login
## Setup Instructions
### Step 1: Create Your CrewAI AMP Account
### Step 1: Create Your CrewAI AOP Account
Visit [app.crewai.com](https://app.crewai.com) and create your free account. This will give you access to the CrewAI AMP platform where you can view traces, metrics, and manage your crews.
Visit [app.crewai.com](https://app.crewai.com) and create your free account. This will give you access to the CrewAI AOP platform where you can view traces, metrics, and manage your crews.
### Step 2: Install CrewAI CLI and Authenticate
@@ -38,7 +38,7 @@ If you haven't already, install CrewAI with the CLI tools:
uv add crewai[tools]
```
Then authenticate your CLI with your CrewAI AMP account:
Then authenticate your CLI with your CrewAI AOP account:
```bash
crewai login
@@ -47,7 +47,7 @@ crewai login
This command will:
1. Open your browser to the authentication page
2. Prompt you to enter a device code
3. Authenticate your local environment with your CrewAI AMP account
3. Authenticate your local environment with your CrewAI AOP account
4. Enable tracing capabilities for your local development
### Step 3: Enable Tracing in Your Crew
@@ -147,9 +147,9 @@ flow = ExampleFlow(tracing=True)
result = flow.kickoff()
```
### Step 5: View Traces in the CrewAI AMP Dashboard
### Step 5: View Traces in the CrewAI AOP Dashboard
After running the crew or flow, you can view the traces generated by your CrewAI application in the CrewAI AMP dashboard. You should see detailed steps of the agent interactions, tool usages, and LLM calls.
After running the crew or flow, you can view the traces generated by your CrewAI application in the CrewAI AOP dashboard. You should see detailed steps of the agent interactions, tool usages, and LLM calls.
Just click on the link below to view the traces or head over to the traces tab in the dashboard [here](https://app.crewai.com/crewai_plus/trace_batches)
![CrewAI Tracing Interface](/images/view-traces.png)
@@ -172,7 +172,7 @@ When this environment variable is set, all Crews and Flows will automatically ha
## Viewing Your Traces
### Access the CrewAI AMP Dashboard
### Access the CrewAI AOP Dashboard
1. Visit [app.crewai.com](https://app.crewai.com) and log in to your account
2. Navigate to your project dashboard

View File

@@ -209,9 +209,9 @@ Follow the steps below to get Crewing! 🚣‍♂️
</Step>
<Step title="Enterprise Alternative: Create in Crew Studio">
For CrewAI AMP users, you can create the same crew without writing code:
For CrewAI AOP users, you can create the same crew without writing code:
1. Log in to your CrewAI AMP account (create a free account at [app.crewai.com](https://app.crewai.com))
1. Log in to your CrewAI AOP account (create a free account at [app.crewai.com](https://app.crewai.com))
2. Open Crew Studio
3. Type what is the automation you're trying to build
4. Create your tasks visually and connect them in sequence
@@ -219,8 +219,8 @@ Follow the steps below to get Crewing! 🚣‍♂️
![Crew Studio Quickstart](/images/enterprise/crew-studio-interface.png)
<Card title="Try CrewAI AMP" icon="rocket" href="https://app.crewai.com">
Start your free account at CrewAI AMP
<Card title="Try CrewAI AOP" icon="rocket" href="https://app.crewai.com">
Start your free account at CrewAI AOP
</Card>
</Step>
<Step title="View your final report">
@@ -340,9 +340,9 @@ email_summarizer_task:
## Deploying Your Crew
The easiest way to deploy your crew to production is through [CrewAI AMP](http://app.crewai.com).
The easiest way to deploy your crew to production is through [CrewAI AOP](http://app.crewai.com).
Watch this video tutorial for a step-by-step demonstration of deploying your crew to [CrewAI AMP](http://app.crewai.com) using the CLI.
Watch this video tutorial for a step-by-step demonstration of deploying your crew to [CrewAI AOP](http://app.crewai.com) using the CLI.
<iframe
className="w-full aspect-video rounded-xl"
@@ -359,7 +359,7 @@ Watch this video tutorial for a step-by-step demonstration of deploying your cre
icon="rocket"
href="http://app.crewai.com"
>
Get started with CrewAI AMP and deploy your crew in a production environment with just a few clicks.
Get started with CrewAI AOP and deploy your crew in a production environment with just a few clicks.
</Card>
<Card
title="Join the Community"

View File

@@ -77,7 +77,7 @@ The `RagTool` accepts the following parameters:
- **summarize**: Optional. Whether to summarize the retrieved content. Default is `False`.
- **adapter**: Optional. A custom adapter for the knowledge base. If not provided, a CrewAIRagAdapter will be used.
- **config**: Optional. Configuration for the underlying CrewAI RAG system.
- **config**: Optional. Configuration for the underlying CrewAI RAG system. Accepts a `RagToolConfig` TypedDict with optional `embedding_model` (ProviderSpec) and `vectordb` (VectorDbConfig) keys. All configuration values provided programmatically take precedence over environment variables.
## Adding Content
@@ -127,26 +127,528 @@ You can customize the behavior of the `RagTool` by providing a configuration dic
```python Code
from crewai_tools import RagTool
from crewai_tools.tools.rag import RagToolConfig, VectorDbConfig, ProviderSpec
# Create a RAG tool with custom configuration
config = {
"vectordb": {
"provider": "qdrant",
"config": {
"collection_name": "my-collection"
}
},
"embedding_model": {
"provider": "openai",
"config": {
"model": "text-embedding-3-small"
}
vectordb: VectorDbConfig = {
"provider": "qdrant",
"config": {
"collection_name": "my-collection"
}
}
embedding_model: ProviderSpec = {
"provider": "openai",
"config": {
"model_name": "text-embedding-3-small"
}
}
config: RagToolConfig = {
"vectordb": vectordb,
"embedding_model": embedding_model
}
rag_tool = RagTool(config=config, summarize=True)
```
## Embedding Model Configuration
The `embedding_model` parameter accepts a `crewai.rag.embeddings.types.ProviderSpec` dictionary with the structure:
```python
{
"provider": "provider-name", # Required
"config": { # Optional
# Provider-specific configuration
}
}
```
### Supported Providers
<AccordionGroup>
<Accordion title="OpenAI">
```python main.py
from crewai.rag.embeddings.providers.openai.types import OpenAIProviderSpec
embedding_model: OpenAIProviderSpec = {
"provider": "openai",
"config": {
"api_key": "your-api-key",
"model_name": "text-embedding-ada-002",
"dimensions": 1536,
"organization_id": "your-org-id",
"api_base": "https://api.openai.com/v1",
"api_version": "v1",
"default_headers": {"Custom-Header": "value"}
}
}
```
**Config Options:**
- `api_key` (str): OpenAI API key
- `model_name` (str): Model to use. Default: `text-embedding-ada-002`. Options: `text-embedding-3-small`, `text-embedding-3-large`, `text-embedding-ada-002`
- `dimensions` (int): Number of dimensions for the embedding
- `organization_id` (str): OpenAI organization ID
- `api_base` (str): Custom API base URL
- `api_version` (str): API version
- `default_headers` (dict): Custom headers for API requests
**Environment Variables:**
- `OPENAI_API_KEY` or `EMBEDDINGS_OPENAI_API_KEY`: `api_key`
- `OPENAI_ORGANIZATION_ID` or `EMBEDDINGS_OPENAI_ORGANIZATION_ID`: `organization_id`
- `OPENAI_MODEL_NAME` or `EMBEDDINGS_OPENAI_MODEL_NAME`: `model_name`
- `OPENAI_API_BASE` or `EMBEDDINGS_OPENAI_API_BASE`: `api_base`
- `OPENAI_API_VERSION` or `EMBEDDINGS_OPENAI_API_VERSION`: `api_version`
- `OPENAI_DIMENSIONS` or `EMBEDDINGS_OPENAI_DIMENSIONS`: `dimensions`
</Accordion>
<Accordion title="Cohere">
```python main.py
from crewai.rag.embeddings.providers.cohere.types import CohereProviderSpec
embedding_model: CohereProviderSpec = {
"provider": "cohere",
"config": {
"api_key": "your-api-key",
"model_name": "embed-english-v3.0"
}
}
```
**Config Options:**
- `api_key` (str): Cohere API key
- `model_name` (str): Model to use. Default: `large`. Options: `embed-english-v3.0`, `embed-multilingual-v3.0`, `large`, `small`
**Environment Variables:**
- `COHERE_API_KEY` or `EMBEDDINGS_COHERE_API_KEY`: `api_key`
- `EMBEDDINGS_COHERE_MODEL_NAME`: `model_name`
</Accordion>
<Accordion title="VoyageAI">
```python main.py
from crewai.rag.embeddings.providers.voyageai.types import VoyageAIProviderSpec
embedding_model: VoyageAIProviderSpec = {
"provider": "voyageai",
"config": {
"api_key": "your-api-key",
"model": "voyage-3",
"input_type": "document",
"truncation": True,
"output_dtype": "float32",
"output_dimension": 1024,
"max_retries": 3,
"timeout": 60.0
}
}
```
**Config Options:**
- `api_key` (str): VoyageAI API key
- `model` (str): Model to use. Default: `voyage-2`. Options: `voyage-3`, `voyage-3-lite`, `voyage-code-3`, `voyage-large-2`
- `input_type` (str): Type of input. Options: `document` (for storage), `query` (for search)
- `truncation` (bool): Whether to truncate inputs that exceed max length. Default: `True`
- `output_dtype` (str): Output data type
- `output_dimension` (int): Dimension of output embeddings
- `max_retries` (int): Maximum number of retry attempts. Default: `0`
- `timeout` (float): Request timeout in seconds
**Environment Variables:**
- `VOYAGEAI_API_KEY` or `EMBEDDINGS_VOYAGEAI_API_KEY`: `api_key`
- `VOYAGEAI_MODEL` or `EMBEDDINGS_VOYAGEAI_MODEL`: `model`
- `VOYAGEAI_INPUT_TYPE` or `EMBEDDINGS_VOYAGEAI_INPUT_TYPE`: `input_type`
- `VOYAGEAI_TRUNCATION` or `EMBEDDINGS_VOYAGEAI_TRUNCATION`: `truncation`
- `VOYAGEAI_OUTPUT_DTYPE` or `EMBEDDINGS_VOYAGEAI_OUTPUT_DTYPE`: `output_dtype`
- `VOYAGEAI_OUTPUT_DIMENSION` or `EMBEDDINGS_VOYAGEAI_OUTPUT_DIMENSION`: `output_dimension`
- `VOYAGEAI_MAX_RETRIES` or `EMBEDDINGS_VOYAGEAI_MAX_RETRIES`: `max_retries`
- `VOYAGEAI_TIMEOUT` or `EMBEDDINGS_VOYAGEAI_TIMEOUT`: `timeout`
</Accordion>
<Accordion title="Ollama">
```python main.py
from crewai.rag.embeddings.providers.ollama.types import OllamaProviderSpec
embedding_model: OllamaProviderSpec = {
"provider": "ollama",
"config": {
"model_name": "llama2",
"url": "http://localhost:11434/api/embeddings"
}
}
```
**Config Options:**
- `model_name` (str): Ollama model name (e.g., `llama2`, `mistral`, `nomic-embed-text`)
- `url` (str): Ollama API endpoint URL. Default: `http://localhost:11434/api/embeddings`
**Environment Variables:**
- `OLLAMA_MODEL` or `EMBEDDINGS_OLLAMA_MODEL`: `model_name`
- `OLLAMA_URL` or `EMBEDDINGS_OLLAMA_URL`: `url`
</Accordion>
<Accordion title="Amazon Bedrock">
```python main.py
from crewai.rag.embeddings.providers.aws.types import BedrockProviderSpec
embedding_model: BedrockProviderSpec = {
"provider": "amazon-bedrock",
"config": {
"model_name": "amazon.titan-embed-text-v2:0",
"session": boto3_session
}
}
```
**Config Options:**
- `model_name` (str): Bedrock model ID. Default: `amazon.titan-embed-text-v1`. Options: `amazon.titan-embed-text-v1`, `amazon.titan-embed-text-v2:0`, `cohere.embed-english-v3`, `cohere.embed-multilingual-v3`
- `session` (Any): Boto3 session object for AWS authentication
**Environment Variables:**
- `AWS_ACCESS_KEY_ID`: AWS access key
- `AWS_SECRET_ACCESS_KEY`: AWS secret key
- `AWS_REGION`: AWS region (e.g., `us-east-1`)
</Accordion>
<Accordion title="Azure OpenAI">
```python main.py
from crewai.rag.embeddings.providers.microsoft.types import AzureProviderSpec
embedding_model: AzureProviderSpec = {
"provider": "azure",
"config": {
"deployment_id": "your-deployment-id",
"api_key": "your-api-key",
"api_base": "https://your-resource.openai.azure.com",
"api_version": "2024-02-01",
"model_name": "text-embedding-ada-002",
"api_type": "azure"
}
}
```
**Config Options:**
- `deployment_id` (str): **Required** - Azure OpenAI deployment ID
- `api_key` (str): Azure OpenAI API key
- `api_base` (str): Azure OpenAI resource endpoint
- `api_version` (str): API version. Example: `2024-02-01`
- `model_name` (str): Model name. Default: `text-embedding-ada-002`
- `api_type` (str): API type. Default: `azure`
- `dimensions` (int): Output dimensions
- `default_headers` (dict): Custom headers
**Environment Variables:**
- `AZURE_OPENAI_API_KEY` or `EMBEDDINGS_AZURE_API_KEY`: `api_key`
- `AZURE_OPENAI_ENDPOINT` or `EMBEDDINGS_AZURE_API_BASE`: `api_base`
- `EMBEDDINGS_AZURE_DEPLOYMENT_ID`: `deployment_id`
- `EMBEDDINGS_AZURE_API_VERSION`: `api_version`
- `EMBEDDINGS_AZURE_MODEL_NAME`: `model_name`
- `EMBEDDINGS_AZURE_API_TYPE`: `api_type`
- `EMBEDDINGS_AZURE_DIMENSIONS`: `dimensions`
</Accordion>
<Accordion title="Google Generative AI">
```python main.py
from crewai.rag.embeddings.providers.google.types import GenerativeAiProviderSpec
embedding_model: GenerativeAiProviderSpec = {
"provider": "google-generativeai",
"config": {
"api_key": "your-api-key",
"model_name": "gemini-embedding-001",
"task_type": "RETRIEVAL_DOCUMENT"
}
}
```
**Config Options:**
- `api_key` (str): Google AI API key
- `model_name` (str): Model name. Default: `gemini-embedding-001`. Options: `gemini-embedding-001`, `text-embedding-005`, `text-multilingual-embedding-002`
- `task_type` (str): Task type for embeddings. Default: `RETRIEVAL_DOCUMENT`. Options: `RETRIEVAL_DOCUMENT`, `RETRIEVAL_QUERY`
**Environment Variables:**
- `GOOGLE_API_KEY`, `GEMINI_API_KEY`, or `EMBEDDINGS_GOOGLE_API_KEY`: `api_key`
- `EMBEDDINGS_GOOGLE_GENERATIVE_AI_MODEL_NAME`: `model_name`
- `EMBEDDINGS_GOOGLE_GENERATIVE_AI_TASK_TYPE`: `task_type`
</Accordion>
<Accordion title="Google Vertex AI">
```python main.py
from crewai.rag.embeddings.providers.google.types import VertexAIProviderSpec
embedding_model: VertexAIProviderSpec = {
"provider": "google-vertex",
"config": {
"model_name": "text-embedding-004",
"project_id": "your-project-id",
"region": "us-central1",
"api_key": "your-api-key"
}
}
```
**Config Options:**
- `model_name` (str): Model name. Default: `textembedding-gecko`. Options: `text-embedding-004`, `textembedding-gecko`, `textembedding-gecko-multilingual`
- `project_id` (str): Google Cloud project ID. Default: `cloud-large-language-models`
- `region` (str): Google Cloud region. Default: `us-central1`
- `api_key` (str): API key for authentication
**Environment Variables:**
- `GOOGLE_APPLICATION_CREDENTIALS`: Path to service account JSON file
- `GOOGLE_CLOUD_PROJECT` or `EMBEDDINGS_GOOGLE_VERTEX_PROJECT_ID`: `project_id`
- `EMBEDDINGS_GOOGLE_VERTEX_MODEL_NAME`: `model_name`
- `EMBEDDINGS_GOOGLE_VERTEX_REGION`: `region`
- `EMBEDDINGS_GOOGLE_VERTEX_API_KEY`: `api_key`
</Accordion>
<Accordion title="Jina AI">
```python main.py
from crewai.rag.embeddings.providers.jina.types import JinaProviderSpec
embedding_model: JinaProviderSpec = {
"provider": "jina",
"config": {
"api_key": "your-api-key",
"model_name": "jina-embeddings-v3"
}
}
```
**Config Options:**
- `api_key` (str): Jina AI API key
- `model_name` (str): Model name. Default: `jina-embeddings-v2-base-en`. Options: `jina-embeddings-v3`, `jina-embeddings-v2-base-en`, `jina-embeddings-v2-small-en`
**Environment Variables:**
- `JINA_API_KEY` or `EMBEDDINGS_JINA_API_KEY`: `api_key`
- `EMBEDDINGS_JINA_MODEL_NAME`: `model_name`
</Accordion>
<Accordion title="HuggingFace">
```python main.py
from crewai.rag.embeddings.providers.huggingface.types import HuggingFaceProviderSpec
embedding_model: HuggingFaceProviderSpec = {
"provider": "huggingface",
"config": {
"url": "https://api-inference.huggingface.co/models/sentence-transformers/all-MiniLM-L6-v2"
}
}
```
**Config Options:**
- `url` (str): Full URL to HuggingFace inference API endpoint
**Environment Variables:**
- `HUGGINGFACE_URL` or `EMBEDDINGS_HUGGINGFACE_URL`: `url`
</Accordion>
<Accordion title="Instructor">
```python main.py
from crewai.rag.embeddings.providers.instructor.types import InstructorProviderSpec
embedding_model: InstructorProviderSpec = {
"provider": "instructor",
"config": {
"model_name": "hkunlp/instructor-xl",
"device": "cuda",
"instruction": "Represent the document"
}
}
```
**Config Options:**
- `model_name` (str): HuggingFace model ID. Default: `hkunlp/instructor-base`. Options: `hkunlp/instructor-xl`, `hkunlp/instructor-large`, `hkunlp/instructor-base`
- `device` (str): Device to run on. Default: `cpu`. Options: `cpu`, `cuda`, `mps`
- `instruction` (str): Instruction prefix for embeddings
**Environment Variables:**
- `EMBEDDINGS_INSTRUCTOR_MODEL_NAME`: `model_name`
- `EMBEDDINGS_INSTRUCTOR_DEVICE`: `device`
- `EMBEDDINGS_INSTRUCTOR_INSTRUCTION`: `instruction`
</Accordion>
<Accordion title="Sentence Transformer">
```python main.py
from crewai.rag.embeddings.providers.sentence_transformer.types import SentenceTransformerProviderSpec
embedding_model: SentenceTransformerProviderSpec = {
"provider": "sentence-transformer",
"config": {
"model_name": "all-mpnet-base-v2",
"device": "cuda",
"normalize_embeddings": True
}
}
```
**Config Options:**
- `model_name` (str): Sentence Transformers model name. Default: `all-MiniLM-L6-v2`. Options: `all-mpnet-base-v2`, `all-MiniLM-L6-v2`, `paraphrase-multilingual-MiniLM-L12-v2`
- `device` (str): Device to run on. Default: `cpu`. Options: `cpu`, `cuda`, `mps`
- `normalize_embeddings` (bool): Whether to normalize embeddings. Default: `False`
**Environment Variables:**
- `EMBEDDINGS_SENTENCE_TRANSFORMER_MODEL_NAME`: `model_name`
- `EMBEDDINGS_SENTENCE_TRANSFORMER_DEVICE`: `device`
- `EMBEDDINGS_SENTENCE_TRANSFORMER_NORMALIZE_EMBEDDINGS`: `normalize_embeddings`
</Accordion>
<Accordion title="ONNX">
```python main.py
from crewai.rag.embeddings.providers.onnx.types import ONNXProviderSpec
embedding_model: ONNXProviderSpec = {
"provider": "onnx",
"config": {
"preferred_providers": ["CUDAExecutionProvider", "CPUExecutionProvider"]
}
}
```
**Config Options:**
- `preferred_providers` (list[str]): List of ONNX execution providers in order of preference
**Environment Variables:**
- `EMBEDDINGS_ONNX_PREFERRED_PROVIDERS`: `preferred_providers` (comma-separated list)
</Accordion>
<Accordion title="OpenCLIP">
```python main.py
from crewai.rag.embeddings.providers.openclip.types import OpenCLIPProviderSpec
embedding_model: OpenCLIPProviderSpec = {
"provider": "openclip",
"config": {
"model_name": "ViT-B-32",
"checkpoint": "laion2b_s34b_b79k",
"device": "cuda"
}
}
```
**Config Options:**
- `model_name` (str): OpenCLIP model architecture. Default: `ViT-B-32`. Options: `ViT-B-32`, `ViT-B-16`, `ViT-L-14`
- `checkpoint` (str): Pretrained checkpoint name. Default: `laion2b_s34b_b79k`. Options: `laion2b_s34b_b79k`, `laion400m_e32`, `openai`
- `device` (str): Device to run on. Default: `cpu`. Options: `cpu`, `cuda`
**Environment Variables:**
- `EMBEDDINGS_OPENCLIP_MODEL_NAME`: `model_name`
- `EMBEDDINGS_OPENCLIP_CHECKPOINT`: `checkpoint`
- `EMBEDDINGS_OPENCLIP_DEVICE`: `device`
</Accordion>
<Accordion title="Text2Vec">
```python main.py
from crewai.rag.embeddings.providers.text2vec.types import Text2VecProviderSpec
embedding_model: Text2VecProviderSpec = {
"provider": "text2vec",
"config": {
"model_name": "shibing624/text2vec-base-multilingual"
}
}
```
**Config Options:**
- `model_name` (str): Text2Vec model name from HuggingFace. Default: `shibing624/text2vec-base-chinese`. Options: `shibing624/text2vec-base-multilingual`, `shibing624/text2vec-base-chinese`
**Environment Variables:**
- `EMBEDDINGS_TEXT2VEC_MODEL_NAME`: `model_name`
</Accordion>
<Accordion title="Roboflow">
```python main.py
from crewai.rag.embeddings.providers.roboflow.types import RoboflowProviderSpec
embedding_model: RoboflowProviderSpec = {
"provider": "roboflow",
"config": {
"api_key": "your-api-key",
"api_url": "https://infer.roboflow.com"
}
}
```
**Config Options:**
- `api_key` (str): Roboflow API key. Default: `""` (empty string)
- `api_url` (str): Roboflow inference API URL. Default: `https://infer.roboflow.com`
**Environment Variables:**
- `ROBOFLOW_API_KEY` or `EMBEDDINGS_ROBOFLOW_API_KEY`: `api_key`
- `ROBOFLOW_API_URL` or `EMBEDDINGS_ROBOFLOW_API_URL`: `api_url`
</Accordion>
<Accordion title="WatsonX (IBM)">
```python main.py
from crewai.rag.embeddings.providers.ibm.types import WatsonXProviderSpec
embedding_model: WatsonXProviderSpec = {
"provider": "watsonx",
"config": {
"model_id": "ibm/slate-125m-english-rtrvr",
"url": "https://us-south.ml.cloud.ibm.com",
"api_key": "your-api-key",
"project_id": "your-project-id",
"batch_size": 100,
"concurrency_limit": 10,
"persistent_connection": True
}
}
```
**Config Options:**
- `model_id` (str): WatsonX model identifier
- `url` (str): WatsonX API endpoint
- `api_key` (str): IBM Cloud API key
- `project_id` (str): WatsonX project ID
- `space_id` (str): WatsonX space ID (alternative to project_id)
- `batch_size` (int): Batch size for embeddings. Default: `100`
- `concurrency_limit` (int): Maximum concurrent requests. Default: `10`
- `persistent_connection` (bool): Use persistent connections. Default: `True`
- Plus 20+ additional authentication and configuration options
**Environment Variables:**
- `WATSONX_API_KEY` or `EMBEDDINGS_WATSONX_API_KEY`: `api_key`
- `WATSONX_URL` or `EMBEDDINGS_WATSONX_URL`: `url`
- `WATSONX_PROJECT_ID` or `EMBEDDINGS_WATSONX_PROJECT_ID`: `project_id`
- `EMBEDDINGS_WATSONX_MODEL_ID`: `model_id`
- `EMBEDDINGS_WATSONX_SPACE_ID`: `space_id`
- `EMBEDDINGS_WATSONX_BATCH_SIZE`: `batch_size`
- `EMBEDDINGS_WATSONX_CONCURRENCY_LIMIT`: `concurrency_limit`
- `EMBEDDINGS_WATSONX_PERSISTENT_CONNECTION`: `persistent_connection`
</Accordion>
<Accordion title="Custom">
```python main.py
from crewai.rag.core.base_embeddings_callable import EmbeddingFunction
from crewai.rag.embeddings.providers.custom.types import CustomProviderSpec
class MyEmbeddingFunction(EmbeddingFunction):
def __call__(self, input):
# Your custom embedding logic
return embeddings
embedding_model: CustomProviderSpec = {
"provider": "custom",
"config": {
"embedding_callable": MyEmbeddingFunction
}
}
```
**Config Options:**
- `embedding_callable` (type[EmbeddingFunction]): Custom embedding function class
**Note:** Custom embedding functions must implement the `EmbeddingFunction` protocol defined in `crewai.rag.core.base_embeddings_callable`. The `__call__` method should accept input data and return embeddings as a list of numpy arrays (or compatible format that will be normalized). The returned embeddings are automatically normalized and validated.
</Accordion>
</AccordionGroup>
### Notes
- All config fields are optional unless marked as **Required**
- API keys can typically be provided via environment variables instead of config
- Default values are shown where applicable
## Conclusion
The `RagTool` provides a powerful way to create and query knowledge bases from various data sources. By leveraging Retrieval-Augmented Generation, it enables agents to access and retrieve relevant information efficiently, enhancing their ability to provide accurate and contextually appropriate responses.

View File

@@ -18,7 +18,7 @@ These tools enable your agents to interact with cloud services, access cloud sto
Write and upload files to Amazon S3 storage.
</Card>
<Card title="Bedrock Invoke Agent" icon="aws" href="/en/tools/cloud-storage/bedrockinvokeagenttool">
<Card title="Bedrock Invoke Agent" icon="aws" href="/en/tools/integration/bedrockinvokeagenttool">
Invoke Amazon Bedrock agents for AI-powered tasks.
</Card>

View File

@@ -58,10 +58,10 @@ tool = MySQLSearchTool(
),
),
embedder=dict(
provider="google",
provider="google-generativeai",
config=dict(
model="models/embedding-001",
task_type="retrieval_document",
model_name="gemini-embedding-001",
task_type="RETRIEVAL_DOCUMENT",
# title="Embeddings",
),
),

View File

@@ -71,10 +71,10 @@ tool = PGSearchTool(
),
),
embedder=dict(
provider="google", # or openai, ollama, ...
provider="google-generativeai", # or openai, ollama, ...
config=dict(
model="models/embedding-001",
task_type="retrieval_document",
model_name="gemini-embedding-001",
task_type="RETRIEVAL_DOCUMENT",
# title="Embeddings",
),
),

View File

@@ -23,13 +23,15 @@ Here's a minimal example of how to use the tool:
```python
from crewai import Agent
from crewai_tools import QdrantVectorSearchTool
from crewai_tools import QdrantVectorSearchTool, QdrantConfig
# Initialize the tool
# Initialize the tool with QdrantConfig
qdrant_tool = QdrantVectorSearchTool(
qdrant_url="your_qdrant_url",
qdrant_api_key="your_qdrant_api_key",
collection_name="your_collection"
qdrant_config=QdrantConfig(
qdrant_url="your_qdrant_url",
qdrant_api_key="your_qdrant_api_key",
collection_name="your_collection"
)
)
# Create an agent that uses the tool
@@ -82,7 +84,7 @@ def extract_text_from_pdf(pdf_path):
def get_openai_embedding(text):
response = client.embeddings.create(
input=text,
model="text-embedding-3-small"
model="text-embedding-3-large"
)
return response.data[0].embedding
@@ -90,13 +92,13 @@ def get_openai_embedding(text):
def load_pdf_to_qdrant(pdf_path, qdrant, collection_name):
# Extract text from PDF
text_chunks = extract_text_from_pdf(pdf_path)
# Create Qdrant collection
if qdrant.collection_exists(collection_name):
qdrant.delete_collection(collection_name)
qdrant.create_collection(
collection_name=collection_name,
vectors_config=VectorParams(size=1536, distance=Distance.COSINE)
vectors_config=VectorParams(size=3072, distance=Distance.COSINE)
)
# Store embeddings
@@ -120,19 +122,23 @@ pdf_path = "path/to/your/document.pdf"
load_pdf_to_qdrant(pdf_path, qdrant, collection_name)
# Initialize Qdrant search tool
from crewai_tools import QdrantConfig
qdrant_tool = QdrantVectorSearchTool(
qdrant_url=os.getenv("QDRANT_URL"),
qdrant_api_key=os.getenv("QDRANT_API_KEY"),
collection_name=collection_name,
limit=3,
score_threshold=0.35
qdrant_config=QdrantConfig(
qdrant_url=os.getenv("QDRANT_URL"),
qdrant_api_key=os.getenv("QDRANT_API_KEY"),
collection_name=collection_name,
limit=3,
score_threshold=0.35
)
)
# Create CrewAI agents
search_agent = Agent(
role="Senior Semantic Search Agent",
goal="Find and analyze documents based on semantic search",
backstory="""You are an expert research assistant who can find relevant
backstory="""You are an expert research assistant who can find relevant
information using semantic search in a Qdrant database.""",
tools=[qdrant_tool],
verbose=True
@@ -141,7 +147,7 @@ search_agent = Agent(
answer_agent = Agent(
role="Senior Answer Assistant",
goal="Generate answers to questions based on the context provided",
backstory="""You are an expert answer assistant who can generate
backstory="""You are an expert answer assistant who can generate
answers to questions based on the context provided.""",
tools=[qdrant_tool],
verbose=True
@@ -180,21 +186,82 @@ print(result)
## Tool Parameters
### Required Parameters
- `qdrant_url` (str): The URL of your Qdrant server
- `qdrant_api_key` (str): API key for authentication with Qdrant
- `collection_name` (str): Name of the Qdrant collection to search
- `qdrant_config` (QdrantConfig): Configuration object containing all Qdrant settings
### Optional Parameters
### QdrantConfig Parameters
- `qdrant_url` (str): The URL of your Qdrant server
- `qdrant_api_key` (str, optional): API key for authentication with Qdrant
- `collection_name` (str): Name of the Qdrant collection to search
- `limit` (int): Maximum number of results to return (default: 3)
- `score_threshold` (float): Minimum similarity score threshold (default: 0.35)
- `filter` (Any, optional): Qdrant Filter instance for advanced filtering (default: None)
### Optional Tool Parameters
- `custom_embedding_fn` (Callable[[str], list[float]]): Custom function for text vectorization
- `qdrant_package` (str): Base package path for Qdrant (default: "qdrant_client")
- `client` (Any): Pre-initialized Qdrant client (optional)
## Advanced Filtering
The QdrantVectorSearchTool supports powerful filtering capabilities to refine your search results:
### Dynamic Filtering
Use `filter_by` and `filter_value` parameters in your search to filter results on-the-fly:
```python
# Agent will use these parameters when calling the tool
# The tool schema accepts filter_by and filter_value
# Example: search with category filter
# Results will be filtered where category == "technology"
```
### Preset Filters with QdrantConfig
For complex filtering, use Qdrant Filter instances in your configuration:
```python
from qdrant_client.http import models as qmodels
from crewai_tools import QdrantVectorSearchTool, QdrantConfig
# Create a filter for specific conditions
preset_filter = qmodels.Filter(
must=[
qmodels.FieldCondition(
key="category",
match=qmodels.MatchValue(value="research")
),
qmodels.FieldCondition(
key="year",
match=qmodels.MatchValue(value=2024)
)
]
)
# Initialize tool with preset filter
qdrant_tool = QdrantVectorSearchTool(
qdrant_config=QdrantConfig(
qdrant_url="your_url",
qdrant_api_key="your_key",
collection_name="your_collection",
filter=preset_filter # Preset filter applied to all searches
)
)
```
### Combining Filters
The tool automatically combines preset filters from `QdrantConfig` with dynamic filters from `filter_by` and `filter_value`:
```python
# If QdrantConfig has a preset filter for category="research"
# And the search uses filter_by="year", filter_value=2024
# Both filters will be combined (AND logic)
```
## Search Parameters
The tool accepts these parameters in its schema:
- `query` (str): The search query to find similar documents
- `filter_by` (str, optional): Metadata field to filter on
- `filter_value` (str, optional): Value to filter by
- `filter_value` (Any, optional): Value to filter by
## Return Format
@@ -214,7 +281,7 @@ The tool returns results in JSON format:
## Default Embedding
By default, the tool uses OpenAI's `text-embedding-3-small` model for vectorization. This requires:
By default, the tool uses OpenAI's `text-embedding-3-large` model for vectorization. This requires:
- OpenAI API key set in environment: `OPENAI_API_KEY`
## Custom Embeddings
@@ -240,18 +307,22 @@ def custom_embeddings(text: str) -> list[float]:
# Tokenize and get model outputs
inputs = tokenizer(text, return_tensors="pt", padding=True, truncation=True)
outputs = model(**inputs)
# Use mean pooling to get text embedding
embeddings = outputs.last_hidden_state.mean(dim=1)
# Convert to list of floats and return
return embeddings[0].tolist()
# Use custom embeddings with the tool
from crewai_tools import QdrantConfig
tool = QdrantVectorSearchTool(
qdrant_url="your_url",
qdrant_api_key="your_key",
collection_name="your_collection",
qdrant_config=QdrantConfig(
qdrant_url="your_url",
qdrant_api_key="your_key",
collection_name="your_collection"
),
custom_embedding_fn=custom_embeddings # Pass your custom function
)
```
@@ -269,4 +340,4 @@ Required environment variables:
```bash
export QDRANT_URL="your_qdrant_url" # If not provided in constructor
export QDRANT_API_KEY="your_api_key" # If not provided in constructor
export OPENAI_API_KEY="your_openai_key" # If using default embeddings
export OPENAI_API_KEY="your_openai_key" # If using default embeddings

View File

@@ -54,25 +54,25 @@ The following parameters can be used to customize the `CSVSearchTool`'s behavior
By default, the tool uses OpenAI for both embeddings and summarization. To customize the model, you can use a config dictionary as follows:
```python Code
from chromadb.config import Settings
tool = CSVSearchTool(
config=dict(
llm=dict(
provider="ollama", # or google, openai, anthropic, llama2, ...
config=dict(
model="llama2",
# temperature=0.5,
# top_p=1,
# stream=true,
),
),
embedder=dict(
provider="google", # or openai, ollama, ...
config=dict(
model="models/embedding-001",
task_type="retrieval_document",
# title="Embeddings",
),
),
)
config={
"embedding_model": {
"provider": "openai",
"config": {
"model": "text-embedding-3-small",
# "api_key": "sk-...",
},
},
"vectordb": {
"provider": "chromadb", # or "qdrant"
"config": {
# "settings": Settings(persist_directory="/content/chroma", allow_reset=True, is_persistent=True),
# from qdrant_client.models import VectorParams, Distance
# "vectors_config": VectorParams(size=384, distance=Distance.COSINE),
}
},
}
)
```

View File

@@ -46,23 +46,25 @@ tool = DirectorySearchTool(directory='/path/to/directory')
The DirectorySearchTool uses OpenAI for embeddings and summarization by default. Customization options for these settings include changing the model provider and configuration, enhancing flexibility for advanced users.
```python Code
from chromadb.config import Settings
tool = DirectorySearchTool(
config=dict(
llm=dict(
provider="ollama", # Options include ollama, google, anthropic, llama2, and more
config=dict(
model="llama2",
# Additional configurations here
),
),
embedder=dict(
provider="google", # or openai, ollama, ...
config=dict(
model="models/embedding-001",
task_type="retrieval_document",
# title="Embeddings",
),
),
)
config={
"embedding_model": {
"provider": "openai",
"config": {
"model": "text-embedding-3-small",
# "api_key": "sk-...",
},
},
"vectordb": {
"provider": "chromadb", # or "qdrant"
"config": {
# "settings": Settings(persist_directory="/content/chroma", allow_reset=True, is_persistent=True),
# from qdrant_client.models import VectorParams, Distance
# "vectors_config": VectorParams(size=384, distance=Distance.COSINE),
}
},
}
)
```

View File

@@ -56,25 +56,25 @@ The following parameters can be used to customize the `DOCXSearchTool`'s behavio
By default, the tool uses OpenAI for both embeddings and summarization. To customize the model, you can use a config dictionary as follows:
```python Code
from chromadb.config import Settings
tool = DOCXSearchTool(
config=dict(
llm=dict(
provider="ollama", # or google, openai, anthropic, llama2, ...
config=dict(
model="llama2",
# temperature=0.5,
# top_p=1,
# stream=true,
),
),
embedder=dict(
provider="google", # or openai, ollama, ...
config=dict(
model="models/embedding-001",
task_type="retrieval_document",
# title="Embeddings",
),
),
)
config={
"embedding_model": {
"provider": "openai",
"config": {
"model": "text-embedding-3-small",
# "api_key": "sk-...",
},
},
"vectordb": {
"provider": "chromadb", # or "qdrant"
"config": {
# "settings": Settings(persist_directory="/content/chroma", allow_reset=True, is_persistent=True),
# from qdrant_client.models import VectorParams, Distance
# "vectors_config": VectorParams(size=384, distance=Distance.COSINE),
}
},
}
)
```

View File

@@ -64,10 +64,10 @@ tool = JSONSearchTool(
},
},
"embedding_model": {
"provider": "google", # or openai, ollama, ...
"provider": "google-generativeai", # or openai, ollama, ...
"config": {
"model": "models/embedding-001",
"task_type": "retrieval_document",
"model_name": "gemini-embedding-001",
"task_type": "RETRIEVAL_DOCUMENT",
# Further customization options can be added here.
},
},

View File

@@ -48,27 +48,25 @@ tool = MDXSearchTool(mdx='path/to/your/document.mdx')
The tool defaults to using OpenAI for embeddings and summarization. For customization, utilize a configuration dictionary as shown below:
```python Code
from chromadb.config import Settings
tool = MDXSearchTool(
config=dict(
llm=dict(
provider="ollama", # Options include google, openai, anthropic, llama2, etc.
config=dict(
model="llama2",
# Optional parameters can be included here.
# temperature=0.5,
# top_p=1,
# stream=true,
),
),
embedder=dict(
provider="google", # or openai, ollama, ...
config=dict(
model="models/embedding-001",
task_type="retrieval_document",
# Optional title for the embeddings can be added here.
# title="Embeddings",
),
),
)
config={
"embedding_model": {
"provider": "openai",
"config": {
"model": "text-embedding-3-small",
# "api_key": "sk-...",
},
},
"vectordb": {
"provider": "chromadb", # or "qdrant"
"config": {
# "settings": Settings(persist_directory="/content/chroma", allow_reset=True, is_persistent=True),
# from qdrant_client.models import VectorParams, Distance
# "vectors_config": VectorParams(size=384, distance=Distance.COSINE),
}
},
}
)
```

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