mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-01-09 16:18:30 +00:00
fix: Add Mistral provider configuration and tests (#2200)
- Add Mistral provider to constants.py with API key config - Add Mistral models to available models list - Fix env file creation to only write when API keys are provided - Add tests for Mistral provider setup with and without API key Fixes #2200 Co-Authored-By: Joe Moura <joao@crewai.com>
This commit is contained in:
@@ -5,6 +5,12 @@ ENV_VARS = {
|
||||
"key_name": "OPENAI_API_KEY",
|
||||
}
|
||||
],
|
||||
"mistral": [
|
||||
{
|
||||
"prompt": "Enter your MISTRAL API key (press Enter to skip)",
|
||||
"key_name": "MISTRAL_API_KEY",
|
||||
}
|
||||
],
|
||||
"anthropic": [
|
||||
{
|
||||
"prompt": "Enter your ANTHROPIC API key (press Enter to skip)",
|
||||
@@ -98,10 +104,17 @@ PROVIDERS = [
|
||||
"bedrock",
|
||||
"azure",
|
||||
"cerebras",
|
||||
"mistral",
|
||||
]
|
||||
|
||||
MODELS = {
|
||||
"openai": ["gpt-4", "gpt-4o", "gpt-4o-mini", "o1-mini", "o1-preview"],
|
||||
"mistral": [
|
||||
"mistral-tiny",
|
||||
"mistral-small",
|
||||
"mistral-medium",
|
||||
"mistral-large",
|
||||
],
|
||||
"anthropic": [
|
||||
"claude-3-5-sonnet-20240620",
|
||||
"claude-3-sonnet-20240229",
|
||||
|
||||
@@ -162,7 +162,12 @@ def create_crew(name, provider=None, skip_provider=False, parent_folder=None):
|
||||
if api_key_value.strip():
|
||||
env_vars[key_name] = api_key_value
|
||||
|
||||
if env_vars:
|
||||
# Only write env file if we have API keys
|
||||
has_api_keys = any(
|
||||
key in env_vars and env_vars[key].strip()
|
||||
for key in ["MISTRAL_API_KEY", "OPENAI_API_KEY", "ANTHROPIC_API_KEY"]
|
||||
)
|
||||
if has_api_keys:
|
||||
write_env_file(folder_path, env_vars)
|
||||
click.secho("API keys and model saved to .env file", fg="green")
|
||||
else:
|
||||
|
||||
@@ -20,6 +20,7 @@ from crewai.cli.cli import (
|
||||
)
|
||||
|
||||
|
||||
from crewai.cli.cli import create
|
||||
@pytest.fixture
|
||||
def runner():
|
||||
return CliRunner()
|
||||
@@ -309,6 +310,69 @@ def test_flow_add_crew(mock_path_exists, mock_create_embedded_crew, runner):
|
||||
assert isinstance(call_kwargs["parent_folder"], Path)
|
||||
|
||||
|
||||
@mock.patch("crewai.cli.create_crew.write_env_file")
|
||||
@mock.patch("crewai.cli.create_crew.load_env_vars")
|
||||
@mock.patch("crewai.cli.create_crew.get_provider_data")
|
||||
@mock.patch("crewai.cli.create_crew.select_model")
|
||||
@mock.patch("crewai.cli.create_crew.select_provider")
|
||||
@mock.patch("crewai.cli.create_crew.click.confirm")
|
||||
@mock.patch("crewai.cli.create_crew.click.prompt")
|
||||
def test_create_crew_with_mistral_provider(
|
||||
mock_prompt, mock_confirm, mock_select_provider, mock_select_model,
|
||||
mock_get_provider_data, mock_load_env_vars, mock_write_env_file, runner
|
||||
):
|
||||
# Mock folder override confirmation
|
||||
mock_confirm.return_value = True
|
||||
# Mock provider data
|
||||
mock_get_provider_data.return_value = {"mistral": ["mistral-tiny"]}
|
||||
# Mock empty env vars
|
||||
mock_load_env_vars.return_value = {}
|
||||
# Mock provider and model selection
|
||||
mock_select_provider.return_value = "mistral"
|
||||
mock_select_model.return_value = "mistral-tiny"
|
||||
# Mock API key input
|
||||
mock_prompt.return_value = "mistral_api_key_123"
|
||||
|
||||
# Run the command
|
||||
result = runner.invoke(create, ["crew", "test_crew"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "API keys and model saved to .env file" in result.output
|
||||
assert "Selected model: mistral-tiny" in result.output
|
||||
|
||||
@mock.patch("crewai.cli.create_crew.write_env_file")
|
||||
@mock.patch("crewai.cli.create_crew.load_env_vars")
|
||||
@mock.patch("crewai.cli.create_crew.get_provider_data")
|
||||
@mock.patch("crewai.cli.create_crew.select_model")
|
||||
@mock.patch("crewai.cli.create_crew.select_provider")
|
||||
@mock.patch("crewai.cli.create_crew.click.confirm")
|
||||
@mock.patch("crewai.cli.create_crew.click.prompt")
|
||||
def test_create_crew_with_mistral_provider_no_key(
|
||||
mock_prompt, mock_confirm, mock_select_provider, mock_select_model,
|
||||
mock_get_provider_data, mock_load_env_vars, mock_write_env_file, runner
|
||||
):
|
||||
# Mock folder override confirmation
|
||||
mock_confirm.return_value = True
|
||||
# Mock provider data
|
||||
mock_get_provider_data.return_value = {"mistral": ["mistral-tiny"]}
|
||||
# Mock empty env vars
|
||||
mock_load_env_vars.return_value = {}
|
||||
# Mock provider and model selection
|
||||
mock_select_provider.return_value = "mistral"
|
||||
mock_select_model.return_value = "mistral-tiny"
|
||||
# Mock empty API key input for all prompts
|
||||
mock_prompt.side_effect = [""] * 10 # Enough empty responses for all prompts
|
||||
|
||||
# Run the command
|
||||
result = runner.invoke(create, ["crew", "test_crew"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "No API keys provided. Skipping .env file creation." in result.output
|
||||
# Verify env file was not written since no API keys were provided
|
||||
mock_write_env_file.assert_not_called()
|
||||
# Verify model was still selected
|
||||
assert "Selected model: mistral-tiny" in result.output
|
||||
|
||||
def test_add_crew_to_flow_not_in_root(runner):
|
||||
# Simulate not being in the root of a flow project
|
||||
with mock.patch("pathlib.Path.exists", autospec=True) as mock_exists:
|
||||
|
||||
Reference in New Issue
Block a user