fix: wizard preview TLS, progress storage and inactive bot logs (#2651)

This commit is contained in:
RockChinQ
2026-10-12 00:15:58 +08:00
committed by GitHub
parent 13446ecfd3
commit 80ea528ca0
5 changed files with 57 additions and 3 deletions
+2 -1
View File
@@ -776,7 +776,8 @@ class BotService:
raise WorkspaceNotFoundError('Bot not found')
runtime_bot = await self.ap.platform_mgr.get_bot_by_uuid(context, bot_uuid)
if runtime_bot is None:
raise Exception('Bot not found')
# Saved but disabled/unconfigured bots have no runtime logs yet.
return [], 0
logs, total_count = await runtime_bot.logger.get_logs(from_index, max_count)
@@ -9,7 +9,7 @@ class Metadata(Base):
__tablename__ = 'metadata'
key = sqlalchemy.Column(sqlalchemy.String(255), primary_key=True)
value = sqlalchemy.Column(sqlalchemy.String(255))
value = sqlalchemy.Column(sqlalchemy.Text())
class WorkspaceMetadata(Base):
@@ -23,4 +23,4 @@ class WorkspaceMetadata(Base):
primary_key=True,
)
key = sqlalchemy.Column(sqlalchemy.String(255), primary_key=True)
value = sqlalchemy.Column(sqlalchemy.String(255))
value = sqlalchemy.Column(sqlalchemy.Text())
@@ -0,0 +1,22 @@
"""Allow structured wizard progress in metadata values."""
from alembic import op
import sqlalchemy as sa
revision = '0037_metadata_text'
down_revision = '0036_execution_host_leases'
branch_labels = None
depends_on = None
def upgrade():
inspector = sa.inspect(op.get_bind())
for table in ('metadata', 'workspace_metadata'):
if inspector.has_table(table):
with op.batch_alter_table(table) as batch:
batch.alter_column('value', existing_type=sa.String(255), type_=sa.Text(), existing_nullable=True)
def downgrade():
# Keep the widened type: narrowing would destroy valid saved progress.
pass
+11
View File
@@ -174,6 +174,17 @@
bubbleIcon: "__LANGBOT_BUBBLE_ICON__",
};
// Wizard previews must use the browser-visible backend URL. Behind a TLS
// proxy the server's request URL can be HTTP even when widget.js uses HTTPS.
// External embeds retain their configured public webhook prefix.
if (scriptEl && scriptEl.src) {
var scriptUrl = new URL(scriptEl.src, document.baseURI);
if (scriptUrl.searchParams.get("preview") === "wizard") {
CONFIG.baseUrl = scriptUrl.origin;
CONFIG.logoUrl = CONFIG.baseUrl + "/api/v1/embed/logo";
}
}
// ========== Styles ==========
var STYLES =
'\
@@ -0,0 +1,20 @@
from types import SimpleNamespace
from unittest.mock import AsyncMock
import pytest
import sqlalchemy
from langbot.pkg.entity.persistence.metadata import Metadata, WorkspaceMetadata
from langbot.pkg.api.http.service.bot import BotService
def test_metadata_supports_long_wizard_json():
for model in (Metadata, WorkspaceMetadata):
assert isinstance(model.__table__.c.value.type, sqlalchemy.Text)
@pytest.mark.asyncio
async def test_saved_bot_without_runtime_has_empty_logs():
service = BotService(SimpleNamespace(platform_mgr=SimpleNamespace(get_bot_by_uuid=AsyncMock(return_value=None))))
service.get_bot = AsyncMock(return_value={'uuid': 'bot'})
assert await service.list_event_logs('workspace', 'bot', 0, 20) == ([], 0)