Compare commits

...

5 Commits

Author SHA1 Message Date
Devin AI
f36d48d57e feat: Enhance Bedrock authentication with improved docs, validation, and tests
- Add clearer authentication method comments in documentation examples
- Include security best practices for API key usage
- Add CLI validation hints for AWS Bedrock API key format
- Implement comprehensive error handling tests (timeout, rate limit, invalid key)
- Add connection error and retry scenario test cases
- Maintain consistency between English and Portuguese documentation

Addresses AI code review feedback on PR #3126

Co-Authored-By: Jo\u00E3o <joao@crewai.com>
2025-07-09 12:24:56 +00:00
Devin AI
3eea890409 fix: Remove unused pytest import to resolve lint check
- Remove unused pytest import from test_bedrock_authentication.py
- Fixes F401 lint error that was causing CI failure

Co-Authored-By: Jo\u00E3o <joao@crewai.com>
2025-07-09 12:18:33 +00:00
Devin AI
a670b2b35e feat: Add AWS Bedrock API key authentication support
- Add AWS_BEARER_TOKEN_BEDROCK environment variable to CLI constants
- Update English and Portuguese documentation with both IAM and API key auth methods
- Document boto3 v1.393+ requirement for API key authentication
- Add comprehensive tests for both authentication methods
- Include links to AWS console for API key generation

Addresses issue #3125

