Compare commits

..

6 Commits

Author SHA1 Message Date
Devin AI
74c1f7492a Fix lint: Apply automatic fixes from ruff linter
Co-Authored-By: Joe Moura <joao@crewai.com>
2025-04-19 23:16:22 +00:00
Devin AI
559442853e Fix lint: Add unittest import to match project conventions
Co-Authored-By: Joe Moura <joao@crewai.com>
2025-04-19 23:14:44 +00:00
Devin AI
65dd3c1bdc Fix lint: Correct import order in test file
Co-Authored-By: Joe Moura <joao@crewai.com>
2025-04-19 23:12:48 +00:00
Devin AI
5ebd3ce269 Fix CI issues: Fix import sorting and type error
Co-Authored-By: Joe Moura <joao@crewai.com>
2025-04-19 23:10:40 +00:00
Devin AI
7ff66aaf71 Fix security: Use mock approach in tests instead of hardcoded API keys
Co-Authored-By: Joe Moura <joao@crewai.com>
2025-04-19 23:08:16 +00:00
Devin AI
f7ecc0bc47 Fix issue #2647: Make planning LLM inherit authentication parameters from agent's LLM
Co-Authored-By: Joe Moura <joao@crewai.com>
2025-04-19 23:06:52 +00:00
15 changed files with 176 additions and 167 deletions

View File

