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:
Devin AI
2025-02-22 16:36:25 +00:00
parent 409892d65f
commit dc765e6491
3 changed files with 83 additions and 1 deletions

View File

@@ -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",

View File

@@ -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:

View File

@@ -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: