-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
feat: add template_list config type to support multiple repeated core/plugin config sets
#4208
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Soulter
merged 4 commits into
AstrBotDevs:master
from
railgun19457:feature/template-list-config
Dec 29, 2025
Merged
feat: add template_list config type to support multiple repeated core/plugin config sets
#4208
Soulter
merged 4 commits into
AstrBotDevs:master
from
railgun19457:feature/template-list-config
Dec 29, 2025
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
…lication - Create ConfigItemRenderer.vue to centralize rendering logic for various config types (string, int, bool, selectors, etc.) - Refactor TemplateListEditor.vue to use the new renderer for entry fields - Refactor AstrBotConfig.vue and AstrBotConfigV4.vue to simplify metadata-driven rendering - Resolve circular dependency by decoupling TemplateListEditor from the base renderer
Contributor
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey - 我发现了 1 个问题,并留下了一些高层次的反馈:
- 在
TemplateListEditor.vue中,ensureEntryDefaults/applyDefaults会就地修改props.modelValue的条目;建议克隆数组/对象并通过 emit 发送更新后的值,以保持 prop 的严格单向数据流,并避免一些微妙的响应式问题。 ConfigItemRenderer.vue按需引入了TemplateListEditor,但从未在模板中渲染(模板中没有template_list分支);可以移除这个 import,或者合并相关处理逻辑,以避免未使用的代码。
给 AI Agent 的提示
Please address the comments from this code review:
## Overall Comments
- 在 `TemplateListEditor.vue` 中,`ensureEntryDefaults`/`applyDefaults` 会就地修改 `props.modelValue` 的条目;建议克隆数组/对象并通过 emit 发送更新后的值,以保持 prop 的严格单向数据流,并避免一些微妙的响应式问题。
- `ConfigItemRenderer.vue` 按需引入了 `TemplateListEditor`,但从未在模板中渲染(模板中没有 `template_list` 分支);可以移除这个 import,或者合并相关处理逻辑,以避免未使用的代码。
## Individual Comments
### Comment 1
<location> `astrbot/dashboard/routes/config.py:64` </location>
<code_context>
if value is None:
data[key] = DEFAULT_VALUE_MAP[meta["type"]]
continue
+ if meta["type"] == "template_list":
+ if not isinstance(value, list):
+ errors.append(
</code_context>
<issue_to_address>
**issue (complexity):** 考虑将 `validate` 中的 `template_list` 处理逻辑和类型检查拆分成一些小的辅助函数,以减少嵌套并将这部分逻辑隔离出来。
你可以在保持现有行为不变的前提下,通过将 `template_list` 相关逻辑提取到一个专门的 helper 中,并复用一个小的类型检查 helper,来降低 `validate` 的复杂度。这样可以拉平条件嵌套,并把分支逻辑局部化。
For example:
```python
def _expect_type(value, expected_type, path_key, errors, expected_name=None):
if not isinstance(value, expected_type):
errors.append(
f"错误的类型 {path_key}: 期望是 {expected_name or expected_type.__name__}, "
f"得到了 {type(value).__name__}"
)
return False
return True
def _validate_template_list(value, meta, path_key, errors):
if not _expect_type(value, list, path_key, errors, "list"):
return
templates = meta.get("templates")
if not isinstance(templates, dict):
templates = {}
for idx, item in enumerate(value):
item_path = f"{path_key}[{idx}]"
if not _expect_type(item, dict, item_path, errors, "dict"):
continue
template_key = item.get("__template_key") or item.get("template")
if not template_key:
errors.append(f"缺少模板选择 {item_path}: 需要 __template_key")
continue
template_meta = templates.get(template_key)
if not template_meta:
errors.append(f"未知模板 {item_path}: {template_key}")
continue
validate(
item,
template_meta.get("items", {}),
path=f"{item_path}.",
)
```
然后 `validate` 可以保持为一个精简的分发器:
```python
if meta["type"] == "template_list":
_validate_template_list(value, meta, f"{path}{key}", errors)
continue
if meta["type"] == "list" and not isinstance(value, list):
errors.append(
f"错误的类型 {path}{key}: 期望是 list, 得到了 {type(value).__name__}",
)
```
这样可以保留当前的全部行为(包括错误信息),同时去掉 `validate` 中多层嵌套的 `if`,让 `template_list` 逻辑更易于测试,并统一类型错误信息的格式。
</issue_to_address>帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈改进后续的审查。
Original comment in English
Hey - I've found 1 issue, and left some high level feedback:
- In
TemplateListEditor.vue,ensureEntryDefaults/applyDefaultsmutateprops.modelValueentries in place; consider cloning the array/object and emitting an updated value instead to keep prop usage strictly one-way and avoid subtle reactivity issues. ConfigItemRenderer.vuelazily importsTemplateListEditorbut never renders it (template has notemplate_listbranch); this import can be removed or the handling consolidated to avoid unused code.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `TemplateListEditor.vue`, `ensureEntryDefaults`/`applyDefaults` mutate `props.modelValue` entries in place; consider cloning the array/object and emitting an updated value instead to keep prop usage strictly one-way and avoid subtle reactivity issues.
- `ConfigItemRenderer.vue` lazily imports `TemplateListEditor` but never renders it (template has no `template_list` branch); this import can be removed or the handling consolidated to avoid unused code.
## Individual Comments
### Comment 1
<location> `astrbot/dashboard/routes/config.py:64` </location>
<code_context>
if value is None:
data[key] = DEFAULT_VALUE_MAP[meta["type"]]
continue
+ if meta["type"] == "template_list":
+ if not isinstance(value, list):
+ errors.append(
</code_context>
<issue_to_address>
**issue (complexity):** Consider extracting the `template_list` handling and type checks from `validate` into small helpers to flatten nesting and isolate that logic.
You can keep the behavior but reduce complexity in `validate` by extracting the `template_list` logic into a focused helper and reusing a small type-check helper. This flattens the nesting and localizes the branching.
For example:
```python
def _expect_type(value, expected_type, path_key, errors, expected_name=None):
if not isinstance(value, expected_type):
errors.append(
f"错误的类型 {path_key}: 期望是 {expected_name or expected_type.__name__}, "
f"得到了 {type(value).__name__}"
)
return False
return True
def _validate_template_list(value, meta, path_key, errors):
if not _expect_type(value, list, path_key, errors, "list"):
return
templates = meta.get("templates")
if not isinstance(templates, dict):
templates = {}
for idx, item in enumerate(value):
item_path = f"{path_key}[{idx}]"
if not _expect_type(item, dict, item_path, errors, "dict"):
continue
template_key = item.get("__template_key") or item.get("template")
if not template_key:
errors.append(f"缺少模板选择 {item_path}: 需要 __template_key")
continue
template_meta = templates.get(template_key)
if not template_meta:
errors.append(f"未知模板 {item_path}: {template_key}")
continue
validate(
item,
template_meta.get("items", {}),
path=f"{item_path}.",
)
```
Then `validate` can stay as a thin dispatcher:
```python
if meta["type"] == "template_list":
_validate_template_list(value, meta, f"{path}{key}", errors)
continue
if meta["type"] == "list" and not isinstance(value, list):
errors.append(
f"错误的类型 {path}{key}: 期望是 list, 得到了 {type(value).__name__}",
)
```
This keeps all current behavior (including error messages) but removes multiple nested `if`s from `validate`, makes `template_list` logic easier to test, and standardizes the type error formatting.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
- Frontend: Fix one-way data flow in TemplateListEditor.vue by cloning entries before applying defaults and emitting updates instead of in-place modification. - Frontend: Remove unused TemplateListEditor import in ConfigItemRenderer.vue. - Backend: Refactor validate_config in config.py by extracting _expect_type and _validate_template_list helpers to reduce nesting and complexity.
Soulter
approved these changes
Dec 29, 2025
template_list config type to support multiple repeated core/plugin config sets
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
area:core
The bug / feature is about astrbot's core, backend
area:webui
The bug / feature is about webui(dashboard) of astrbot.
lgtm
This PR has been approved by a maintainer
size:XXL
This PR changes 1000+ lines, ignoring generated files.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
解决插件配置中需要保存多组重复类型的配置问题
应用场景比如插件中保存多种api供应商(baseurl、key、model),或者人设相关插件,保存多套人设(头像、昵称、人格等)
Modifications / 改动点
修改内容
/dashboard/src/components/shareddashboard/src/i18n/locales/zh-CN/core/common.jsondashboard/src/i18n/locales/en-US/core/common.jsonastrbot/core/config/default.pyastrbot/core/config/astrbot_config.pyastrbot/core/config/astrbot_config.py功能实现
插件开发者可以在_conf_schema中按照以下格式添加模板配置项(有点类似于原有的嵌套配置)
保存后的config为
Screenshots or Test Results / 运行截图或测试结果
测试插件源码
实际存储的config文件
Checklist / 检查清单
requirements.txt和pyproject.toml文件相应位置。/ I have ensured that no new dependencies are introduced, OR if new dependencies are introduced, they have been added to the appropriate locations inrequirements.txtandpyproject.toml.Summary by Sourcery
在仪表盘 UI 中新增对基于模板的列表配置类型的支持,并将配置字段渲染逻辑集中管理。
新功能:
template_list配置类型,使插件能够基于预定义模板存储多条配置项。TemplateListEditorUI 组件,用于管理基于模板的配置列表,包括条件字段和默认值。增强改进:
ConfigItemRenderer组件,并在AstrBotConfig与AstrBotConfigV4中统一使用,以实现一致的行为。template_list字段,并针对不同模板进行条目级校验和合理的默认值处理。template_list相关的 UI 和文案。Original summary in English
Summary by Sourcery
Add support for a new template-based list configuration type and centralize config field rendering in the dashboard UI.
New Features:
Enhancements:
Summary by Sourcery
添加对新的基于模板的列表配置类型的支持,并在仪表盘和后端配置处理中统一配置项的渲染。
新功能:
template_list配置类型,允许基于预定义模板创建多条配置条目。TemplateListEditorUI 组件,用于管理基于模板的配置列表。增强改进:
ConfigItemRenderer组件,并在AstrBotConfig和AstrBotConfigV4中采用,以实现行为一致。template_list字段,包括对每个条目的模板校验以及合理的默认值处理。template_list相关的 UI 与消息。Original summary in English
Summary by Sourcery
Add support for a new template-based list configuration type and centralize config item rendering in both dashboard and backend configuration handling.
New Features:
Enhancements: