Phase 4: Shell completion scripts and comprehensive test suite
This commit is contained in:
1 parent
aba2fc11f4
commit
5e70e22780
5 files changed
+641
-7
No files matched your search
@@ -11,6 +11,8 @@ Un agente configurabile basato su DeepAgents che supporta più provider LLM.
|
||||
- **Estensibile**: Aggiungi strumenti personalizzati, modifica i prompt e configura i sub-agenti secondo le tue esigenze
|
||||
- **Strumenti unificati**: Gestisci qualsiasi provider con la stessa interfaccia
|
||||
- **Strumenti personalizzati**: Include strumenti per gestire Proxmox e Ollama
|
||||
- **Completamento shell**: Supporta bash e zsh per autocompletamento dei comandi
|
||||
- **Test completi**: Suite di test per garantire la qualità del codice
|
||||
|
||||
## Installazione
|
||||
|
||||
@@ -20,6 +22,21 @@ Un agente configurabile basato su DeepAgents che supporta più provider LLM.
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
### Configurazione del Completamento Shell
|
||||
|
||||
#### Bash
|
||||
```bash
|
||||
# Aggiungi al tuo ~/.bashrc o ~/.bash_profile
|
||||
source /path/to/maxclaw_agent/completions/maxclaw.bash
|
||||
```
|
||||
|
||||
#### Zsh
|
||||
```bash
|
||||
# Aggiungi al tuo ~/.zshrc
|
||||
fpath=(/path/to/maxclaw_agent/completions $fpath)
|
||||
autoload -Uz compinit && compinit
|
||||
```
|
||||
|
||||
## Configurazione
|
||||
|
||||
Puoi configurare MaxClaw Agent in diversi modi:
|
||||
@@ -202,6 +219,21 @@ Gli strumenti Ollama specifici sono ancora disponibili per retrocompatibilità:
|
||||
- `ollama_status`: Controlla se Ollama è in esecuzione
|
||||
- `ollama_running_models`: Mostra i modelli attualmente in esecuzione
|
||||
|
||||
## Test
|
||||
|
||||
Esegui la suite di test:
|
||||
```bash
|
||||
# Esegui tutti i test
|
||||
pytest tests/
|
||||
|
||||
# Esegui test specifici
|
||||
pytest tests/test_config_manager.py
|
||||
pytest tests/test_provider_tools.py
|
||||
|
||||
# Esegui con output verboso
|
||||
pytest tests/ -v
|
||||
```
|
||||
|
||||
## Personalizzazione
|
||||
|
||||
Per personalizzare l'agente, modifica `main.py`:
|
||||
@@ -210,13 +242,6 @@ Per personalizzare l'agente, modifica `main.py`:
|
||||
- Aggiungi strumenti personalizzati alla chiamata `create_deep_agent`
|
||||
- Configura i sub-agenti o altre funzionalità di DeepAgents
|
||||
|
||||
## Test
|
||||
|
||||
Esegui lo script di test:
|
||||
```bash
|
||||
python test_agent.py
|
||||
```
|
||||
|
||||
## Sicurezza
|
||||
|
||||
MaxClaw Agent implementa misure di sicurezza avanzate:
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
#!/bin/bash
|
||||
# Bash completion for MaxClaw Agent CLI
|
||||
|
||||
_maxclaw_completions()
|
||||
{
|
||||
local cur prev commands
|
||||
COMPREPLY=()
|
||||
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
||||
|
||||
# Main commands
|
||||
commands="list search add remove set-active active test export import help"
|
||||
|
||||
# Handle main command completion
|
||||
if [[ ${COMP_CWORD} -eq 1 ]]; then
|
||||
COMPREPLY=( $(compgen -W "${commands}" -- ${cur}) )
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Handle subcommand-specific completions
|
||||
case "${prev}" in
|
||||
search)
|
||||
# Search term - no completion
|
||||
return 0
|
||||
;;
|
||||
add)
|
||||
# Add command options
|
||||
local add_options="--non-interactive --name --provider --model --api-key --base-url --set-active"
|
||||
COMPREPLY=( $(compgen -W "${add_options}" -- ${cur}) )
|
||||
return 0
|
||||
;;
|
||||
remove|set-active|test)
|
||||
# Configuration names - try to get from config list
|
||||
if command -v python3 &> /dev/null; then
|
||||
local configs=$(python3 -c "
|
||||
import sys
|
||||
sys.path.insert(0, '.')
|
||||
try:
|
||||
from config_manager import config_manager
|
||||
configs = config_manager.list_configuration_names()
|
||||
print(' '.join(configs))
|
||||
except:
|
||||
pass
|
||||
" 2>/dev/null)
|
||||
COMPREPLY=( $(compgen -W "${configs}" -- ${cur}) )
|
||||
fi
|
||||
return 0
|
||||
;;
|
||||
export)
|
||||
# Export options
|
||||
local export_options="--format --output"
|
||||
COMPREPLY=( $(compgen -W "${export_options}" -- ${cur}) )
|
||||
return 0
|
||||
;;
|
||||
import)
|
||||
# File completion
|
||||
COMPREPLY=( $(compgen -f -- ${cur}) )
|
||||
return 0
|
||||
;;
|
||||
--provider)
|
||||
# Provider options
|
||||
local providers="openai ollama openrouter"
|
||||
COMPREPLY=( $(compgen -W "${providers}" -- ${cur}) )
|
||||
return 0
|
||||
;;
|
||||
--format)
|
||||
# Format options
|
||||
local formats="json yaml"
|
||||
COMPREPLY=( $(compgen -W "${formats}" -- ${cur}) )
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
|
||||
# Handle option arguments
|
||||
case "${cur}" in
|
||||
-*)
|
||||
# Option completion
|
||||
local options="--non-interactive --name --provider --model --api-key --base-url --set-active --format --output"
|
||||
COMPREPLY=( $(compgen -W "${options}" -- ${cur}) )
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
complete -F _maxclaw_completions python3 config_cli.py
|
||||
complete -F _maxclaw_completions python config_cli.py
|
||||
@@ -0,0 +1,79 @@
|
||||
#compdef config_cli.py
|
||||
# Zsh completion for MaxClaw Agent CLI
|
||||
|
||||
_maxclaw() {
|
||||
local -a commands
|
||||
local curcontext="$curcontext" state line
|
||||
typeset -A opt_args
|
||||
|
||||
_arguments -C \
|
||||
'1: :->command' \
|
||||
'*::arg:->args'
|
||||
|
||||
case $state in
|
||||
command)
|
||||
commands=(
|
||||
'list:List all configurations'
|
||||
'search:Search configurations'
|
||||
'add:Add a new configuration'
|
||||
'remove:Remove a configuration'
|
||||
'set-active:Set active configuration'
|
||||
'active:Show active configuration'
|
||||
'test:Test connection to a configuration'
|
||||
'export:Export configurations to JSON/YAML'
|
||||
'import:Import configurations from JSON/YAML'
|
||||
'help:Show help'
|
||||
)
|
||||
_describe -t commands 'MaxClaw commands' commands
|
||||
;;
|
||||
args)
|
||||
case ${line[1]} in
|
||||
search)
|
||||
_message 'search term'
|
||||
;;
|
||||
add)
|
||||
_arguments \
|
||||
'--non-interactive[Non-interactive mode]' \
|
||||
'--name[Configuration name]:name' \
|
||||
'--provider[Provider]:provider:(openai ollama openrouter)' \
|
||||
'--model[Model name]:model' \
|
||||
'--api-key[API key]:api_key' \
|
||||
'--base-url[Base URL]:base_url' \
|
||||
'--set-active[Set as active configuration]'
|
||||
;;
|
||||
remove|set-active|test)
|
||||
# Try to get configuration names
|
||||
local -a configs
|
||||
if (( $+commands[python3] )); then
|
||||
configs=(${(f)"$(python3 -c "
|
||||
import sys
|
||||
sys.path.insert(0, '.')
|
||||
try:
|
||||
from config_manager import config_manager
|
||||
configs = config_manager.list_configuration_names()
|
||||
for c in configs:
|
||||
print(c)
|
||||
except:
|
||||
pass
|
||||
" 2>/dev/null)"})
|
||||
fi
|
||||
if (( ${#configs} )); then
|
||||
_describe -t configurations 'configurations' configs
|
||||
else
|
||||
_message 'configuration name'
|
||||
fi
|
||||
;;
|
||||
export)
|
||||
_arguments \
|
||||
'--format[Export format]:format:(json yaml)' \
|
||||
'--output[Output filename]:filename'
|
||||
;;
|
||||
import)
|
||||
_files -g '*.json *.yaml *.yml'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
_maxclaw "$@"
|
||||
@@ -0,0 +1,186 @@
|
||||
"""
|
||||
Test suite for MaxClaw Agent configuration manager
|
||||
"""
|
||||
import os
|
||||
import json
|
||||
import tempfile
|
||||
import pytest
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
# Add parent directory to path
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
from config_manager import ConfigManager
|
||||
|
||||
|
||||
class TestConfigManager:
|
||||
"""Test cases for ConfigManager"""
|
||||
|
||||
def setup_method(self):
|
||||
"""Set up test environment"""
|
||||
self.temp_dir = tempfile.mkdtemp()
|
||||
self.config_manager = ConfigManager(self.temp_dir)
|
||||
|
||||
def teardown_method(self):
|
||||
"""Clean up test environment"""
|
||||
import shutil
|
||||
shutil.rmtree(self.temp_dir, ignore_errors=True)
|
||||
|
||||
def test_initialization(self):
|
||||
"""Test ConfigManager initialization"""
|
||||
assert self.config_manager.config_dir.exists()
|
||||
assert self.config_manager.config_file.exists()
|
||||
assert self.config_manager.key_file.exists()
|
||||
assert self.config_manager.config == {"configurations": {}, "active_configuration": None, "version": "1.0"}
|
||||
|
||||
def test_add_configuration(self):
|
||||
"""Test adding a configuration"""
|
||||
config = {
|
||||
"provider": "ollama",
|
||||
"model_name": "gemma2:9b",
|
||||
"base_url": "http://localhost:11434"
|
||||
}
|
||||
|
||||
self.config_manager.add_configuration("test-config", config)
|
||||
|
||||
# Verify configuration was added
|
||||
assert self.config_manager.configuration_exists("test-config")
|
||||
retrieved = self.config_manager.get_configuration("test-config")
|
||||
assert retrieved["provider"] == "ollama"
|
||||
assert retrieved["model_name"] == "gemma2:9b"
|
||||
assert retrieved["base_url"] == "http://localhost:11434"
|
||||
|
||||
def test_remove_configuration(self):
|
||||
"""Test removing a configuration"""
|
||||
config = {
|
||||
"provider": "openai",
|
||||
"model_name": "gpt-4o",
|
||||
"api_key": "sk-test123"
|
||||
}
|
||||
|
||||
self.config_manager.add_configuration("test-openai", config)
|
||||
assert self.config_manager.configuration_exists("test-openai")
|
||||
|
||||
# Remove configuration
|
||||
result = self.config_manager.remove_configuration("test-openai")
|
||||
assert result is True
|
||||
assert not self.config_manager.configuration_exists("test-openai")
|
||||
|
||||
def test_set_active_configuration(self):
|
||||
"""Test setting active configuration"""
|
||||
config = {
|
||||
"provider": "ollama",
|
||||
"model_name": "gemma2:9b",
|
||||
"base_url": "http://localhost:11434"
|
||||
}
|
||||
|
||||
self.config_manager.add_configuration("test-config", config)
|
||||
|
||||
# Set as active
|
||||
result = self.config_manager.set_active_configuration("test-config")
|
||||
assert result is True
|
||||
assert self.config_manager.get_active_configuration() == "test-config"
|
||||
|
||||
def test_validation(self):
|
||||
"""Test configuration validation"""
|
||||
# Valid configuration
|
||||
valid_config = {
|
||||
"provider": "ollama",
|
||||
"model_name": "gemma2:9b",
|
||||
"base_url": "http://localhost:11434"
|
||||
}
|
||||
|
||||
is_valid, errors = self.config_manager.validate_configuration(valid_config)
|
||||
assert is_valid is True
|
||||
assert len(errors) == 0
|
||||
|
||||
# Invalid configuration - missing provider
|
||||
invalid_config = {
|
||||
"model_name": "gemma2:9b",
|
||||
"base_url": "http://localhost:11434"
|
||||
}
|
||||
|
||||
is_valid, errors = self.config_manager.validate_configuration(invalid_config)
|
||||
assert is_valid is False
|
||||
assert "Provider is required" in errors
|
||||
|
||||
# Invalid configuration - OpenAI without API key
|
||||
invalid_openai = {
|
||||
"provider": "openai",
|
||||
"model_name": "gpt-4o"
|
||||
}
|
||||
|
||||
is_valid, errors = self.config_manager.validate_configuration(invalid_openai)
|
||||
assert is_valid is False
|
||||
assert "API key is required for OpenAI provider" in errors
|
||||
|
||||
def test_encryption(self):
|
||||
"""Test that API keys are encrypted"""
|
||||
config = {
|
||||
"provider": "openai",
|
||||
"model_name": "gpt-4o",
|
||||
"api_key": "sk-test123456789"
|
||||
}
|
||||
|
||||
self.config_manager.add_configuration("test-openai", config)
|
||||
|
||||
# Read the raw config file
|
||||
with open(self.config_manager.config_file, 'r') as f:
|
||||
raw_config = json.load(f)
|
||||
|
||||
# Check that API key is encrypted in the file
|
||||
stored_config = raw_config["configurations"]["test-openai"]
|
||||
assert "api_key" in stored_config
|
||||
assert stored_config["api_key"] != "sk-test123456789" # Should be encrypted
|
||||
assert len(stored_config["api_key"]) > 20 # Encrypted data is longer
|
||||
|
||||
# But when retrieved, it should be decrypted
|
||||
retrieved = self.config_manager.get_configuration("test-openai")
|
||||
assert retrieved["api_key"] == "sk-test123456789"
|
||||
|
||||
def test_list_configurations(self):
|
||||
"""Test listing configurations"""
|
||||
# Add multiple configurations
|
||||
configs = [
|
||||
("config1", {"provider": "ollama", "model_name": "gemma2:9b", "base_url": "http://localhost:11434"}),
|
||||
("config2", {"provider": "openai", "model_name": "gpt-4o", "api_key": "sk-test"}),
|
||||
("config3", {"provider": "openrouter", "model_name": "claude-3.5-sonnet", "api_key": "sk-or-test", "base_url": "https://openrouter.ai/api/v1"})
|
||||
]
|
||||
|
||||
for name, config in configs:
|
||||
self.config_manager.add_configuration(name, config)
|
||||
|
||||
# List configurations
|
||||
config_names = self.config_manager.list_configuration_names()
|
||||
assert len(config_names) == 3
|
||||
assert "config1" in config_names
|
||||
assert "config2" in config_names
|
||||
assert "config3" in config_names
|
||||
|
||||
def test_backup_creation(self):
|
||||
"""Test that backups are created"""
|
||||
config = {
|
||||
"provider": "ollama",
|
||||
"model_name": "gemma2:9b",
|
||||
"base_url": "http://localhost:11434"
|
||||
}
|
||||
|
||||
# Add first configuration
|
||||
self.config_manager.add_configuration("config1", config)
|
||||
|
||||
# Add second configuration (should create backup)
|
||||
config2 = {
|
||||
"provider": "openai",
|
||||
"model_name": "gpt-4o",
|
||||
"api_key": "sk-test"
|
||||
}
|
||||
self.config_manager.add_configuration("config2", config2)
|
||||
|
||||
# Check that backup file exists
|
||||
backup_file = self.config_manager.config_file.with_suffix('.json.bak')
|
||||
assert backup_file.exists()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pytest.main([__file__, "-v"])
|
||||
@@ -0,0 +1,256 @@
|
||||
"""
|
||||
Test suite for MaxClaw Agent provider tools
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
import pytest
|
||||
from unittest.mock import Mock, patch, MagicMock
|
||||
|
||||
# Add parent directory to path
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
from tools.provider_tools import (
|
||||
OllamaProviderTools,
|
||||
OpenAIProviderTools,
|
||||
OpenRouterProviderTools,
|
||||
get_provider_tools
|
||||
)
|
||||
|
||||
|
||||
class TestOllamaProviderTools:
|
||||
"""Test cases for OllamaProviderTools"""
|
||||
|
||||
def setup_method(self):
|
||||
"""Set up test environment"""
|
||||
self.tools = OllamaProviderTools(base_url="http://localhost:11434")
|
||||
|
||||
def test_initialization(self):
|
||||
"""Test OllamaProviderTools initialization"""
|
||||
assert self.tools.provider_name == "ollama"
|
||||
assert self.tools.base_url == "http://localhost:11434"
|
||||
assert self.tools.api_url == "http://localhost:11434/api"
|
||||
|
||||
@patch('requests.get')
|
||||
def test_list_models_success(self, mock_get):
|
||||
"""Test successful model listing"""
|
||||
mock_response = Mock()
|
||||
mock_response.status_code = 200
|
||||
mock_response.json.return_value = {
|
||||
"models": [
|
||||
{"name": "gemma2:9b", "size": 5000000000},
|
||||
{"name": "llama2:7b", "size": 4000000000}
|
||||
]
|
||||
}
|
||||
mock_get.return_value = mock_response
|
||||
|
||||
result = self.tools.list_models()
|
||||
|
||||
assert "Available Ollama Models" in result
|
||||
assert "gemma2:9b" in result
|
||||
assert "llama2:7b" in result
|
||||
|
||||
@patch('requests.get')
|
||||
def test_list_models_failure(self, mock_get):
|
||||
"""Test failed model listing"""
|
||||
mock_get.side_effect = Exception("Connection failed")
|
||||
|
||||
result = self.tools.list_models()
|
||||
|
||||
assert "Error listing models" in result
|
||||
|
||||
@patch('requests.post')
|
||||
def test_get_model_info_success(self, mock_post):
|
||||
"""Test successful model info retrieval"""
|
||||
mock_response = Mock()
|
||||
mock_response.status_code = 200
|
||||
mock_response.json.return_value = {
|
||||
"license": "Apache 2.0",
|
||||
"parameters": "9B",
|
||||
"details": {
|
||||
"parameter_size": "9B",
|
||||
"quantization_level": "Q4_0"
|
||||
}
|
||||
}
|
||||
mock_post.return_value = mock_response
|
||||
|
||||
result = self.tools.get_model_info("gemma2:9b")
|
||||
|
||||
assert "Model Information: gemma2:9b" in result
|
||||
assert "License: Apache 2.0" in result
|
||||
assert "Parameter Size: 9B" in result
|
||||
|
||||
@patch('requests.get')
|
||||
def test_test_connection_success(self, mock_get):
|
||||
"""Test successful connection test"""
|
||||
mock_response = Mock()
|
||||
mock_response.status_code = 200
|
||||
mock_get.return_value = mock_response
|
||||
|
||||
result = self.tools.test_connection()
|
||||
|
||||
assert "✅ Ollama instance at http://localhost:11434 is running" in result
|
||||
|
||||
@patch('requests.get')
|
||||
def test_test_connection_failure(self, mock_get):
|
||||
"""Test failed connection test"""
|
||||
mock_get.side_effect = Exception("Connection failed")
|
||||
|
||||
result = self.tools.test_connection()
|
||||
|
||||
assert "❌ Cannot connect to Ollama instance" in result
|
||||
|
||||
def test_get_tools(self):
|
||||
"""Test tool generation"""
|
||||
tools = self.tools.get_tools()
|
||||
|
||||
assert len(tools) == 6
|
||||
tool_names = [tool.name for tool in tools]
|
||||
assert "ollama_list_models" in tool_names
|
||||
assert "ollama_model_info" in tool_names
|
||||
assert "ollama_test_connection" in tool_names
|
||||
assert "ollama_get_default_model" in tool_names
|
||||
assert "ollama_set_default_model" in tool_names
|
||||
assert "ollama_info" in tool_names
|
||||
|
||||
|
||||
class TestOpenAIProviderTools:
|
||||
"""Test cases for OpenAIProviderTools"""
|
||||
|
||||
def setup_method(self):
|
||||
"""Set up test environment"""
|
||||
self.tools = OpenAIProviderTools(api_key="sk-test123")
|
||||
|
||||
def test_initialization(self):
|
||||
"""Test OpenAIProviderTools initialization"""
|
||||
assert self.tools.provider_name == "openai"
|
||||
assert self.tools.api_key == "sk-test123"
|
||||
assert self.tools.api_url == "https://api.openai.com/v1"
|
||||
|
||||
@patch('requests.get')
|
||||
def test_list_models_success(self, mock_get):
|
||||
"""Test successful model listing"""
|
||||
mock_response = Mock()
|
||||
mock_response.status_code = 200
|
||||
mock_response.json.return_value = {
|
||||
"data": [
|
||||
{"id": "gpt-4o"},
|
||||
{"id": "gpt-4o-mini"},
|
||||
{"id": "gpt-3.5-turbo"}
|
||||
]
|
||||
}
|
||||
mock_get.return_value = mock_response
|
||||
|
||||
result = self.tools.list_models()
|
||||
|
||||
assert "Available OpenAI Models" in result
|
||||
assert "gpt-4o" in result
|
||||
assert "gpt-4o-mini" in result
|
||||
|
||||
@patch('requests.get')
|
||||
def test_test_connection_success(self, mock_get):
|
||||
"""Test successful connection test"""
|
||||
mock_response = Mock()
|
||||
mock_response.status_code = 200
|
||||
mock_response.json.return_value = {"data": []}
|
||||
mock_get.return_value = mock_response
|
||||
|
||||
result = self.tools.test_connection()
|
||||
|
||||
assert "✅ OpenAI API connection successful" in result
|
||||
|
||||
def test_get_tools(self):
|
||||
"""Test tool generation"""
|
||||
tools = self.tools.get_tools()
|
||||
|
||||
assert len(tools) == 6
|
||||
tool_names = [tool.name for tool in tools]
|
||||
assert "openai_list_models" in tool_names
|
||||
assert "openai_model_info" in tool_names
|
||||
assert "openai_test_connection" in tool_names
|
||||
|
||||
|
||||
class TestOpenRouterProviderTools:
|
||||
"""Test cases for OpenRouterProviderTools"""
|
||||
|
||||
def setup_method(self):
|
||||
"""Set up test environment"""
|
||||
self.tools = OpenRouterProviderTools(
|
||||
api_key="sk-or-test123",
|
||||
base_url="https://openrouter.ai/api/v1"
|
||||
)
|
||||
|
||||
def test_initialization(self):
|
||||
"""Test OpenRouterProviderTools initialization"""
|
||||
assert self.tools.provider_name == "openrouter"
|
||||
assert self.tools.api_key == "sk-or-test123"
|
||||
assert self.tools.base_url == "https://openrouter.ai/api/v1"
|
||||
|
||||
@patch('requests.get')
|
||||
def test_list_models_success(self, mock_get):
|
||||
"""Test successful model listing"""
|
||||
mock_response = Mock()
|
||||
mock_response.status_code = 200
|
||||
mock_response.json.return_value = {
|
||||
"data": [
|
||||
{"id": "anthropic/claude-3.5-sonnet", "name": "Claude 3.5 Sonnet"},
|
||||
{"id": "openai/gpt-4o", "name": "GPT-4o"}
|
||||
]
|
||||
}
|
||||
mock_get.return_value = mock_response
|
||||
|
||||
result = self.tools.list_models()
|
||||
|
||||
assert "Available OpenRouter Models" in result
|
||||
assert "anthropic/claude-3.5-sonnet" in result
|
||||
assert "openai/gpt-4o" in result
|
||||
|
||||
def test_get_tools(self):
|
||||
"""Test tool generation"""
|
||||
tools = self.tools.get_tools()
|
||||
|
||||
assert len(tools) == 6
|
||||
tool_names = [tool.name for tool in tools]
|
||||
assert "openrouter_list_models" in tool_names
|
||||
assert "openrouter_model_info" in tool_names
|
||||
assert "openrouter_test_connection" in tool_names
|
||||
|
||||
|
||||
class TestGetProviderTools:
|
||||
"""Test cases for get_provider_tools function"""
|
||||
|
||||
@patch.dict(os.environ, {"OLLAMA_BASE_URL": "http://localhost:11434"})
|
||||
def test_get_ollama_tools(self):
|
||||
"""Test getting Ollama tools"""
|
||||
tools = get_provider_tools("ollama")
|
||||
|
||||
assert len(tools) == 6
|
||||
tool_names = [tool.name for tool in tools]
|
||||
assert "ollama_list_models" in tool_names
|
||||
|
||||
@patch.dict(os.environ, {"OPENAI_API_KEY": "sk-test123"})
|
||||
def test_get_openai_tools(self):
|
||||
"""Test getting OpenAI tools"""
|
||||
tools = get_provider_tools("openai")
|
||||
|
||||
assert len(tools) == 6
|
||||
tool_names = [tool.name for tool in tools]
|
||||
assert "openai_list_models" in tool_names
|
||||
|
||||
@patch.dict(os.environ, {"OPENROUTER_API_KEY": "sk-or-test123"})
|
||||
def test_get_openrouter_tools(self):
|
||||
"""Test getting OpenRouter tools"""
|
||||
tools = get_provider_tools("openrouter")
|
||||
|
||||
assert len(tools) == 6
|
||||
tool_names = [tool.name for tool in tools]
|
||||
assert "openrouter_list_models" in tool_names
|
||||
|
||||
def test_get_unknown_provider_tools(self):
|
||||
"""Test getting tools for unknown provider"""
|
||||
tools = get_provider_tools("unknown")
|
||||
|
||||
assert len(tools) == 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pytest.main([__file__, "-v"])
|
||||
Reference in new issue
Block a user