From 6c5b01fa3c991bd9fcb675985fda2c55569a0c00 Mon Sep 17 00:00:00 2001 From: dadachann <185672915+dadachann@users.noreply.github.com> Date: Fri, 26 Jun 2026 12:50:26 -0400 Subject: [PATCH] fix(ci): ruff/prettier format, fix test_importutil assertion --- .../http/controller/groups/platform/bots.py | 5 ++- src/langbot/pkg/api/http/service/bot.py | 12 +++--- src/langbot/pkg/command/cmdmgr.py | 1 + src/langbot/pkg/entity/persistence/bot.py | 4 +- .../alembic/versions/0007_add_bot_admins.py | 8 ++-- tests/unit_tests/utils/test_importutil.py | 4 +- web/src/app/home/bots/BotDetailContent.tsx | 14 ++++++- .../components/bot-admins/BotAdminsPanel.tsx | 39 ++++++++++++++----- 8 files changed, 58 insertions(+), 29 deletions(-) diff --git a/src/langbot/pkg/api/http/controller/groups/platform/bots.py b/src/langbot/pkg/api/http/controller/groups/platform/bots.py index ab234fa05..e3a13b789 100644 --- a/src/langbot/pkg/api/http/controller/groups/platform/bots.py +++ b/src/langbot/pkg/api/http/controller/groups/platform/bots.py @@ -59,6 +59,7 @@ class BotsRouterGroup(group.RouterGroup): return self.success(data={'sent': True}) except Exception as e: import traceback + traceback.print_exc() return self.http_status(500, -1, f'Failed to send message: {str(e)}') @@ -81,7 +82,9 @@ class BotsRouterGroup(group.RouterGroup): except Exception as e: return self.http_status(409, -1, str(e)) - @self.route('//admins/', methods=['DELETE'], auth_type=group.AuthType.USER_TOKEN_OR_API_KEY) + @self.route( + '//admins/', methods=['DELETE'], auth_type=group.AuthType.USER_TOKEN_OR_API_KEY + ) async def _(bot_uuid: str, admin_id: int) -> str: await self.ap.bot_service.delete_bot_admin(bot_uuid, admin_id) return self.success() diff --git a/src/langbot/pkg/api/http/service/bot.py b/src/langbot/pkg/api/http/service/bot.py index f31efcf7f..995267cf5 100644 --- a/src/langbot/pkg/api/http/service/bot.py +++ b/src/langbot/pkg/api/http/service/bot.py @@ -204,18 +204,15 @@ class BotService: async def get_bot_admins(self, bot_uuid: str) -> list[dict]: from ....entity.persistence import bot as persistence_bot + result = await self.ap.persistence_mgr.execute_async( - sqlalchemy.select(persistence_bot.BotAdmin).where( - persistence_bot.BotAdmin.bot_uuid == bot_uuid - ) + sqlalchemy.select(persistence_bot.BotAdmin).where(persistence_bot.BotAdmin.bot_uuid == bot_uuid) ) - return [ - {'id': r.id, 'launcher_type': r.launcher_type, 'launcher_id': r.launcher_id} - for r in result.all() - ] + return [{'id': r.id, 'launcher_type': r.launcher_type, 'launcher_id': r.launcher_id} for r in result.all()] async def add_bot_admin(self, bot_uuid: str, launcher_type: str, launcher_id: str) -> int: from ....entity.persistence import bot as persistence_bot + result = await self.ap.persistence_mgr.execute_async( sqlalchemy.insert(persistence_bot.BotAdmin).values( bot_uuid=bot_uuid, @@ -227,6 +224,7 @@ class BotService: async def delete_bot_admin(self, bot_uuid: str, admin_id: int) -> None: from ....entity.persistence import bot as persistence_bot + await self.ap.persistence_mgr.execute_async( sqlalchemy.delete(persistence_bot.BotAdmin).where( persistence_bot.BotAdmin.bot_uuid == bot_uuid, diff --git a/src/langbot/pkg/command/cmdmgr.py b/src/langbot/pkg/command/cmdmgr.py index e955b6eac..ee064c219 100644 --- a/src/langbot/pkg/command/cmdmgr.py +++ b/src/langbot/pkg/command/cmdmgr.py @@ -86,6 +86,7 @@ class CommandManager: import sqlalchemy as _sa from ..entity.persistence.bot import BotAdmin as _BotAdmin + _admins = await self.ap.persistence_mgr.execute_async( _sa.select(_BotAdmin).where( _BotAdmin.bot_uuid == (query.bot_uuid or ''), diff --git a/src/langbot/pkg/entity/persistence/bot.py b/src/langbot/pkg/entity/persistence/bot.py index 6ff8512f9..9043b7560 100644 --- a/src/langbot/pkg/entity/persistence/bot.py +++ b/src/langbot/pkg/entity/persistence/bot.py @@ -14,9 +14,7 @@ class BotAdmin(Base): launcher_id = sqlalchemy.Column(sqlalchemy.String(255), nullable=False) created_at = sqlalchemy.Column(sqlalchemy.DateTime, nullable=False, server_default=sqlalchemy.func.now()) - __table_args__ = ( - sqlalchemy.UniqueConstraint('bot_uuid', 'launcher_type', 'launcher_id', name='uq_bot_admin'), - ) + __table_args__ = (sqlalchemy.UniqueConstraint('bot_uuid', 'launcher_type', 'launcher_id', name='uq_bot_admin'),) class Bot(Base): diff --git a/src/langbot/pkg/persistence/alembic/versions/0007_add_bot_admins.py b/src/langbot/pkg/persistence/alembic/versions/0007_add_bot_admins.py index 2f6c96944..a13f2caa6 100644 --- a/src/langbot/pkg/persistence/alembic/versions/0007_add_bot_admins.py +++ b/src/langbot/pkg/persistence/alembic/versions/0007_add_bot_admins.py @@ -44,13 +44,12 @@ def upgrade() -> None: # Read instance_config metadata key that holds the admins list if 'metadata' not in tables: return - meta_row = conn.execute( - sa.text("SELECT value FROM metadata WHERE key = 'instance_config'") - ).first() + meta_row = conn.execute(sa.text("SELECT value FROM metadata WHERE key = 'instance_config'")).first() if meta_row is None: return import json + try: cfg = json.loads(meta_row[0]) except Exception: @@ -65,8 +64,7 @@ def upgrade() -> None: try: conn.execute( sa.text( - 'INSERT OR IGNORE INTO bot_admins (bot_uuid, launcher_type, launcher_id)' - ' VALUES (:bu, :lt, :li)' + 'INSERT OR IGNORE INTO bot_admins (bot_uuid, launcher_type, launcher_id) VALUES (:bu, :lt, :li)' ), {'bu': first_bot_uuid, 'lt': launcher_type, 'li': launcher_id}, ) diff --git a/tests/unit_tests/utils/test_importutil.py b/tests/unit_tests/utils/test_importutil.py index bf0e4e050..cfd7fc23e 100644 --- a/tests/unit_tests/utils/test_importutil.py +++ b/tests/unit_tests/utils/test_importutil.py @@ -138,7 +138,7 @@ class TestReadResourceFile: from langbot.pkg.utils import importutil content = importutil.read_resource_file('templates/config.yaml') - assert 'admins:' in content + assert 'api:' in content assert 'edition: community' in content def test_raises_for_nonexistent_file(self): @@ -157,7 +157,7 @@ class TestReadResourceFileBytes: from langbot.pkg.utils import importutil content = importutil.read_resource_file_bytes('templates/config.yaml') - assert b'admins:' in content + assert b'api:' in content assert b'edition: community' in content def test_raises_for_nonexistent_file_bytes(self): diff --git a/web/src/app/home/bots/BotDetailContent.tsx b/web/src/app/home/bots/BotDetailContent.tsx index 118b3f8d0..df197dc50 100644 --- a/web/src/app/home/bots/BotDetailContent.tsx +++ b/web/src/app/home/bots/BotDetailContent.tsx @@ -27,7 +27,14 @@ import type { BotSessionMonitorHandle } from '@/app/home/bots/components/bot-ses import { httpClient } from '@/app/infra/http/HttpClient'; import { useSidebarData } from '@/app/home/components/home-sidebar/SidebarDataContext'; import { useTranslation } from 'react-i18next'; -import { Settings, FileText, Users, RefreshCw, Trash2, ShieldCheck } from 'lucide-react'; +import { + Settings, + FileText, + Users, + RefreshCw, + Trash2, + ShieldCheck, +} from 'lucide-react'; import { cn } from '@/lib/utils'; import { toast } from 'sonner'; @@ -298,7 +305,10 @@ export default function BotDetailContent({ id }: { id: string }) { {/* Tab: Admins */} - +
diff --git a/web/src/app/home/bots/components/bot-admins/BotAdminsPanel.tsx b/web/src/app/home/bots/components/bot-admins/BotAdminsPanel.tsx index 4d7f3e85b..55fbd6a6c 100644 --- a/web/src/app/home/bots/components/bot-admins/BotAdminsPanel.tsx +++ b/web/src/app/home/bots/components/bot-admins/BotAdminsPanel.tsx @@ -37,7 +37,9 @@ export default function BotAdminsPanel({ botId }: { botId: string }) { } }, [botId]); - useEffect(() => { load(); }, [load]); + useEffect(() => { + load(); + }, [load]); async function handleAdd() { if (!newId.trim()) return; @@ -72,7 +74,9 @@ export default function BotAdminsPanel({ botId }: { botId: string }) { - {t('bots.admins.typePerson')} + + {t('bots.admins.typePerson')} + {t('bots.admins.typeGroup')} @@ -83,32 +87,49 @@ export default function BotAdminsPanel({ botId }: { botId: string }) { onChange={(e) => setNewId(e.target.value)} onKeyDown={(e) => e.key === 'Enter' && handleAdd()} /> - {loading ? ( -
{t('bots.sessionMonitor.loading')}
+
+ {t('bots.sessionMonitor.loading')} +
) : admins.length === 0 ? ( -
{t('bots.admins.noAdmins')}
+
+ {t('bots.admins.noAdmins')} +
) : (
- - + + {admins.map((admin) => ( - +
{t('bots.admins.launcherType')}{t('bots.admins.launcherId')} + {t('bots.admins.launcherType')} + + {t('bots.admins.launcherId')} +
- {admin.launcher_type === 'person' ? t('bots.admins.typePerson') : t('bots.admins.typeGroup')} + {admin.launcher_type === 'person' + ? t('bots.admins.typePerson') + : t('bots.admins.typeGroup')} {admin.launcher_id}