@@ -4,36 +4,6 @@ description: View the latest updates and changes to CrewAI
icon: timeline
---
<Update label="2025-04-07" description="v0.114.0">
## Release Highlights
<Frame>
<img src="/images/v01140.png" />
</Frame>
**New Features & Enhancements**
- Agents as an atomic unit. (`Agent(...).kickoff()`)
- Support for [Custom LLM implementations](https://docs.crewai.com/guides/advanced/custom-llm).
- Integrated External Memory and [Opik observability](https://docs.crewai.com/how-to/opik-observability).
- Enhanced YAML extraction.
- Multimodal agent validation.
- Added Secure fingerprints for agents and crews.
**Core Improvements & Fixes**
- Improved serialization, agent copying, and Python compatibility.
- Added wildcard support to `emit()`
- Added support for additional router calls and context window adjustments.
- Fixed typing issues, validation, and import statements.
- Improved method performance.
- Enhanced agent task handling, event emissions, and memory management.
- Fixed CLI issues, conditional tasks, cloning behavior, and tool outputs.
**Documentation & Guides**
- Improved documentation structure, theme, and organization.
- Added guides for Local NVIDIA NIM with WSL2, W&B Weave, and Arize Phoenix.
- Updated tool configuration examples, prompts, and observability docs.
- Guide on using singular agents within Flows.
</Update>
<Update label="2025-03-17" description="v0.108.0">
**Features**
- Converted tabs to spaces in `crew.py` template

View File

@@ -1,10 +1,10 @@
---
title: LangChain Tool
description: The `LangChainTool` is a wrapper for LangChain tools and query engines.
title: Using LangChain Tools
description: Learn how to integrate LangChain tools with CrewAI agents to enhance search-based queries and more.
icon: link
---
## `LangChainTool`
## Using LangChain Tools
<Info>
CrewAI seamlessly integrates with LangChain's comprehensive [list of tools](https://python.langchain.com/docs/integrations/tools/), all of which can be used with CrewAI.

View File

@@ -0,0 +1,71 @@
---
title: Using LlamaIndex Tools
description: Learn how to integrate LlamaIndex tools with CrewAI agents to enhance search-based queries and more.
icon: toolbox
---
## Using LlamaIndex Tools
<Info>
CrewAI seamlessly integrates with LlamaIndexs comprehensive toolkit for RAG (Retrieval-Augmented Generation) and agentic pipelines, enabling advanced search-based queries and more.
</Info>
Here are the available built-in tools offered by LlamaIndex.
```python Code
from crewai import Agent
from crewai_tools import LlamaIndexTool
# Example 1: Initialize from FunctionTool
from llama_index.core.tools import FunctionTool
your_python_function = lambda ...: ...
og_tool = FunctionTool.from_defaults(
your_python_function,
name="<name>",
description='<description>'
)
tool = LlamaIndexTool.from_tool(og_tool)
# Example 2: Initialize from LlamaHub Tools
from llama_index.tools.wolfram_alpha import WolframAlphaToolSpec
wolfram_spec = WolframAlphaToolSpec(app_id="<app_id>")
wolfram_tools = wolfram_spec.to_tool_list()
tools = [LlamaIndexTool.from_tool(t) for t in wolfram_tools]
# Example 3: Initialize Tool from a LlamaIndex Query Engine
query_engine = index.as_query_engine()
query_tool = LlamaIndexTool.from_query_engine(
query_engine,
name="Uber 2019 10K Query Tool",
description="Use this tool to lookup the 2019 Uber 10K Annual Report"
)
# Create and assign the tools to an agent
agent = Agent(
role='Research Analyst',
goal='Provide up-to-date market analysis',
backstory='An expert analyst with a keen eye for market trends.',
tools=[tool, *tools, query_tool]
)
# rest of the code ...
```
## Steps to Get Started
To effectively use the LlamaIndexTool, follow these steps:
<Steps>
<Step title="Package Installation">
Make sure that `crewai[tools]` package is installed in your Python environment:
<CodeGroup>
```shell Terminal
pip install 'crewai[tools]'
```
</CodeGroup>
</Step>
<Step title="Install and Use LlamaIndex">
Follow the LlamaIndex documentation [LlamaIndex Documentation](https://docs.llamaindex.ai/) to set up a RAG/agent pipeline.
</Step>
</Steps>

View File

@@ -1,13 +1,9 @@
---
title: Custom LLM Implementation
description: Learn how to create custom LLM implementations in CrewAI.
icon: code
---
## Custom LLM Implementations
# Custom LLM Implementations
CrewAI now supports custom LLM implementations through the `BaseLLM` abstract base class. This allows you to create your own LLM implementations that don't rely on litellm's authentication mechanism.
## Using Custom LLM Implementations
To create a custom LLM implementation, you need to:
1. Inherit from the `BaseLLM` abstract base class

View File

@@ -11,21 +11,22 @@
"navigation": {
"tabs": [
{
"tab": "Documentation",
"tab": "Get Started",
"groups": [
{
"group": "Get Started",
"pages": [
"introduction",
"installation",
"quickstart"
"quickstart",
"changelog"
]
},
{
"group": "Guides",
"pages": [
{
"group": "Strategy",
"group": "Concepts",
"pages": [
"guides/concepts/evaluating-use-cases"
]
@@ -78,6 +79,41 @@
"concepts/event-listener"
]
},
{
"group": "How to Guides",
"pages": [
"how-to/create-custom-tools",
"how-to/sequential-process",
"how-to/hierarchical-process",
"how-to/custom-manager-agent",
"how-to/llm-connections",
"how-to/customizing-agents",
"how-to/multimodal-agents",
"how-to/coding-agents",
"how-to/force-tool-output-as-result",
"how-to/human-input-on-execution",
"how-to/kickoff-async",
"how-to/kickoff-for-each",
"how-to/replay-tasks-from-latest-crew-kickoff",
"how-to/conditional-tasks",
"how-to/langchain-tools",
"how-to/llamaindex-tools"
]
},
{
"group": "Agent Monitoring & Observability",
"pages": [
"how-to/agentops-observability",
"how-to/arize-phoenix-observability",
"how-to/langfuse-observability",
"how-to/langtrace-observability",
"how-to/mlflow-observability",
"how-to/openlit-observability",
"how-to/opik-observability",
"how-to/portkey-observability",
"how-to/weave-integration"
]
},
{
"group": "Tools",
"pages": [
@@ -105,7 +141,6 @@
"tools/hyperbrowserloadtool",
"tools/linkupsearchtool",
"tools/llamaindextool",
"tools/langchaintool",
"tools/serperdevtool",
"tools/s3readertool",
"tools/s3writertool",
@@ -135,40 +170,6 @@
"tools/youtubevideosearchtool"
]
},
{
"group": "Agent Monitoring & Observability",
"pages": [
"how-to/agentops-observability",
"how-to/arize-phoenix-observability",
"how-to/langfuse-observability",
"how-to/langtrace-observability",
"how-to/mlflow-observability",
"how-to/openlit-observability",
"how-to/opik-observability",
"how-to/portkey-observability",
"how-to/weave-integration"
]
},
{
"group": "Learn",
"pages": [
"how-to/conditional-tasks",
"how-to/coding-agents",
"how-to/create-custom-tools",
"how-to/custom-llm",
"how-to/custom-manager-agent",
"how-to/customizing-agents",
"how-to/force-tool-output-as-result",
"how-to/hierarchical-process",
"how-to/human-input-on-execution",
"how-to/kickoff-async",
"how-to/kickoff-for-each",
"how-to/llm-connections",
"how-to/multimodal-agents",
"how-to/replay-tasks-from-latest-crew-kickoff",
"how-to/sequential-process"
]
},
{
"group": "Telemetry",
"pages": [
@@ -187,35 +188,19 @@
]
}
]
},
{
"tab": "Releases",
"groups": [
{
"group": "Releases",
"pages": [
"changelog"
]
}
]
}
],
"global": {
"anchors": [
{
"anchor": "Website",
"href": "https://crewai.com",
"icon": "globe"
},
{
"anchor": "Forum",
"anchor": "Community",
"href": "https://community.crewai.com",
"icon": "discourse"
},
{
"anchor": "Get Help",
"href": "mailto:support@crewai.com",
"icon": "headset"
"anchor": "Tutorials",
"href": "https://www.youtube.com/@crewAIInc",
"icon": "youtube"
}
]
}
@@ -229,12 +214,6 @@
"strict": false
},
"navbar": {
"links": [
{
"label": "Start Free Trial",
"href": "https://app.crewai.com"
}
],
"primary": {
"type": "github",
"href": "https://github.com/crewAIInc/crewAI"

View File

@@ -1,5 +1,5 @@
---
title: Custom Manager Agent
title: Create Your Own Manager Agent
description: Learn how to set a custom agent as the manager in CrewAI, providing more control over task management and coordination.
icon: user-shield
---

View File

@@ -20,8 +20,10 @@ Here's an example of how to replay from a task:
To use the replay feature, follow these steps:
<Steps>
<Step title="Open your terminal or command prompt."></Step>
<Step title="Navigate to the directory where your CrewAI project is located."></Step>
<Step title="Open your terminal or command prompt.">
</Step>
<Step title="Navigate to the directory where your CrewAI project is located.">
</Step>
<Step title="Run the following commands:">
To view the latest kickoff task_ids use:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 MiB

View File

@@ -336,22 +336,9 @@ email_summarizer_task:
- research_task
```
## Deploying Your Crew
## Deploying Your Project
The easiest way to deploy your crew to production is through [CrewAI Enterprise](http://app.crewai.com).
Watch this video tutorial for a step-by-step demonstration of deploying your crew to [CrewAI Enterprise](http://app.crewai.com) using the CLI.
<iframe
width="100%"
height="400"
src="https://www.youtube.com/embed/3EqSV-CYDZA"
title="CrewAI Deployment Guide"
frameborder="0"
style={{ borderRadius: '10px' }}
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen
></iframe>
The easiest way to deploy your crew is through [CrewAI Enterprise](http://app.crewai.com), where you can deploy your crew in a few clicks.
<CardGroup cols={2}>
<Card

View File

@@ -720,8 +720,13 @@ class Crew(BaseModel):
def _handle_crew_planning(self):
"""Handles the Crew planning."""
self._logger.log("info", "Planning the crew execution")
agent_llm = self.agents[0].llm if self.agents and hasattr(self.agents[0], 'llm') else None
result = CrewPlanner(
tasks=self.tasks, planning_agent_llm=self.planning_llm
tasks=self.tasks,
planning_agent_llm=self.planning_llm,
agent_llm=agent_llm
)._handle_crew_planning()
for task, step_plan in zip(self.tasks, result.list_of_plans_per_task):

View File

@@ -358,12 +358,7 @@ class LLM(BaseLLM):
}
# Remove None values from params
params = {k: v for k, v in params.items() if v is not None}
if "o4-mini" in self.model:
params.pop("stop", None)
return params
return {k: v for k, v in params.items() if v is not None}
def _handle_streaming_response(
self,

View File

@@ -28,11 +28,23 @@ class PlannerTaskPydanticOutput(BaseModel):
class CrewPlanner:
"""Plans and coordinates the execution of crew tasks."""
def __init__(self, tasks: List[Task], planning_agent_llm: Optional[Any] = None):
def __init__(self, tasks: List[Task], planning_agent_llm: Optional[Any] = None, agent_llm: Optional[Any] = None):
self.tasks = tasks
if planning_agent_llm is None:
self.planning_agent_llm = "gpt-4o-mini"
if agent_llm is not None and hasattr(agent_llm, "base_url") and agent_llm.base_url is not None:
from crewai.llm import LLM
self.planning_agent_llm = LLM(
model="gpt-4o-mini",
base_url=agent_llm.base_url,
api_key=getattr(agent_llm, "api_key", None),
organization=getattr(agent_llm, "organization", None),
api_version=getattr(agent_llm, "api_version", None),
extra_headers=getattr(agent_llm, "extra_headers", None)
)
else:
from crewai.llm import LLM
self.planning_agent_llm = LLM(model="gpt-4o-mini")
else:
self.planning_agent_llm = planning_agent_llm

View File

@@ -533,39 +533,3 @@ def test_handle_streaming_tool_calls_no_tools(mock_emit):
expected_completed_llm_call=1,
expected_final_chunk_result=response,
)
def test_llm_o4_mini_stop_parameter():
"""Test that o4-mini model works correctly without stop parameter."""
llm = LLM(model="o4-mini", stop=["STOP", "END"])
# Check that stop parameter is set
assert llm.stop == ["STOP", "END"]
params = llm._prepare_completion_params(messages=[{"role": "user", "content": "Hello"}])
assert "stop" not in params
with patch("litellm.completion") as mock_completion:
# Create a mock response
mock_message = MagicMock()
mock_message.content = "Test response"
mock_choice = MagicMock()
mock_choice.message = mock_message
mock_response = MagicMock()
mock_response.choices = [mock_choice]
mock_response.usage = {
"prompt_tokens": 5,
"completion_tokens": 5,
"total_tokens": 10,
}
# Set up the mock to return our response
mock_completion.return_value = mock_response
response = llm.call(messages=[{"role": "user", "content": "Hello, world!"}])
assert response == "Test response"
call_args = mock_completion.call_args[1]
assert "stop" not in call_args

View File

@@ -0,0 +1,28 @@
import unittest
from unittest.mock import MagicMock
from crewai import Task
from crewai.utilities.planning_handler import CrewPlanner
def test_planning_llm_inherits_auth_params():
"""Test that planning LLM inherits authentication parameters from agent LLM."""
mock_llm = MagicMock()
mock_llm.base_url = "https://api.custom-provider.com/v1"
mock_llm.api_version = "2023-05-15"
task = Task(
description="Test Task",
expected_output="Test Output"
)
planner = CrewPlanner(
tasks=[task],
planning_agent_llm=None, # This should trigger the inheritance logic
agent_llm=mock_llm
)
assert hasattr(planner, 'planning_agent_llm')
assert hasattr(planner.planning_agent_llm, 'base_url')
assert planner.planning_agent_llm.base_url == "https://api.custom-provider.com/v1"
assert planner.planning_agent_llm.api_version == "2023-05-15"