Skip to content
Merged

Dev #55

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/semantic-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
pip install -e .

- name: Run tests
run: python run_tests.py --regression --feature
run: python run_tests.py --regression --feature --skip requires_api_key

release:
needs: test
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ dependencies = [
"ollama==0.5.1",
"openai==1.97.0",

"hatch @ git+https://github.com/CrackingShells/Hatch.git@feat/dependency-installers"
"hatch @ git+https://github.com/CrackingShells/Hatch.git@v0.5.1"
]

[project.scripts]
Expand Down
34 changes: 34 additions & 0 deletions tests/feature_test_llm_provider_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,23 @@ def llm_to_hatchling_tool_call(self, event):
def mcp_to_provider_tool(self, tool_info):
"""Mock implementation of mcp_to_provider_tool."""
return {"type": "function", "function": {"name": tool_info.name}}

def hatchling_to_llm_tool_call(self, tool_call):
"""Mock implementation of hatchling_to_llm_tool_call."""
return {
"id": tool_call.tool_call_id,
"function": {
"name": tool_call.function_name,
"arguments": tool_call.arguments
}
}

def hatchling_to_provider_tool_result(self, tool_result):
"""Mock implementation of hatchling_to_provider_tool_result."""
return {
"tool_call_id": tool_result.tool_call_id,
"content": str(tool_result.result)
}

# Should be able to instantiate concrete implementation
test_settings = test_data.get_test_settings()
Expand Down Expand Up @@ -164,6 +181,23 @@ def llm_to_hatchling_tool_call(self, event):
def mcp_to_provider_tool(self, tool_info):
"""Mock implementation of mcp_to_provider_tool."""
return {"type": "function", "function": {"name": tool_info.name}}

def hatchling_to_llm_tool_call(self, tool_call):
"""Mock implementation of hatchling_to_llm_tool_call."""
return {
"id": tool_call.tool_call_id,
"function": {
"name": tool_call.function_name,
"arguments": tool_call.arguments
}
}

def hatchling_to_provider_tool_result(self, tool_result):
"""Mock implementation of hatchling_to_provider_tool_result."""
return {
"tool_call_id": tool_result.tool_call_id,
"content": str(tool_result.result)
}

provider = OllamaProvider({})
self.assertEqual(provider.provider_name, "ollama",
Expand Down
24 changes: 22 additions & 2 deletions tests/feature_test_mcp_tool_call_subscriber.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,21 @@
using provider methods directly instead of the registry pattern.
"""

import os
import sys
import logging
import unittest
import time
from pathlib import Path
from asyncio.log import logger
from unittest.mock import MagicMock
from dotenv import load_dotenv

from tests.test_decorators import feature_test, requires_api_key

from hatchling.config.openai_settings import OpenAISettings
from hatchling.config.settings import AppSettings
from hatchling.core.llm.event_system import Event, EventType

from hatchling.mcp_utils.mcp_tool_execution import MCPToolExecution
from hatchling.mcp_utils.mcp_tool_call_subscriber import MCPToolCallSubscriber
from hatchling.core.llm.providers.registry import ProviderRegistry
Expand Down Expand Up @@ -98,8 +103,23 @@ def test_on_event_openai(self):
timestamp=time.time()
)

# load the test api key from local .env
# Load environment variables for API key
env_path = Path(__file__).parent / ".env"
if load_dotenv(env_path):
logger.info("Loaded environment variables from .env file")
else:
logger.warning("No .env file found, using system environment variables")

api_key = os.environ.get('OPENAI_API_KEY')
if not api_key:
logger.warning("OPENAI_API_KEY environment variable not set")
self.skipTest("OpenAI API key is not set. Please set OPENAI_API_KEY environment variable.")

# Use provider to get the strategy
provider = ProviderRegistry.get_provider(ELLMProvider.OPENAI)
openai_settings = OpenAISettings(api_key=api_key, timeout=30.0)
app_settings = AppSettings(openai=openai_settings)
provider = ProviderRegistry.get_provider(ELLMProvider.OPENAI, app_settings)
subscriber = MCPToolCallSubscriber(self.mock_tool_execution)
subscriber.on_event(first_event)

Expand Down
17 changes: 17 additions & 0 deletions tests/feature_test_provider_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,23 @@ def llm_to_hatchling_tool_call(self, event):
def mcp_to_provider_tool(self, tool_info):
"""Mock implementation of mcp_to_provider_tool."""
return {"type": "function", "function": {"name": tool_info.name}}

def hatchling_to_llm_tool_call(self, tool_call):
"""Mock implementation of hatchling_to_llm_tool_call."""
return {
"id": tool_call.tool_call_id,
"function": {
"name": tool_call.function_name,
"arguments": tool_call.arguments
}
}

def hatchling_to_provider_tool_result(self, tool_result):
"""Mock implementation of hatchling_to_provider_tool_result."""
return {
"tool_call_id": tool_result.tool_call_id,
"content": str(tool_result.result)
}

return TestProvider

Expand Down
8 changes: 4 additions & 4 deletions tests/integration_test_command_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,11 @@ def test_mcp_command_structure(self):
'mcp:tool:info',
'mcp:tool:enable',
'mcp:tool:disable',
'mcp:tool:execute',
'mcp:tool:schema',
#'mcp:tool:execute',
#'mcp:tool:schema',
'mcp:health',
'mcp:citations',
'mcp:reset'
#'mcp:citations',
#'mcp:reset'
]

for cmd_name in expected_commands:
Expand Down
5 changes: 3 additions & 2 deletions tests/integration_test_openai.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
from hatchling.config.openai_settings import OpenAISettings
from hatchling.config.settings import AppSettings
from hatchling.config.llm_settings import ELLMProvider
from hatchling.mcp_utils.mcp_tool_lifecycle_subscriber import ToolLifecycleSubscriber
from hatchling.core.llm.providers.registry import ProviderRegistry
from hatchling.mcp_utils.mcp_tool_data import MCPToolInfo, MCPToolStatus, MCPToolStatusReason
from hatchling.core.llm.event_system import (
Expand All @@ -47,7 +46,6 @@
EventType,
Event
)
from hatchling.mcp_utils.mcp_tool_lifecycle_subscriber import ToolLifecycleSubscriber
from hatchling.core.llm.providers.openai_provider import OpenAIProvider

logger = logging.getLogger("integration_test_openai")
Expand Down Expand Up @@ -165,6 +163,7 @@ def tearDown(self):
self.loop.close()

@integration_test
@requires_api_key
def test_provider_registration(self):
"""Test that OpenAIProvider is properly registered in the provider registry.

Expand Down Expand Up @@ -238,6 +237,7 @@ def test_health_check_sync(self):
self.fail(f"Health check test failed: {e}")

@integration_test
@requires_api_key
def test_payload_preparation(self):
"""Test chat payload preparation for API requests.

Expand Down Expand Up @@ -430,6 +430,7 @@ def test_simple_chat_integration_sync(self):
self.fail(f"Simple chat integration test failed: {e}")

@integration_test
@requires_api_key
def test_api_key_validation(self):
"""Test that provider validates API key requirement.

Expand Down
Loading