feat(i18n): localize backend messages by workspace language

This commit is contained in:
Hyu
2026-10-15 05:31:04 +00:00
committed by RockChinQ
parent b1d9484876
commit e29fd27f02
74 changed files with 2296 additions and 177 deletions
@@ -10,6 +10,7 @@ from sqlalchemy.ext.asyncio import create_async_engine
from langbot.pkg.api.http.controller import group
from langbot.pkg.persistence.mgr import PersistenceManager, PersistenceMode
from langbot.pkg.entity.persistence.metadata import WorkspaceMetadata
pytestmark = pytest.mark.asyncio
@@ -20,6 +21,8 @@ async def test_authenticated_route_does_not_hold_database_session_during_externa
release = asyncio.Event()
observations: list[bool] = []
engine = create_async_engine('sqlite+aiosqlite:///:memory:')
async with engine.begin() as connection:
await connection.run_sync(WorkspaceMetadata.__table__.create)
persistence = PersistenceManager(object(), mode=PersistenceMode.CLOUD_RUNTIME)
persistence.db = SimpleNamespace(get_engine=lambda: engine)
@@ -60,7 +63,7 @@ async def test_authenticated_route_does_not_hold_database_session_during_externa
)
)
try:
await entered.wait()
await asyncio.wait_for(entered.wait(), timeout=5)
assert observations == [True]
release.set()
response = await request
@@ -15,6 +15,7 @@ from langbot.pkg.api.http.controller.groups.provider.providers import ModelProvi
from langbot.pkg.api.http.service.provider import ModelProviderService
from langbot.pkg.entity.persistence.model import CodexCredential, EmbeddingModel, LLMModel, ModelProvider, RerankModel
from langbot.pkg.entity.persistence.user import User
from langbot.pkg.entity.persistence.metadata import WorkspaceMetadata
from langbot.pkg.entity.persistence.workspace import Workspace
from langbot.pkg.persistence.mgr import PersistenceManager, PersistenceMode
from langbot.pkg.provider.modelmgr.modelmgr import ModelManager
@@ -51,7 +52,7 @@ async def deletion(tmp_path):
}
async with engine.begin() as conn:
for table in (User, Workspace, ModelProvider, CodexCredential, *MODEL_TYPES):
for table in (User, Workspace, WorkspaceMetadata, ModelProvider, CodexCredential, *MODEL_TYPES):
await conn.run_sync(table.__table__.create)
for workspace in contexts:
await conn.execute(
@@ -357,7 +357,7 @@ class TestUserServiceAuthenticate:
service = UserService(ap)
# Execute & Verify
with pytest.raises(ValueError, match='用户不存在'):
with pytest.raises(ValueError, match='Resource not found'):
await service.authenticate('[email protected]', 'password')
async def test_authenticate_space_user_without_password_raises_error(self):
@@ -377,7 +377,7 @@ class TestUserServiceAuthenticate:
service = UserService(ap)
# Execute & Verify
with pytest.raises(ValueError, match='请使用 LangBot 账号登录'):
with pytest.raises(ValueError, match='Please sign in with your LangBot Account'):
await service.authenticate('[email protected]', 'password')
@@ -418,7 +418,6 @@ class TestUserServiceGenerateJwtToken:
assert token is not None
class TestUserServiceVerifyJwtToken:
"""Tests for verify_jwt_token method."""
@@ -99,7 +99,11 @@ async def test_extensions_route_redacts_plugin_secrets_without_mutating_runtime_
@pytest.mark.asyncio
async def test_extensions_parallel_reads_open_explicit_child_task_scopes():
from langbot.pkg.entity.persistence.metadata import WorkspaceMetadata
engine = create_async_engine('sqlite+aiosqlite:///:memory:')
async with engine.begin() as connection:
await connection.run_sync(WorkspaceMetadata.__table__.create)
account = SimpleNamespace(uuid='account-a', user='[email protected]')
ap = SimpleNamespace()
ap.persistence_mgr = PersistenceManager(ap)
+12
View File
@@ -65,3 +65,15 @@ async def test_mcp_server_exposes_bot_event_route_tools():
assert 'test_bot_event_route' not in tool_names
assert 'list_processors' in tool_names
assert 'list_agents' not in tool_names
assert 'get_workspace_message_language' in tool_names
language_tool = next(tool for tool in tools if tool.name == 'set_workspace_message_language')
assert set(language_tool.inputSchema['properties']['language']['enum']) == {
'en_US',
'zh_Hans',
'zh_Hant',
'ja_JP',
'es_ES',
'ru_RU',
'th_TH',
'vi_VN',
}