mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-01-10 00:28:31 +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",
|
"key_name": "OPENAI_API_KEY",
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"mistral": [
|
||||||
|
{
|
||||||
|
"prompt": "Enter your MISTRAL API key (press Enter to skip)",
|
||||||
|
"key_name": "MISTRAL_API_KEY",
|
||||||
|
}
|
||||||
|
],
|
||||||
"anthropic": [
|
"anthropic": [
|
||||||
{
|
{
|
||||||
"prompt": "Enter your ANTHROPIC API key (press Enter to skip)",
|
"prompt": "Enter your ANTHROPIC API key (press Enter to skip)",
|
||||||
@@ -98,10 +104,17 @@ PROVIDERS = [
|
|||||||
"bedrock",
|
"bedrock",
|
||||||
"azure",
|
"azure",
|
||||||
"cerebras",
|
"cerebras",
|
||||||
|
"mistral",
|
||||||
]
|
]
|
||||||
|
|
||||||
MODELS = {
|
MODELS = {
|
||||||
"openai": ["gpt-4", "gpt-4o", "gpt-4o-mini", "o1-mini", "o1-preview"],
|
"openai": ["gpt-4", "gpt-4o", "gpt-4o-mini", "o1-mini", "o1-preview"],
|
||||||
|
"mistral": [
|
||||||
|
"mistral-tiny",
|
||||||
|
"mistral-small",
|
||||||
|
"mistral-medium",
|
||||||
|
"mistral-large",
|
||||||
|
],
|
||||||
"anthropic": [
|
"anthropic": [
|
||||||
"claude-3-5-sonnet-20240620",
|
"claude-3-5-sonnet-20240620",
|
||||||
"claude-3-sonnet-20240229",
|
"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():
|
if api_key_value.strip():
|
||||||
env_vars[key_name] = api_key_value
|
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)
|
write_env_file(folder_path, env_vars)
|
||||||
click.secho("API keys and model saved to .env file", fg="green")
|
click.secho("API keys and model saved to .env file", fg="green")
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ from crewai.cli.cli import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
from crewai.cli.cli import create
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def runner():
|
def runner():
|
||||||
return CliRunner()
|
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)
|
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):
|
def test_add_crew_to_flow_not_in_root(runner):
|
||||||
# Simulate not being in the root of a flow project
|
# Simulate not being in the root of a flow project
|
||||||
with mock.patch("pathlib.Path.exists", autospec=True) as mock_exists:
|
with mock.patch("pathlib.Path.exists", autospec=True) as mock_exists:
|
||||||
|
|||||||
Reference in New Issue
Block a user