diff --git a/lib/cli/src/crewai_cli/constants.py b/lib/cli/src/crewai_cli/constants.py index c587147b3f..2ff02f289d 100644 --- a/lib/cli/src/crewai_cli/constants.py +++ b/lib/cli/src/crewai_cli/constants.py @@ -58,6 +58,12 @@ "API_BASE": "http://localhost:11434", } ], + "llmman": [ + { + "default": True, + "API_BASE": "http://localhost:17434", + } + ], "bedrock": [ { "prompt": "Enter your AWS Access Key ID (press Enter to skip)", @@ -123,6 +129,7 @@ "groq", "huggingface", "ollama", + "llmman", "watson", "bedrock", "azure", @@ -269,6 +276,7 @@ "groq/gemma-7b-it", ], "ollama": ["ollama/llama3.1", "ollama/mixtral"], + "llmman": ["llmman/qwen3.8", "llmman/gemma4"], "watson": [ "watsonx/meta-llama/llama-3-1-70b-instruct", "watsonx/meta-llama/llama-3-1-8b-instruct", diff --git a/lib/crewai/src/crewai/llms/providers/openai_compatible/completion.py b/lib/crewai/src/crewai/llms/providers/openai_compatible/completion.py index da4cfd03db..e8302c0ebf 100644 --- a/lib/crewai/src/crewai/llms/providers/openai_compatible/completion.py +++ b/lib/crewai/src/crewai/llms/providers/openai_compatible/completion.py @@ -70,6 +70,13 @@ class ProviderConfig: api_key_required=False, default_api_key="ollama", ), + "llmman": ProviderConfig( + base_url="http://localhost:17434/v1", + api_key_env="LLMMAN_API_KEY", + base_url_env="LLMMAN_HOST", + api_key_required=False, + default_api_key="llmman", + ), "hosted_vllm": ProviderConfig( base_url="http://localhost:8000/v1", api_key_env="VLLM_API_KEY", @@ -122,6 +129,7 @@ class OpenAICompatibleCompletion(OpenAICompletion): - deepseek: DeepSeek (https://deepseek.com) - ollama: Ollama local server (https://ollama.ai) - ollama_chat: Alias for ollama + - llmman: llmman local server (https://github.com/llmmanorg/llmman) - hosted_vllm: vLLM server (https://github.com/vllm-project/vllm) - cerebras: Cerebras (https://cerebras.ai) - dashscope: Alibaba Dashscope/Qwen (https://dashscope.aliyun.com) @@ -222,7 +230,7 @@ def _resolve_base_url( else: resolved = config.base_url - if provider in ("ollama", "ollama_chat"): + if provider in ("ollama", "ollama_chat", "llmman"): resolved = _normalize_ollama_base_url(resolved) return resolved diff --git a/lib/crewai/tests/llms/openai_compatible/test_openai_compatible.py b/lib/crewai/tests/llms/openai_compatible/test_openai_compatible.py index ce856a5334..839bb96211 100644 --- a/lib/crewai/tests/llms/openai_compatible/test_openai_compatible.py +++ b/lib/crewai/tests/llms/openai_compatible/test_openai_compatible.py @@ -73,6 +73,24 @@ def test_ollama_chat_is_alias(self): assert ollama.base_url == ollama_chat.base_url assert ollama.api_key_required == ollama_chat.api_key_required + def test_llmman_config(self): + """Test llmman provider configuration.""" + config = OPENAI_COMPATIBLE_PROVIDERS["llmman"] + assert config.base_url == "http://localhost:17434/v1" + assert config.api_key_env == "LLMMAN_API_KEY" + assert config.base_url_env == "LLMMAN_HOST" + assert config.api_key_required is False + assert config.default_api_key == "llmman" + + def test_llmman_port_does_not_collide(self): + """llmman must not reuse another local provider's default port.""" + others = { + name: cfg.base_url + for name, cfg in OPENAI_COMPATIBLE_PROVIDERS.items() + if name != "llmman" + } + assert OPENAI_COMPATIBLE_PROVIDERS["llmman"].base_url not in others.values() + def test_hosted_vllm_config(self): """Test hosted_vllm provider configuration.""" config = OPENAI_COMPATIBLE_PROVIDERS["hosted_vllm"]