Some checks failed
Release / semantic-release (push) Successful in 59s
tests / Unit tests (Linux, Python 3.11) (push) Successful in 13m45s
Release / build-linux (push) Failing after 7m47s
Release / build-windows (push) Has been cancelled
Release / build-macos (arm64, macos-latest) (push) Has been cancelled
Release / build-macos (x64, macos-15-intel) (push) Has been cancelled
Release / release-main (push) Has been cancelled
Release / release-develop (push) Has been cancelled
Transform isair/jarvis into a Discord-controlled voice assistant running on the Ubuntu VNC desktop, keeping the mature ~39k-line Python brain intact. - bot/ (Node + bun, discord.js): /자비스 slash commands (ephemeral), voice channel join + voice receive/playback, pluggable VNC screen broadcast (selfbot live / noVNC / screenshot) - bridge/ (Python, Flask): wraps jarvis STT + run_reply_engine + Piper TTS behind a thin localhost HTTP API - .env.example, scripts/ (start_bridge/start_bot/dev), README rewrite, docs/language-comparison.md and docs/vnc-xfce-setup.md Language decision: hybrid (Python brain + Node/bun Discord layer) because Discord blocks bot video; native screen broadcast only works via a Node selfbot library.
123 lines
4.0 KiB
Python
123 lines
4.0 KiB
Python
"""
|
|
Integration tests for MCP tools in the reply engine.
|
|
|
|
These tests require more complex setup and may not run in basic CI environments.
|
|
They can be run locally or in development environments with git hooks.
|
|
"""
|
|
|
|
import pytest
|
|
from unittest.mock import Mock, patch
|
|
|
|
|
|
@pytest.mark.integration
|
|
def test_mcp_tools_integrated_with_reply_engine():
|
|
"""Test that MCP tools are properly integrated with the reply engine's tool discovery."""
|
|
from jarvis.tools.registry import discover_mcp_tools, generate_tools_description, BUILTIN_TOOLS
|
|
|
|
# Mock MCP client
|
|
class FakeMCPClient:
|
|
def __init__(self, config):
|
|
pass
|
|
|
|
def list_tools(self, server_name):
|
|
if server_name == "test-server":
|
|
return [
|
|
{"name": "tool1", "description": "Test tool 1"},
|
|
{"name": "tool2", "description": "Test tool 2"}
|
|
]
|
|
return []
|
|
|
|
with patch('jarvis.tools.registry.MCPClient', FakeMCPClient):
|
|
# Test discovery
|
|
mcps_config = {"test-server": {"command": "fake"}}
|
|
mcp_tools, _errors = discover_mcp_tools(mcps_config)
|
|
|
|
# Test tool registration (simulate what reply engine does)
|
|
allowed_tools = list(BUILTIN_TOOLS.keys())
|
|
for mcp_tool_name in mcp_tools.keys():
|
|
if mcp_tool_name not in allowed_tools:
|
|
allowed_tools.append(mcp_tool_name)
|
|
|
|
# Test tool descriptions include MCP tools
|
|
description = generate_tools_description(allowed_tools, mcp_tools)
|
|
|
|
# Assertions
|
|
assert "test-server__tool1" in allowed_tools
|
|
assert "test-server__tool2" in allowed_tools
|
|
assert "test-server__tool1" in description
|
|
assert "test-server__tool2" in description
|
|
|
|
|
|
@pytest.mark.integration
|
|
def test_mcp_tool_execution_in_context():
|
|
"""Test MCP tool execution with proper context and error handling."""
|
|
from jarvis.tools.registry import run_tool_with_retries, ToolExecutionResult
|
|
|
|
class MockDB:
|
|
pass
|
|
|
|
class MockConfig:
|
|
def __init__(self):
|
|
self.mcps = {"test-server": {"command": "fake"}}
|
|
self.voice_debug = False
|
|
|
|
# Mock successful execution
|
|
class FakeMCPClient:
|
|
def __init__(self, config):
|
|
pass
|
|
|
|
def invoke_tool(self, server_name, tool_name, arguments):
|
|
return {"text": f"Executed {tool_name} on {server_name}", "isError": False}
|
|
|
|
with patch('jarvis.tools.registry.MCPClient', FakeMCPClient):
|
|
result = run_tool_with_retries(
|
|
db=MockDB(),
|
|
cfg=MockConfig(),
|
|
tool_name="test-server__example_tool",
|
|
tool_args={"param": "value"},
|
|
system_prompt="test",
|
|
original_prompt="test",
|
|
redacted_text="test",
|
|
max_retries=0
|
|
)
|
|
|
|
assert result.success is True
|
|
assert "Executed example_tool on test-server" in result.reply_text
|
|
|
|
|
|
@pytest.mark.integration
|
|
def test_mcp_error_handling_in_context():
|
|
"""Test that MCP errors are properly handled in execution context."""
|
|
from jarvis.tools.registry import run_tool_with_retries
|
|
|
|
class MockDB:
|
|
pass
|
|
|
|
class MockConfig:
|
|
def __init__(self):
|
|
self.mcps = {"test-server": {"command": "fake"}}
|
|
self.voice_debug = False
|
|
|
|
# Mock failing execution
|
|
class FailingMCPClient:
|
|
def __init__(self, config):
|
|
pass
|
|
|
|
def invoke_tool(self, server_name, tool_name, arguments):
|
|
return {"text": "Tool failed", "isError": True}
|
|
|
|
with patch('jarvis.tools.registry.MCPClient', FailingMCPClient):
|
|
result = run_tool_with_retries(
|
|
db=MockDB(),
|
|
cfg=MockConfig(),
|
|
tool_name="test-server__failing_tool",
|
|
tool_args={},
|
|
system_prompt="test",
|
|
original_prompt="test",
|
|
redacted_text="test",
|
|
max_retries=0
|
|
)
|
|
|
|
assert result.success is False
|
|
assert result.error_message == "Tool failed"
|