chore(release): v0.1.1-alpha

##前端美化和bug修复
#### 💄 美化
- **前端美化**:对于整个前端效果进行了重新设计,现在的前端看起来会更立体。

#### 🐛 修复
- **前端演示**:修复了前端展示workflow列表的bug,但是workflow的具体条目显示由于序列化导致仍然有问题。 
- **密钥修复**:对于secret_key现在在使用默认情况时,会强制生成一个安全的密钥。
This commit is contained in:
2026-05-04 16:38:21 +08:00
committed by GitHub
parent d84212f780
commit d30c7e37a6
92 changed files with 2449 additions and 863 deletions
-145
View File
@@ -1,145 +0,0 @@
import pytest
from unittest.mock import MagicMock, AsyncMock, patch
import json
import sys
import builtins
real_import = builtins.__import__
def mock_import(name, globals=None, locals=None, fromlist=(), level=0):
if name == 'sqlmodel':
mock_sqlmodel = MagicMock()
class DummySQLModel:
def __init_subclass__(cls, **kwargs):
pass
mock_sqlmodel.SQLModel = DummySQLModel
mock_sqlmodel.Field = MagicMock(return_value=None)
mock_sqlmodel.select = MagicMock()
return mock_sqlmodel
return real_import(name, globals, locals, fromlist, level)
builtins.__import__ = mock_import
for mod in list(sys.modules.keys()):
if 'pretor.core.database.module.memory' in mod or 'sqlmodel' in mod:
del sys.modules[mod]
from pretor.core.database.module.memory import MemoryRAG
builtins.__import__ = real_import
@pytest.fixture(autouse=True)
def mock_dependencies():
with patch("pretor.core.database.module.memory.WorkflowRecord") as mock_workflow_record:
with patch("pretor.core.database.module.memory.MemoryRecord") as mock_memory_record:
with patch("pretor.core.database.module.memory.select") as mock_select:
yield mock_workflow_record, mock_memory_record, mock_select
@pytest.fixture
def mock_session_maker():
maker = MagicMock()
session = AsyncMock()
session.add = MagicMock()
maker.return_value.__aenter__.return_value = session
maker.__aenter__.return_value = session
maker.__aexit__ = AsyncMock()
return maker, session
@pytest.mark.asyncio
async def test_save_workflow(mock_session_maker, mock_dependencies):
mock_workflow_record, _, _ = mock_dependencies
maker, session = mock_session_maker
rag = MemoryRAG(maker)
mock_record = MagicMock()
mock_workflow_record.return_value = mock_record
workflow_data = {"key": "value"}
record = await rag.save_workflow("wf_123", workflow_data)
mock_workflow_record.assert_called_once_with(
workflow_id="wf_123",
workflow_data_json=json.dumps(workflow_data)
)
session.add.assert_called_once_with(mock_record)
session.commit.assert_called_once()
session.refresh.assert_called_once_with(mock_record)
assert record == mock_record
@pytest.mark.asyncio
async def test_get_workflow_success(mock_session_maker, mock_dependencies):
_, _, mock_select = mock_dependencies
maker, session = mock_session_maker
rag = MemoryRAG(maker)
mock_statement = MagicMock()
mock_select.return_value.where.return_value = mock_statement
mock_record = MagicMock()
mock_record.workflow_data_json = '{"key": "value"}'
mock_exec_result = MagicMock()
mock_exec_result.scalar_one_or_none.return_value = mock_record
session.execute = AsyncMock(return_value=mock_exec_result)
data = await rag.get_workflow("wf_123")
session.execute.assert_called_once_with(mock_statement)
assert data == {"key": "value"}
@pytest.mark.asyncio
async def test_get_workflow_not_found(mock_session_maker, mock_dependencies):
_, _, mock_select = mock_dependencies
maker, session = mock_session_maker
rag = MemoryRAG(maker)
mock_exec_result = MagicMock()
mock_exec_result.scalar_one_or_none.return_value = None
session.execute = AsyncMock(return_value=mock_exec_result)
data = await rag.get_workflow("wf_123")
assert data is None
@pytest.mark.asyncio
async def test_add_memory(mock_session_maker, mock_dependencies):
_, mock_memory_record, _ = mock_dependencies
maker, session = mock_session_maker
rag = MemoryRAG(maker)
mock_record = MagicMock()
mock_memory_record.return_value = mock_record
record = await rag.add_memory("text", [0.1, 0.2])
mock_memory_record.assert_called_once_with(memory_text="text", embedding=[0.1, 0.2])
session.add.assert_called_once_with(mock_record)
session.commit.assert_called_once()
session.refresh.assert_called_once_with(mock_record)
assert record == mock_record
@pytest.mark.asyncio
async def test_retrieve_memory(mock_session_maker, mock_dependencies):
_, _, mock_select = mock_dependencies
maker, session = mock_session_maker
rag = MemoryRAG(maker)
mock_statement = MagicMock()
mock_select.return_value.limit.return_value = mock_statement
mock_exec_result = MagicMock()
mock_exec_result.all.return_value = ["res1", "res2"]
session.execute = AsyncMock(return_value=mock_exec_result)
results = await rag.retrieve_memory([0.1, 0.2], 5)
session.execute.assert_called_once_with(mock_statement)
assert results == ["res1", "res2"]
@@ -1,8 +1,6 @@
import pytest
import asyncio
from unittest.mock import MagicMock, AsyncMock, patch
import sys
import builtins
real_import = builtins.__import__
@@ -31,8 +29,6 @@ for mod in list(sys.modules.keys()):
del sys.modules[mod]
from pretor.core.global_state_machine.global_state_machine import GlobalStateMachine
from pretor.api.platform.event import PretorEvent
from pretor.core.workflow.workflow import PretorWorkflow
builtins.__import__ = real_import
@@ -48,53 +44,6 @@ def gsm(mock_postgres):
return manager
def test_add_delete_get_event(gsm):
event = MagicMock(spec=PretorEvent)
event.trace_id = "123"
gsm.add_event(event)
assert getattr(event, 'pending_queue', None) is not None
assert getattr(event, 'receive_queue', None) is not None
retrieved = gsm.get_event("123")
assert retrieved == event
gsm.delete_event("123")
assert gsm.get_event("123") is None
def test_update_attachment_and_workflow(gsm):
event = MagicMock(spec=PretorEvent)
event.trace_id = "abc"
gsm.add_event(event)
gsm.update_attachment("abc", {"k": "v"})
assert event.attachment == {"k": "v"}
wf = MagicMock(spec=PretorWorkflow)
gsm.update_workflow("abc", wf)
assert event.workflow == wf
@pytest.mark.asyncio
async def test_queues(gsm):
event = MagicMock(spec=PretorEvent)
event.trace_id = "q_event"
# To use await put/get, we must actually use real asyncio queues for the mock event
event.pending_queue = asyncio.Queue()
event.receive_queue = asyncio.Queue()
gsm.event_dict["q_event"] = event
await gsm.put_pending("q_event", "item1")
res1 = await gsm.get_pending("q_event")
assert res1 == "item1"
await gsm.put_received("q_event", "item2")
res2 = await gsm.get_received("q_event")
assert res2 == "item2"
@pytest.mark.asyncio
async def test_add_provider_success(gsm, mock_postgres):
mock_provider_class = AsyncMock()
+8 -3
View File
@@ -147,16 +147,21 @@ async def test_workflow_running_engine_runner():
# Mock the global_state_machine get_skill_list.remote method properly
mock_gsm = MagicMock()
mock_gsm.get_skill_list.remote = AsyncMock(return_value={"test_skill": ("description", "instructions")})
mock_gsm.list_individuals.remote = AsyncMock(return_value={"test_skill": {"agent_type": "skill_individual", "agent_name": "TestSkill", "description": "desc"}})
engine.global_state_machine = mock_gsm
with patch("pretor.core.workflow.workflow_runner.WorkflowEngine") as mock_wf_engine_cls, patch("builtins.open", new_callable=MagicMock) as mock_open:
with patch("pretor.core.workflow.workflow_runner.WorkflowEngine") as mock_wf_engine_cls, patch("builtins.open", new_callable=MagicMock) as mock_open, \
patch("pretor.core.workflow.workflow_runner.ray_actor_hook") as mock_hook:
# Instead of patching hook, we inject it directly
engine.global_state_machine = AsyncMock()
# engine.global_state_machine = AsyncMock()
mock_open.return_value.__enter__.return_value.read.return_value = '{}'
mock_gwm = MagicMock()
mock_gwm.update_workflow.remote = AsyncMock()
mock_hook.return_value.global_workflow_manager = mock_gwm
mock_engine_instance = MagicMock()
mock_engine_instance.run = AsyncMock()
mock_wf_engine_cls.return_value = mock_engine_instance