Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions astrbot/dashboard/routes/t2i.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
from astrbot.core import logger
from astrbot.core.core_lifecycle import AstrBotCoreLifecycle
from astrbot.core.utils.t2i.template_manager import TemplateManager
from astrbot.core.utils.t2i.network_strategy import (
get_shiki_runtime as _get_shiki_runtime,
)

from .route import Response, Route, RouteContext

Expand All @@ -26,6 +29,7 @@ def __init__(
("/t2i/templates/create", ("POST", self.create_template)),
("/t2i/templates/reset_default", ("POST", self.reset_default_template)),
("/t2i/templates/set_active", ("POST", self.set_active_template)),
("/t2i/shiki_runtime", ("GET", self.get_shiki_runtime)),
# 动态路由应该在静态路由之后注册
(
"/t2i/templates/<name>",
Expand Down Expand Up @@ -235,3 +239,14 @@ async def reset_default_template(self):
response = jsonify(asdict(Response().error(str(e))))
response.status_code = 500
return response

async def get_shiki_runtime(self):
"""获取T2I Shiki运行时"""
try:
runtime = _get_shiki_runtime()
return jsonify(asdict(Response().ok(data={"runtime": runtime})))
except Exception as e:
logger.error("Error in get_shiki_runtime", exc_info=True)
response = jsonify(asdict(Response().error(str(e))))
response.status_code = 500
return response
4 changes: 4 additions & 0 deletions changelogs/v4.23.2.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

## What's Changed

> 在本次更新后,t2i 模板变量将会变更:渲染变量从 `{{ text | safe }}` 改为 `{{ text_base64 }}`,后端改为 base64 编码传输。您需要同步更新模板语法,否则文转图内容将无法正常渲染。

### 新增

- 知识库稀疏检索阶段新增 SQLite FTS5 支持,大幅优化万到十万级别分块时造成的召回时的显著卡顿。([#7648](https://github.com/AstrBotDevs/AstrBot/pull/7648))
Expand Down Expand Up @@ -39,6 +41,8 @@

## What's Changed (EN)

> In this update, the t2i template variable will change: the rendering variable is changed from `{{ text | safe }}` to `{{ text_base64 }}`, and the backend now uses base64 encoding for transmission. Please update your template syntax accordingly, or text-to-image content will not render properly.

### New Features

- Added SQLite FTS5 support to the knowledge-base sparse retrieval stage, greatly reducing recall latency for knowledge bases with tens of thousands to hundreds of thousands of chunks. ([#7648](https://github.com/AstrBotDevs/AstrBot/pull/7648))
Expand Down
50 changes: 46 additions & 4 deletions dashboard/src/components/shared/T2ITemplateEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,18 @@
</div>
</v-card-title>

<v-alert
v-if="showSyntaxMigrationHint"
type="warning"
variant="tonal"
closable
@click:close="dismissMigrationHint"
>
<div class="d-flex align-center">
<span>{{ tm('t2iTemplateEditor.syntaxMigrationHint') }}</span>
</div>
</v-alert>

<v-card-text class="pa-0">
<v-row no-gutters style="height: 70vh;">
<!-- 左侧编辑器 -->
Expand Down Expand Up @@ -271,6 +283,9 @@ const applyAndCloseDialog = ref(false)

const previewFrame = ref(null)

const syntaxHintDismissed = ref(false)
const showSyntaxMigrationHint = ref(false)

// --- 编辑器配置 ---
const editorTheme = computed(() => 'vs-light')
const editorOptions = {
Expand All @@ -296,22 +311,39 @@ const syncPreviewVersion = async () => {
}
}

const shikiRuntime = ref('')
const syncShikiRuntime = async () => {
try {
const res = await axios.get('/api/t2i/shiki_runtime')
shikiRuntime.value = res?.data?.data?.runtime || res?.data?.runtime
} catch (error) {
console.warn('Failed to fetch shiki runtime:', error)
}
}

const previewData = computed(() => ({
text: tm('t2iTemplateEditor.previewText') || '这是一个示例文本,用于预览模板效果。\n\n这里可以包含多行文本,支持换行和各种格式。',
version: previewVersion.value
version: previewVersion.value,
shikiRuntime: shikiRuntime.value
}))

const previewContent = computed(() => {
try {
let content = templateContent.value
content = content.replace(/\{\{\s*text\s*\|\s*safe\s*\}\}/g, previewData.value.text)
content = content.replace(/\{\{\s*text_base64\s*\}\}/g, btoa(String.fromCharCode(...new TextEncoder().encode(previewData.value.text))))
content = content.replace(/\{\{\s*version\s*\}\}/g, previewData.value.version)
content = content.replace(/\{\{\s*shiki_runtime\s*\|\s*safe\s*\}\}/g, previewData.value.shikiRuntime)
return content
} catch (error) {
return `<div style="color: red; padding: 20px;">模板渲染错误: ${error.message}</div>`
}
})

const dismissMigrationHint = () => {
showSyntaxMigrationHint.value = false
syntaxHintDismissed.value = true
}

// --- API 调用方法 ---
const loadInitialData = async () => {
loading.value = true
Expand Down Expand Up @@ -458,11 +490,15 @@ const newTemplate = () => {
<title>New Template</title>
</head>
<body>
<!-- 从这里开始编辑 -->
<article>{{ text | safe }}</article>
<article id="content"></article>

<scr` + `ipt>
document.getElementById('content').textContent = new TextDecoder().decode(Uint8Array.from(atob('{{ text_base64 }}'), c => c.charCodeAt(0)));
</scr` + `ipt>
</body>
</html>
`

}

const promptDelete = () => {
Expand Down Expand Up @@ -522,6 +558,12 @@ watch(selectedTemplate, (newName) => {
}
})

watch(templateContent, (newContent) => {
if (!syntaxHintDismissed.value) {
showSyntaxMigrationHint.value = /\{\{\s*text\s*\|\s*safe\s*\}\}/.test(newContent)
}
})

defineExpose({
openDialog: () => {
dialog.value = true
Expand Down
3 changes: 2 additions & 1 deletion dashboard/src/i18n/locales/en-US/core/shared.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@
"livePreview": "Live Preview (may differ)",
"refreshPreview": "Refresh Preview",
"previewText": "This is a sample text used to preview the template output.\n\nIt can contain multiple lines and various formatting.",
"syntaxHint": "Supports jinja2 syntax. Available variables: text | safe (text to render), version (AstrBot version)",
"syntaxHint": "Supports Jinja2 syntax. Available variables: text_base64 (base64 encoded text to render), shiki_runtime | safe (Shiki runtime environment), version (AstrBot version)",
"syntaxMigrationHint": "Starting from v4.23.2, the rendering variable {{ text | safe }} has been changed to {{ text_base64 }} with base64 encoding. You need to update your template syntax accordingly, or the content will fail to render properly.",
"saveAndApply": "Save and Apply Current Template",
"confirmReset": "Confirm Reset",
"confirmResetMessage": "Are you sure you want to reset the 'base' template to default content? Any unsaved changes in the editor will be lost. This action cannot be undone.",
Expand Down
5 changes: 3 additions & 2 deletions dashboard/src/i18n/locales/ru-RU/core/shared.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@
"livePreview": "Предпросмотр (может отличаться)",
"refreshPreview": "Обновить",
"previewText": "Это пример текста для предпросмотра результата шаблона.\n\nОн может содержать несколько строк и различные форматы.",
"syntaxHint": "Поддерживается синтаксис jinja2. Переменные: text | safe (текст для рендеринга), version (версия AstrBot)",
"syntaxHint": "Поддерживается синтаксис Jinja2. Переменные: text_base64 (base64-кодированный текст для рендеринга), shiki_runtime | safe (среда выполнения Shiki), version (версия AstrBot)",
"syntaxMigrationHint": "Начиная с v4.23.2, переменная рендеринга {{ text | safe }} изменена на {{ text_base64 }} с кодировкой base64. Вам необходимо обновить синтаксис шаблона, иначе содержимое не будет отображаться корректно.",
"saveAndApply": "Сохранить и применить текущий шаблон",
"confirmReset": "Подтверждение сброса",
"confirmResetMessage": "Вы уверены, что хотите сбросить шаблон 'base' до значений по умолчанию? Все несохраненные изменения будут потеряны. Это действие необратимо.",
Expand All @@ -109,4 +110,4 @@
"confirmAction": "Подтверждение действия",
"confirmApplyMessage": "Вы уверены, что хотите сохранить изменения в '{name}' и сделать его активным шаблоном?"
}
}
}
3 changes: 2 additions & 1 deletion dashboard/src/i18n/locales/zh-CN/core/shared.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@
"livePreview": "实时预览(可能有差异)",
"refreshPreview": "刷新预览",
"previewText": "这是一个示例文本,用于预览模板效果。\n\n这里可以包含多行文本,支持换行和各种格式。",
"syntaxHint": "支持 jinja2 语法。可用变量:text | safe(要渲染的文本), version(AstrBot 版本)",
"syntaxHint": "支持 Jinja2 语法。可用变量:text_base64(要渲染文本的 base64 编码)、shiki_runtime | safe(Shiki 运行时环境)、version(AstrBot 版本)",
"syntaxMigrationHint": "从 v4.23.2 开始,渲染变量 {{ text | safe }} 已改为 {{ text_base64 }} 并采用 base64 编码。您需要同步更新模板语法,否则内容将无法正常渲染。",
"saveAndApply": "保存应用当前编辑模板",
"confirmReset": "确认重置",
"confirmResetMessage": "确定要将 'base' 模板恢复为默认内容吗?当前编辑器中的任何未保存更改将丢失。此操作无法撤销。",
Expand Down