mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-07-08 00:15:12 +00:00
Compare commits
4 Commits
devin/1781
...
devin/1744
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bde394024f | ||
|
|
878bbef0e2 | ||
|
|
71569a20da | ||
|
|
205e778d74 |
@@ -85,21 +85,6 @@ ENV_VARS = {
|
||||
"key_name": "CEREBRAS_API_KEY",
|
||||
},
|
||||
],
|
||||
"lmstudio": [
|
||||
{
|
||||
"prompt": "Enter your LM Studio model name (press Enter to skip)",
|
||||
"key_name": "MODEL",
|
||||
},
|
||||
{
|
||||
"prompt": "Enter your LM Studio API base URL",
|
||||
"key_name": "OPENAI_API_BASE",
|
||||
"default_value": "http://localhost:1234/v1",
|
||||
},
|
||||
{
|
||||
"prompt": "Enter your LM Studio API key (press Enter to skip)",
|
||||
"key_name": "OPENAI_API_KEY",
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
@@ -109,7 +94,6 @@ PROVIDERS = [
|
||||
"gemini",
|
||||
"groq",
|
||||
"ollama",
|
||||
"lmstudio",
|
||||
"watson",
|
||||
"bedrock",
|
||||
"azure",
|
||||
|
||||
@@ -157,12 +157,7 @@ def create_crew(name, provider=None, skip_provider=False, parent_folder=None):
|
||||
# Prompt for non-default key-value pairs
|
||||
prompt = details["prompt"]
|
||||
key_name = details["key_name"]
|
||||
default_value = details.get("default_value", "")
|
||||
api_key_value = click.prompt(
|
||||
prompt,
|
||||
default=default_value,
|
||||
show_default=bool(default_value),
|
||||
)
|
||||
api_key_value = click.prompt(prompt, default="", show_default=False)
|
||||
|
||||
if api_key_value.strip():
|
||||
env_vars[key_name] = api_key_value
|
||||
|
||||
@@ -64,6 +64,16 @@ class BaseFileKnowledgeSource(BaseKnowledgeSource, ABC):
|
||||
"""Save the documents to the storage."""
|
||||
self.storage.save(self.chunks)
|
||||
|
||||
def add(self) -> None:
|
||||
"""
|
||||
Process content from files, chunk it, compute embeddings, and save them.
|
||||
This method is called after content is loaded from files.
|
||||
"""
|
||||
for _, text in self.content.items():
|
||||
new_chunks = self._chunk_text(text)
|
||||
self.chunks.extend(new_chunks)
|
||||
self._save_documents()
|
||||
|
||||
def convert_to_path(self, path: Union[Path, str]) -> Path:
|
||||
"""Convert a path to a Path object."""
|
||||
return Path(KNOWLEDGE_DIRECTORY + "/" + path) if isinstance(path, str) else path
|
||||
|
||||
@@ -1,216 +0,0 @@
|
||||
"""Tests for LMStudio provider integration in the CLI."""
|
||||
|
||||
import shutil
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
from unittest import mock
|
||||
|
||||
import pytest
|
||||
|
||||
from crewai.cli.constants import ENV_VARS, PROVIDERS
|
||||
from crewai.cli.create_crew import create_crew
|
||||
|
||||
|
||||
class TestLMStudioConstants:
|
||||
"""Tests verifying LMStudio is properly defined in CLI constants."""
|
||||
|
||||
def test_lmstudio_in_providers_list(self):
|
||||
assert "lmstudio" in PROVIDERS
|
||||
|
||||
def test_lmstudio_env_vars_defined(self):
|
||||
assert "lmstudio" in ENV_VARS
|
||||
|
||||
def test_lmstudio_env_vars_has_model_entry(self):
|
||||
lmstudio_vars = ENV_VARS["lmstudio"]
|
||||
model_entry = next(
|
||||
(d for d in lmstudio_vars if d.get("key_name") == "MODEL"), None
|
||||
)
|
||||
assert model_entry is not None
|
||||
assert "prompt" in model_entry
|
||||
|
||||
def test_lmstudio_env_vars_has_api_base_entry(self):
|
||||
lmstudio_vars = ENV_VARS["lmstudio"]
|
||||
api_base_entry = next(
|
||||
(d for d in lmstudio_vars if d.get("key_name") == "OPENAI_API_BASE"), None
|
||||
)
|
||||
assert api_base_entry is not None
|
||||
assert api_base_entry["default_value"] == "http://localhost:1234/v1"
|
||||
|
||||
def test_lmstudio_env_vars_has_api_key_entry(self):
|
||||
lmstudio_vars = ENV_VARS["lmstudio"]
|
||||
api_key_entry = next(
|
||||
(d for d in lmstudio_vars if d.get("key_name") == "OPENAI_API_KEY"), None
|
||||
)
|
||||
assert api_key_entry is not None
|
||||
assert "prompt" in api_key_entry
|
||||
|
||||
|
||||
class TestLMStudioCreateCrew:
|
||||
"""Tests verifying the create crew flow works with LMStudio provider."""
|
||||
|
||||
@pytest.fixture
|
||||
def temp_dir(self):
|
||||
d = tempfile.mkdtemp()
|
||||
yield Path(d)
|
||||
shutil.rmtree(d)
|
||||
|
||||
@mock.patch("crewai.cli.create_crew.get_provider_data")
|
||||
@mock.patch("crewai.cli.create_crew.select_provider")
|
||||
@mock.patch("click.prompt")
|
||||
@mock.patch("click.confirm", return_value=False)
|
||||
def test_create_crew_with_lmstudio_all_values(
|
||||
self,
|
||||
mock_confirm,
|
||||
mock_prompt,
|
||||
mock_select_provider,
|
||||
mock_get_provider_data,
|
||||
temp_dir,
|
||||
):
|
||||
"""Test creating a crew with LMStudio provider setting all values."""
|
||||
mock_get_provider_data.return_value = {"lmstudio": []}
|
||||
mock_select_provider.return_value = "lmstudio"
|
||||
|
||||
# Simulate user inputs for: model name, api base url, api key
|
||||
mock_prompt.side_effect = [
|
||||
"my-local-model",
|
||||
"http://localhost:1234/v1",
|
||||
"lm-studio-key",
|
||||
]
|
||||
|
||||
create_crew("test_crew", provider="lmstudio", parent_folder=str(temp_dir))
|
||||
|
||||
# Check the .env file was created with correct values
|
||||
env_file = temp_dir / "test_crew" / ".env"
|
||||
assert env_file.exists()
|
||||
env_content = env_file.read_text()
|
||||
assert "MODEL=my-local-model" in env_content
|
||||
assert "OPENAI_API_BASE=http://localhost:1234/v1" in env_content
|
||||
assert "OPENAI_API_KEY=lm-studio-key" in env_content
|
||||
|
||||
@mock.patch("crewai.cli.create_crew.get_provider_data")
|
||||
@mock.patch("crewai.cli.create_crew.select_provider")
|
||||
@mock.patch("click.prompt")
|
||||
@mock.patch("click.confirm", return_value=False)
|
||||
def test_create_crew_with_lmstudio_default_base_url(
|
||||
self,
|
||||
mock_confirm,
|
||||
mock_prompt,
|
||||
mock_select_provider,
|
||||
mock_get_provider_data,
|
||||
temp_dir,
|
||||
):
|
||||
"""Test creating a crew with LMStudio using default base URL."""
|
||||
mock_get_provider_data.return_value = {"lmstudio": []}
|
||||
mock_select_provider.return_value = "lmstudio"
|
||||
|
||||
# User provides model, accepts default URL, skips API key
|
||||
mock_prompt.side_effect = ["my-local-model", "http://localhost:1234/v1", ""]
|
||||
|
||||
create_crew("test_crew", provider="lmstudio", parent_folder=str(temp_dir))
|
||||
|
||||
env_file = temp_dir / "test_crew" / ".env"
|
||||
assert env_file.exists()
|
||||
env_content = env_file.read_text()
|
||||
assert "MODEL=my-local-model" in env_content
|
||||
assert "OPENAI_API_BASE=http://localhost:1234/v1" in env_content
|
||||
# API key should not be present when skipped
|
||||
assert "OPENAI_API_KEY" not in env_content
|
||||
|
||||
@mock.patch("crewai.cli.create_crew.get_provider_data")
|
||||
@mock.patch("crewai.cli.create_crew.select_provider")
|
||||
@mock.patch("click.prompt")
|
||||
@mock.patch("click.confirm", return_value=False)
|
||||
def test_create_crew_with_lmstudio_custom_base_url(
|
||||
self,
|
||||
mock_confirm,
|
||||
mock_prompt,
|
||||
mock_select_provider,
|
||||
mock_get_provider_data,
|
||||
temp_dir,
|
||||
):
|
||||
"""Test creating a crew with LMStudio using a custom base URL."""
|
||||
mock_get_provider_data.return_value = {"lmstudio": []}
|
||||
mock_select_provider.return_value = "lmstudio"
|
||||
|
||||
# User provides model, custom URL, and API key
|
||||
mock_prompt.side_effect = [
|
||||
"my-local-model",
|
||||
"http://192.168.1.100:1234/v1",
|
||||
"my-key",
|
||||
]
|
||||
|
||||
create_crew("test_crew", provider="lmstudio", parent_folder=str(temp_dir))
|
||||
|
||||
env_file = temp_dir / "test_crew" / ".env"
|
||||
assert env_file.exists()
|
||||
env_content = env_file.read_text()
|
||||
assert "MODEL=my-local-model" in env_content
|
||||
assert "OPENAI_API_BASE=http://192.168.1.100:1234/v1" in env_content
|
||||
assert "OPENAI_API_KEY=my-key" in env_content
|
||||
|
||||
@mock.patch("crewai.cli.create_crew.get_provider_data")
|
||||
@mock.patch("crewai.cli.create_crew.select_provider")
|
||||
@mock.patch("click.prompt")
|
||||
@mock.patch("click.confirm", return_value=False)
|
||||
def test_create_crew_with_lmstudio_no_model(
|
||||
self,
|
||||
mock_confirm,
|
||||
mock_prompt,
|
||||
mock_select_provider,
|
||||
mock_get_provider_data,
|
||||
temp_dir,
|
||||
):
|
||||
"""Test creating a crew with LMStudio when user skips model name."""
|
||||
mock_get_provider_data.return_value = {"lmstudio": []}
|
||||
mock_select_provider.return_value = "lmstudio"
|
||||
|
||||
# User skips model, accepts default URL, skips API key
|
||||
mock_prompt.side_effect = ["", "http://localhost:1234/v1", ""]
|
||||
|
||||
create_crew("test_crew", provider="lmstudio", parent_folder=str(temp_dir))
|
||||
|
||||
env_file = temp_dir / "test_crew" / ".env"
|
||||
assert env_file.exists()
|
||||
env_content = env_file.read_text()
|
||||
# MODEL should not be present when skipped
|
||||
assert "MODEL=" not in env_content
|
||||
assert "OPENAI_API_BASE=http://localhost:1234/v1" in env_content
|
||||
|
||||
|
||||
class TestDefaultValueInPrompt:
|
||||
"""Tests verifying the default_value mechanism in env var prompts."""
|
||||
|
||||
@pytest.fixture
|
||||
def temp_dir(self):
|
||||
d = tempfile.mkdtemp()
|
||||
yield Path(d)
|
||||
shutil.rmtree(d)
|
||||
|
||||
@mock.patch("crewai.cli.create_crew.get_provider_data")
|
||||
@mock.patch("crewai.cli.create_crew.select_provider")
|
||||
@mock.patch("click.prompt")
|
||||
@mock.patch("click.confirm", return_value=False)
|
||||
def test_default_value_is_used_when_user_accepts(
|
||||
self,
|
||||
mock_confirm,
|
||||
mock_prompt,
|
||||
mock_select_provider,
|
||||
mock_get_provider_data,
|
||||
temp_dir,
|
||||
):
|
||||
"""Test that default_value is written to .env when user accepts it."""
|
||||
mock_get_provider_data.return_value = {"lmstudio": []}
|
||||
mock_select_provider.return_value = "lmstudio"
|
||||
|
||||
# User enters model, accepts default base URL, enters API key
|
||||
mock_prompt.side_effect = [
|
||||
"test-model",
|
||||
"http://localhost:1234/v1",
|
||||
"test-key",
|
||||
]
|
||||
|
||||
create_crew("test_crew", provider="lmstudio", parent_folder=str(temp_dir))
|
||||
|
||||
env_file = temp_dir / "test_crew" / ".env"
|
||||
env_content = env_file.read_text()
|
||||
assert "OPENAI_API_BASE=http://localhost:1234/v1" in env_content
|
||||
19
tests/knowledge/test_knowledge_source_instantiation.py
Normal file
19
tests/knowledge/test_knowledge_source_instantiation.py
Normal file
@@ -0,0 +1,19 @@
|
||||
from pathlib import Path
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from crewai.knowledge.source.pdf_knowledge_source import PDFKnowledgeSource
|
||||
|
||||
|
||||
@patch('crewai.knowledge.source.base_file_knowledge_source.BaseFileKnowledgeSource.validate_content')
|
||||
@patch('crewai.knowledge.source.pdf_knowledge_source.PDFKnowledgeSource.load_content')
|
||||
def test_pdf_knowledge_source_instantiation(mock_load_content, mock_validate_content, tmp_path):
|
||||
"""Test that PDFKnowledgeSource can be instantiated without errors."""
|
||||
mock_load_content.return_value = {}
|
||||
|
||||
pdf_path = tmp_path / "test.pdf"
|
||||
pdf_path.touch() # Create the file
|
||||
|
||||
pdf_source = PDFKnowledgeSource(file_paths=[pdf_path])
|
||||
assert isinstance(pdf_source, PDFKnowledgeSource)
|
||||
Reference in New Issue
Block a user