refactor(core): decouple actors and remove workflow templates (#67)

Removes the deprecated `workflow_template` concept entirely across both backend API routers, internal logic handling within the `supervisory_node` and `consciousness_node`, and front-end components. Enables `consciousness_node` to work autonomously.

Also refactors core package structure to enforce the "one python package, one Ray Actor" architectural rule. `GlobalWorkflowManager`, `WorkflowRunningEngine`, `PostgresDatabase`, and `WorkerCluster` have been moved to their own top-level decoupled package directories with properly exported `__init__.py` modules. Test suites have been relocated and import paths updated across the system.

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: zhaoxi826 <198742034+zhaoxi826@users.noreply.github.com>
This commit is contained in:
2026-05-06 15:05:47 +08:00
committed by GitHub
parent b3ea4cd8d9
commit 209ba45477
97 changed files with 1872 additions and 1498 deletions
@@ -7,14 +7,16 @@ real_import = builtins.__import__
def mock_import(name, globals=None, locals=None, fromlist=(), level=0):
if name == 'ray':
if name == "ray":
mock_ray = MagicMock()
def mock_remote(*args, **kwargs):
if len(args) == 1 and callable(args[0]):
return args[0]
def decorator(cls):
return cls
return decorator
mock_ray.remote = mock_remote
@@ -25,10 +27,10 @@ def mock_import(name, globals=None, locals=None, fromlist=(), level=0):
builtins.__import__ = mock_import
for mod in list(sys.modules.keys()):
if 'pretor.core.global_state_machine.global_state_machine' in mod or 'ray' in mod:
if "pretor.core.global_state_machine.global_state_machine" in mod or "ray" in mod:
del sys.modules[mod]
from pretor.core.global_state_machine.global_state_machine import GlobalStateMachine
from pretor.core.global_state_machine.global_state_machine import GlobalStateMachine # noqa: E402
builtins.__import__ = real_import
@@ -82,13 +84,17 @@ async def test_add_provider_unsupported(gsm):
@pytest.mark.asyncio
async def test_add_provider_request_error(gsm):
from httpx import RequestError
mock_provider_class = AsyncMock()
mock_provider_class.create_provider.side_effect = RequestError("Network Error", request=MagicMock())
mock_provider_class.create_provider.side_effect = RequestError(
"Network Error", request=MagicMock()
)
gsm._global_provider_manager.provider_mapper = {"openai": mock_provider_class}
with patch("pretor.utils.logger.global_logger.bind") as mock_bind:
from pretor.utils.error import RetryableError
import pytest
mock_logger = MagicMock()
mock_bind.return_value = mock_logger
with pytest.raises(RetryableError):
@@ -117,3 +123,4 @@ def test_get_provider_list_and_get_provider(gsm):
assert gsm._global_provider_manager.get_provider_list() == {"p1": mock_provider}
assert gsm._global_provider_manager.get_provider("p1") == mock_provider
assert gsm._global_provider_manager.get_provider("missing") is None
# noqa: E402
@@ -1,25 +1,32 @@
from pretor.core.global_state_machine.model_provider.base_provider import Provider, ProviderArgs, ProviderStatus
from pretor.core.global_state_machine.model_provider.base_provider import (
Provider,
ProviderArgs,
ProviderStatus,
)
def test_provider_status():
assert ProviderStatus.UP == "up"
assert ProviderStatus.DOWN == "down"
def test_provider_args():
args = ProviderArgs(
provider_title="title",
provider_url="url",
provider_apikey="key",
provider_owner="1"
provider_owner="1",
)
assert args.provider_title == "title"
def test_provider_model():
p = Provider(
provider_title="title",
provider_url="url",
provider_apikey="key",
provider_models=["model"],
provider_type="openai"
provider_type="openai",
)
assert p.provider_status == ProviderStatus.UP
assert p.provider_owner is None
@@ -1,6 +1,9 @@
import pytest
from unittest.mock import patch, MagicMock, AsyncMock
from pretor.core.global_state_machine.model_provider.claude_provider import ClaudeProvider, ProviderArgs
from pretor.core.global_state_machine.model_provider.claude_provider import (
ClaudeProvider,
ProviderArgs,
)
@pytest.fixture
@@ -9,12 +12,14 @@ def provider_args():
provider_title="TestClaude",
provider_url="https://api.anthropic.com",
provider_apikey="testkey",
provider_owner="1"
provider_owner="1",
)
@pytest.mark.asyncio
@patch("pretor.core.global_state_machine.model_provider.claude_provider.httpx.AsyncClient")
@patch(
"pretor.core.global_state_machine.model_provider.claude_provider.httpx.AsyncClient"
)
async def test_load_models_success(mock_client, provider_args):
mock_response = MagicMock()
mock_response.status_code = 200
@@ -31,7 +36,9 @@ async def test_load_models_success(mock_client, provider_args):
@pytest.mark.asyncio
@patch("pretor.core.global_state_machine.model_provider.claude_provider.httpx.AsyncClient")
@patch(
"pretor.core.global_state_machine.model_provider.claude_provider.httpx.AsyncClient"
)
async def test_load_models_error(mock_client, provider_args):
mock_client_instance = AsyncMock()
mock_client_instance.get.side_effect = Exception("network error")
@@ -42,8 +49,10 @@ async def test_load_models_error(mock_client, provider_args):
@pytest.mark.asyncio
@patch("pretor.core.global_state_machine.model_provider.claude_provider.ClaudeProvider._load_models",
return_value=["claude-3"])
@patch(
"pretor.core.global_state_machine.model_provider.claude_provider.ClaudeProvider._load_models",
return_value=["claude-3"],
)
async def test_create_provider(mock_load, provider_args):
provider = await ClaudeProvider.create_provider(provider_args)
assert provider.provider_title == "TestClaude"
@@ -1,6 +1,9 @@
import pytest
from unittest.mock import patch, MagicMock, AsyncMock
from pretor.core.global_state_machine.model_provider.openai_provider import OpenAIProvider, ProviderArgs
from pretor.core.global_state_machine.model_provider.openai_provider import (
OpenAIProvider,
ProviderArgs,
)
@pytest.fixture
@@ -9,7 +12,7 @@ def provider_args():
provider_title="TestOpenAI",
provider_url="https://api.openai.com/v1",
provider_apikey="testkey",
provider_owner="1"
provider_owner="1",
)
@@ -19,12 +22,14 @@ def provider_args_no_v1():
provider_title="TestOpenAI",
provider_url="https://api.openai.com",
provider_apikey="testkey",
provider_owner="1"
provider_owner="1",
)
@pytest.mark.asyncio
@patch("pretor.core.global_state_machine.model_provider.openai_provider.httpx.AsyncClient")
@patch(
"pretor.core.global_state_machine.model_provider.openai_provider.httpx.AsyncClient"
)
async def test_load_models_success(mock_client, provider_args):
mock_response = MagicMock()
mock_response.status_code = 200
@@ -40,12 +45,14 @@ async def test_load_models_success(mock_client, provider_args):
assert models == ["gpt-3.5-turbo", "gpt-4"]
mock_client_instance.get.assert_called_once_with(
"https://api.openai.com/v1/models",
headers={"Authorization": "Bearer testkey", "Content-Type": "application/json"}
headers={"Authorization": "Bearer testkey", "Content-Type": "application/json"},
)
@pytest.mark.asyncio
@patch("pretor.core.global_state_machine.model_provider.openai_provider.httpx.AsyncClient")
@patch(
"pretor.core.global_state_machine.model_provider.openai_provider.httpx.AsyncClient"
)
async def test_load_models_no_v1(mock_client, provider_args_no_v1):
mock_response = MagicMock()
mock_response.status_code = 200
@@ -59,12 +66,14 @@ async def test_load_models_no_v1(mock_client, provider_args_no_v1):
assert models == []
mock_client_instance.get.assert_called_once_with(
"https://api.openai.com/v1/models",
headers={"Authorization": "Bearer testkey", "Content-Type": "application/json"}
headers={"Authorization": "Bearer testkey", "Content-Type": "application/json"},
)
@pytest.mark.asyncio
@patch("pretor.core.global_state_machine.model_provider.openai_provider.httpx.AsyncClient")
@patch(
"pretor.core.global_state_machine.model_provider.openai_provider.httpx.AsyncClient"
)
async def test_load_models_status_error(mock_client, provider_args):
mock_response = MagicMock()
mock_response.status_code = 401
@@ -78,21 +87,29 @@ async def test_load_models_status_error(mock_client, provider_args):
@pytest.mark.asyncio
@patch("pretor.core.global_state_machine.model_provider.openai_provider.httpx.AsyncClient")
@patch(
"pretor.core.global_state_machine.model_provider.openai_provider.httpx.AsyncClient"
)
async def test_load_models_request_error(mock_client, provider_args):
import httpx
mock_client_instance = AsyncMock()
mock_client_instance.get.side_effect = httpx.RequestError("network error", request=MagicMock())
mock_client_instance.get.side_effect = httpx.RequestError(
"network error", request=MagicMock()
)
mock_client.return_value.__aenter__.return_value = mock_client_instance
import pytest
from pretor.utils.error import RetryableError
with pytest.raises(RetryableError):
await OpenAIProvider._load_models(provider_args)
@pytest.mark.asyncio
@patch("pretor.core.global_state_machine.model_provider.openai_provider.httpx.AsyncClient")
@patch(
"pretor.core.global_state_machine.model_provider.openai_provider.httpx.AsyncClient"
)
async def test_load_models_generic_error(mock_client, provider_args):
mock_client_instance = AsyncMock()
mock_client_instance.get.side_effect = Exception("generic error")
@@ -103,8 +120,10 @@ async def test_load_models_generic_error(mock_client, provider_args):
@pytest.mark.asyncio
@patch("pretor.core.global_state_machine.model_provider.openai_provider.OpenAIProvider._load_models",
return_value=["gpt-4"])
@patch(
"pretor.core.global_state_machine.model_provider.openai_provider.OpenAIProvider._load_models",
return_value=["gpt-4"],
)
async def test_create_provider(mock_load, provider_args):
provider = await OpenAIProvider.create_provider(provider_args)
assert provider.provider_title == "TestOpenAI"
@@ -13,11 +13,15 @@ async def test_provider_manager_init():
mock_provider2.provider_title = "title2"
mock_postgres.get_provider = MagicMock()
mock_postgres.get_provider.remote = AsyncMock(return_value=[mock_provider1, mock_provider2])
mock_postgres.get_provider.remote = AsyncMock(
return_value=[mock_provider1, mock_provider2]
)
manager = ProviderManager(mock_postgres)
mock_postgres.provider_database = MagicMock()
mock_postgres.provider_database.remote = AsyncMock(return_value=[mock_provider1, mock_provider2])
mock_postgres.provider_database.remote = AsyncMock(
return_value=[mock_provider1, mock_provider2]
)
await manager.init_provider_register(mock_postgres)
assert "openai" in manager.provider_mapper
@@ -1,5 +1,6 @@
from pretor.core.global_state_machine.tool_manager import GlobalToolManager
def test_global_tool_manager_init():
manager = GlobalToolManager()
assert isinstance(manager, GlobalToolManager)