Co-Authored-By: Jo\u00E3o <joao@crewai.com>
2025-07-09 12:15:57 +00:00
Lucas Gomide
f071966951 docs: add docs about Agent.kickoff usage (#3121)
Some checks failed
Notify Downstream / notify-downstream (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
Co-authored-by: Tony Kipkemboi <iamtonykipkemboi@gmail.com>
2025-07-08 16:15:40 -04:00
Lucas Gomide
318310bb7a docs: add docs about Agent repository (#3122) 2025-07-08 15:56:08 -04:00
7 changed files with 496 additions and 8 deletions

View File

@@ -94,7 +94,7 @@
"pages": [
"en/guides/advanced/customizing-prompts",
"en/guides/advanced/fingerprinting"
]
}
]
@@ -296,7 +296,8 @@
"en/enterprise/features/webhook-streaming",
"en/enterprise/features/traces",
"en/enterprise/features/hallucination-guardrail",
"en/enterprise/features/integrations"
"en/enterprise/features/integrations",
"en/enterprise/features/agent-repositories"
]
},
{
@@ -373,7 +374,7 @@
}
]
}
]
},
{
@@ -730,7 +731,7 @@
}
]
}
]
}
]
@@ -774,7 +775,7 @@
"destination": "/en/introduction"
},
{
"source": "/installation",
"source": "/installation",
"destination": "/en/installation"
},
{

View File

@@ -526,6 +526,103 @@ agent = Agent(
The context window management feature works automatically in the background. You don't need to call any special functions - just set `respect_context_window` to your preferred behavior and CrewAI handles the rest!
</Note>
## Direct Agent Interaction with `kickoff()`
Agents can be used directly without going through a task or crew workflow using the `kickoff()` method. This provides a simpler way to interact with an agent when you don't need the full crew orchestration capabilities.
### How `kickoff()` Works
The `kickoff()` method allows you to send messages directly to an agent and get a response, similar to how you would interact with an LLM but with all the agent's capabilities (tools, reasoning, etc.).
```python Code
from crewai import Agent
from crewai_tools import SerperDevTool
# Create an agent
researcher = Agent(
role="AI Technology Researcher",
goal="Research the latest AI developments",
tools=[SerperDevTool()],
verbose=True
)
# Use kickoff() to interact directly with the agent
result = researcher.kickoff("What are the latest developments in language models?")
# Access the raw response
print(result.raw)
```
### Parameters and Return Values
| Parameter | Type | Description |
| :---------------- | :---------------------------------- | :------------------------------------------------------------------------ |
| `messages` | `Union[str, List[Dict[str, str]]]` | Either a string query or a list of message dictionaries with role/content |
| `response_format` | `Optional[Type[Any]]` | Optional Pydantic model for structured output |
The method returns a `LiteAgentOutput` object with the following properties:
- `raw`: String containing the raw output text
- `pydantic`: Parsed Pydantic model (if a `response_format` was provided)
- `agent_role`: Role of the agent that produced the output
- `usage_metrics`: Token usage metrics for the execution
### Structured Output
You can get structured output by providing a Pydantic model as the `response_format`:
```python Code
from pydantic import BaseModel
from typing import List
class ResearchFindings(BaseModel):
main_points: List[str]
key_technologies: List[str]
future_predictions: str
# Get structured output
result = researcher.kickoff(
"Summarize the latest developments in AI for 2025",
response_format=ResearchFindings
)
# Access structured data
print(result.pydantic.main_points)
print(result.pydantic.future_predictions)
```
### Multiple Messages
You can also provide a conversation history as a list of message dictionaries:
```python Code
messages = [
{"role": "user", "content": "I need information about large language models"},
{"role": "assistant", "content": "I'd be happy to help with that! What specifically would you like to know?"},
{"role": "user", "content": "What are the latest developments in 2025?"}
]
result = researcher.kickoff(messages)
```
### Async Support
An asynchronous version is available via `kickoff_async()` with the same parameters:
```python Code
import asyncio
async def main():
result = await researcher.kickoff_async("What are the latest developments in AI?")
print(result.raw)
asyncio.run(main())
```
<Note>
The `kickoff()` method uses a `LiteAgent` internally, which provides a simpler execution flow while preserving all of the agent's configuration (role, goal, backstory, tools, etc.).
</Note>
## Important Considerations and Best Practices
### Security and Code Execution

View File

@@ -311,20 +311,47 @@ In this section, you'll find detailed examples that help you select, configure,
</Accordion>
<Accordion title="AWS Bedrock">
Amazon Bedrock supports two authentication methods:
**Method 1: IAM Role Authentication (Recommended for Production)**
```toml Code
AWS_ACCESS_KEY_ID=<your-access-key>
AWS_SECRET_ACCESS_KEY=<your-secret-key>
AWS_DEFAULT_REGION=<your-region>
```
**Method 2: API Key Authentication (Recommended for Development)**
```toml Code
AWS_BEARER_TOKEN_BEDROCK=<your-api-key>
AWS_DEFAULT_REGION=<your-region>
```
Example usage in your CrewAI project:
```python Code
# Method 1: IAM Role Authentication (uses AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY)
# Set environment variables: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_DEFAULT_REGION
llm = LLM(
model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0"
)
# Method 2: API Key Authentication (uses AWS_BEARER_TOKEN_BEDROCK)
# Set environment variables: AWS_BEARER_TOKEN_BEDROCK, AWS_DEFAULT_REGION
llm = LLM(
model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0"
)
```
Before using Amazon Bedrock, make sure you have boto3 installed in your environment
**Requirements:**
- Before using Amazon Bedrock, make sure you have boto3 v1.393+ installed in your environment
- For API key authentication, you can generate a 30-day API key from the [Amazon Bedrock console](https://console.aws.amazon.com/bedrock/)
- For production applications, use IAM roles or temporary credentials instead of long-term API keys
**Security Best Practices:**
- API keys expire after 30 days and should be rotated regularly
- Use IAM roles for production environments for better security
- Store API keys securely and never commit them to version control
- Monitor API usage and set up alerts for unusual activity
- Consider using temporary credentials for enhanced security
[Amazon Bedrock](https://docs.aws.amazon.com/bedrock/latest/userguide/models-regions.html) is a managed service that provides access to multiple foundation models from top AI companies through a unified API, enabling secure and responsible AI application development.

View File

@@ -0,0 +1,155 @@
---
title: 'Agent Repositories'
description: 'Learn how to use Agent Repositories to share and reuse your agents across teams and projects'
icon: 'database'
---
Agent Repositories allow enterprise users to store, share, and reuse agent definitions across teams and projects. This feature enables organizations to maintain a centralized library of standardized agents, promoting consistency and reducing duplication of effort.
## Benefits of Agent Repositories
- **Standardization**: Maintain consistent agent definitions across your organization
- **Reusability**: Create an agent once and use it in multiple crews and projects
- **Governance**: Implement organization-wide policies for agent configurations
- **Collaboration**: Enable teams to share and build upon each other's work
## Using Agent Repositories
### Prerequisites
1. You must have an account at CrewAI, try the [free plan](https://app.crewai.com).
2. You need to be authenticated using the CrewAI CLI.
3. If you have more than one organization, make sure you are switched to the correct organization using the CLI command:
```bash
crewai org switch <org_id>
```
### Creating and Managing Agents in Repositories
To create and manage agents in repositories,Enterprise Dashboard.
### Loading Agents from Repositories
You can load agents from repositories in your code using the `from_repository` parameter:
```python
from crewai import Agent
# Create an agent by loading it from a repository
# The agent is loaded with all its predefined configurations
researcher = Agent(
from_repository="market-research-agent"
)
```
### Overriding Repository Settings
You can override specific settings from the repository by providing them in the configuration:
```python
researcher = Agent(
from_repository="market-research-agent",
goal="Research the latest trends in AI development", # Override the repository goal
verbose=True # Add a setting not in the repository
)
```
### Example: Creating a Crew with Repository Agents
```python
from crewai import Crew, Agent, Task
# Load agents from repositories
researcher = Agent(
from_repository="market-research-agent"
)
writer = Agent(
from_repository="content-writer-agent"
)
# Create tasks
research_task = Task(
description="Research the latest trends in AI",
agent=researcher
)
writing_task = Task(
description="Write a comprehensive report based on the research",
agent=writer
)
# Create the crew
crew = Crew(
agents=[researcher, writer],
tasks=[research_task, writing_task],
verbose=True
)
# Run the crew
result = crew.kickoff()
```
### Example: Using `kickoff()` with Repository Agents
You can also use repository agents directly with the `kickoff()` method for simpler interactions:
```python
from crewai import Agent
from pydantic import BaseModel
from typing import List
# Define a structured output format
class MarketAnalysis(BaseModel):
key_trends: List[str]
opportunities: List[str]
recommendation: str
# Load an agent from repository
analyst = Agent(
from_repository="market-analyst-agent",
verbose=True
)
# Get a free-form response
result = analyst.kickoff("Analyze the AI market in 2025")
print(result.raw) # Access the raw response
# Get structured output
structured_result = analyst.kickoff(
"Provide a structured analysis of the AI market in 2025",
response_format=MarketAnalysis
)
# Access structured data
print(f"Key Trends: {structured_result.pydantic.key_trends}")
print(f"Recommendation: {structured_result.pydantic.recommendation}")
```
## Best Practices
1. **Naming Convention**: Use clear, descriptive names for your repository agents
2. **Documentation**: Include comprehensive descriptions for each agent
3. **Tool Management**: Ensure that tools referenced by repository agents are available in your environment
4. **Access Control**: Manage permissions to ensure only authorized team members can modify repository agents
## Organization Management
To switch between organizations or see your current organization, use the CrewAI CLI:
```bash
# View current organization
crewai org current
# Switch to a different organization
crewai org switch <org_id>
# List all available organizations
crewai org list
```
<Note>
When loading agents from repositories, you must be authenticated and switched to the correct organization. If you receive errors, check your authentication status and organization settings using the CLI commands above.
</Note>

View File

@@ -309,20 +309,47 @@ Nesta seção, você encontrará exemplos detalhados que ajudam a selecionar, co
</Accordion>
<Accordion title="AWS Bedrock">
O Amazon Bedrock suporta dois métodos de autenticação:
**Método 1: Autenticação por Função IAM (Recomendado para Produção)**
```toml Code
AWS_ACCESS_KEY_ID=<your-access-key>
AWS_SECRET_ACCESS_KEY=<your-secret-key>
AWS_DEFAULT_REGION=<your-region>
```
**Método 2: Autenticação por Chave de API (Recomendado para Desenvolvimento)**
```toml Code
AWS_BEARER_TOKEN_BEDROCK=<your-api-key>
AWS_DEFAULT_REGION=<your-region>
```
Exemplo de uso em seu projeto CrewAI:
```python Code
# Método 1: Autenticação por Função IAM (usa AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY)
# Configure as variáveis de ambiente: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_DEFAULT_REGION
llm = LLM(
model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0"
)
# Método 2: Autenticação por Chave de API (usa AWS_BEARER_TOKEN_BEDROCK)
# Configure as variáveis de ambiente: AWS_BEARER_TOKEN_BEDROCK, AWS_DEFAULT_REGION
llm = LLM(
model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0"
)
```
Antes de usar o Amazon Bedrock, certifique-se de ter o boto3 instalado em seu ambiente
**Requisitos:**
- Antes de usar o Amazon Bedrock, certifique-se de ter o boto3 v1.393+ instalado em seu ambiente
- Para autenticação por chave de API, você pode gerar uma chave de 30 dias no [console do Amazon Bedrock](https://console.aws.amazon.com/bedrock/)
- Para aplicações de produção, use funções IAM ou credenciais temporárias em vez de chaves de API de longo prazo
**Melhores Práticas de Segurança:**
- Chaves de API expiram após 30 dias e devem ser rotacionadas regularmente
- Use funções IAM para ambientes de produção para melhor segurança
- Armazene chaves de API com segurança e nunca as confirme no controle de versão
- Monitore o uso da API e configure alertas para atividades incomuns
- Considere usar credenciais temporárias para segurança aprimorada
[Amazon Bedrock](https://docs.aws.amazon.com/bedrock/latest/userguide/models-regions.html) é um serviço gerenciado que fornece acesso a múltiplos modelos fundamentais dos principais provedores de IA através de uma API unificada, permitindo o desenvolvimento seguro e responsável de aplicações de IA.
@@ -881,4 +908,4 @@ Saiba como obter o máximo da configuração do seu LLM:
llm = LLM(model="openai/gpt-4o") # 128K tokens
```
</Tab>
</Tabs>
</Tabs>

View File

@@ -62,6 +62,10 @@ ENV_VARS = {
"prompt": "Enter your AWS Region Name (press Enter to skip)",
"key_name": "AWS_REGION_NAME",
},
{
"prompt": "Enter your AWS Bedrock API Key (30-day key from AWS console, press Enter to skip)",
"key_name": "AWS_BEARER_TOKEN_BEDROCK",
},
],
"azure": [
{

View File

@@ -0,0 +1,177 @@
import os
import pytest
from unittest.mock import patch, MagicMock
from crewai import LLM
class TestBedrockAuthentication:
"""Test AWS Bedrock authentication methods."""
@patch.dict(os.environ, {
'AWS_ACCESS_KEY_ID': 'test-key-id',
'AWS_SECRET_ACCESS_KEY': 'test-secret-key',
'AWS_DEFAULT_REGION': 'us-east-1'
})
@patch('litellm.completion')
def test_bedrock_iam_authentication(self, mock_completion):
"""Test Bedrock with IAM role authentication."""
mock_completion.return_value = MagicMock()
mock_completion.return_value.choices = [MagicMock()]
mock_completion.return_value.choices[0].message.content = "Test response"
llm = LLM(model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0")
result = llm.call("test message")
mock_completion.assert_called_once()
assert result == "Test response"
@patch.dict(os.environ, {
'AWS_BEARER_TOKEN_BEDROCK': 'test-api-key',
'AWS_DEFAULT_REGION': 'us-east-1'
})
@patch('litellm.completion')
def test_bedrock_api_key_authentication(self, mock_completion):
"""Test Bedrock with API key authentication."""
mock_completion.return_value = MagicMock()
mock_completion.return_value.choices = [MagicMock()]
mock_completion.return_value.choices[0].message.content = "Test response"
llm = LLM(model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0")
result = llm.call("test message")
mock_completion.assert_called_once()
assert result == "Test response"
def test_bedrock_missing_credentials(self):
"""Test Bedrock fails gracefully with missing credentials."""
with patch.dict(os.environ, {}, clear=True):
llm = LLM(model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0")
assert llm.model == "bedrock/anthropic.claude-3-sonnet-20240229-v1:0"
@patch.dict(os.environ, {
'AWS_BEARER_TOKEN_BEDROCK': 'test-api-key',
'AWS_DEFAULT_REGION': 'us-east-1'
})
@patch('litellm.completion')
def test_bedrock_api_key_with_streaming(self, mock_completion):
"""Test Bedrock API key authentication with streaming."""
mock_completion.return_value = iter([
MagicMock(choices=[MagicMock(delta=MagicMock(content="Test"))]),
MagicMock(choices=[MagicMock(delta=MagicMock(content=" response"))])
])
llm = LLM(model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0")
result = list(llm.stream("test message"))
mock_completion.assert_called_once()
assert len(result) == 2
@patch.dict(os.environ, {
'AWS_ACCESS_KEY_ID': 'test-key-id',
'AWS_SECRET_ACCESS_KEY': 'test-secret-key',
'AWS_DEFAULT_REGION': 'us-east-1'
})
@patch('litellm.completion')
def test_bedrock_iam_with_custom_parameters(self, mock_completion):
"""Test Bedrock IAM authentication with custom parameters."""
mock_completion.return_value = MagicMock()
mock_completion.return_value.choices = [MagicMock()]
mock_completion.return_value.choices[0].message.content = "Test response"
llm = LLM(
model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0",
temperature=0.7,
max_tokens=100
)
result = llm.call("test message")
mock_completion.assert_called_once()
call_args = mock_completion.call_args
assert call_args[1]['temperature'] == 0.7
assert call_args[1]['max_tokens'] == 100
assert result == "Test response"
@patch.dict(os.environ, {
'AWS_BEARER_TOKEN_BEDROCK': 'test-api-key',
'AWS_DEFAULT_REGION': 'us-west-2'
})
@patch('litellm.completion')
def test_bedrock_api_key_different_region(self, mock_completion):
"""Test Bedrock API key authentication with different region."""
mock_completion.return_value = MagicMock()
mock_completion.return_value.choices = [MagicMock()]
mock_completion.return_value.choices[0].message.content = "Test response"
llm = LLM(model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0")
result = llm.call("test message")
mock_completion.assert_called_once()
assert result == "Test response"
@patch.dict(os.environ, {
'AWS_BEARER_TOKEN_BEDROCK': 'test-api-key',
'AWS_DEFAULT_REGION': 'us-east-1'
})
@patch('litellm.completion')
def test_bedrock_timeout_handling(self, mock_completion):
"""Test Bedrock API timeout handling."""
mock_completion.side_effect = TimeoutError("Request timed out")
llm = LLM(model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0")
with pytest.raises(TimeoutError, match="Request timed out"):
llm.call("test message")
@patch.dict(os.environ, {
'AWS_BEARER_TOKEN_BEDROCK': 'test-api-key',
'AWS_DEFAULT_REGION': 'us-east-1'
})
@patch('litellm.completion')
def test_bedrock_rate_limit_handling(self, mock_completion):
"""Test Bedrock API rate limit handling."""
mock_completion.side_effect = Exception("Rate limit exceeded")
llm = LLM(model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0")
with pytest.raises(Exception, match="Rate limit exceeded"):
llm.call("test message")
@patch.dict(os.environ, {
'AWS_BEARER_TOKEN_BEDROCK': 'invalid-key',
'AWS_DEFAULT_REGION': 'us-east-1'
})
@patch('litellm.completion')
def test_bedrock_invalid_api_key(self, mock_completion):
"""Test Bedrock with invalid API key."""
mock_completion.side_effect = Exception("Invalid API key")
llm = LLM(model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0")
with pytest.raises(Exception, match="Invalid API key"):
llm.call("test message")
@patch.dict(os.environ, {
'AWS_ACCESS_KEY_ID': 'test-key-id',
'AWS_SECRET_ACCESS_KEY': 'test-secret-key',
'AWS_DEFAULT_REGION': 'us-east-1'
})
@patch('litellm.completion')
def test_bedrock_connection_error(self, mock_completion):
"""Test Bedrock with connection error."""
mock_completion.side_effect = ConnectionError("Connection failed")
llm = LLM(model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0")
with pytest.raises(ConnectionError, match="Connection failed"):
llm.call("test message")
@patch.dict(os.environ, {
'AWS_BEARER_TOKEN_BEDROCK': 'test-api-key',
'AWS_DEFAULT_REGION': 'us-east-1'
})
@patch('litellm.completion')
def test_bedrock_api_key_with_retry_scenario(self, mock_completion):
"""Test Bedrock API key authentication with retry scenario."""
mock_completion.side_effect = [
Exception("Temporary error"),
MagicMock(choices=[MagicMock(message=MagicMock(content="Success after retry"))])
]
llm = LLM(model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0")
with pytest.raises(Exception, match="Temporary error"):
llm.call("test message")