Feature(provider): add i18n registration path for provider adapters#6889
Feature(provider): add i18n registration path for provider adapters#6889Li-shi-ling wants to merge 6 commits intoAstrBotDevs:masterfrom
Conversation
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly enhances the flexibility and internationalization capabilities of provider adapters within the system. By introducing dedicated paths for registering i18n resources and configuration metadata, it allows providers to define their own dynamic UI elements and translations. This change streamlines the process of integrating new providers with rich, localized configuration options, ensuring a consistent and user-friendly experience across different languages and provider types. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
There was a problem hiding this comment.
Hey - I've found 1 issue, and left some high level feedback:
- In useProviderSources, the i18n namespace passed to useModuleI18n ('features/config-metadata') differs from the one passed to mergeDynamicTranslations ('features.config-metadata'); aligning these keys will avoid subtle issues where dynamically merged provider translations are not resolved by tmConfigMetadata.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In useProviderSources, the i18n namespace passed to useModuleI18n ('features/config-metadata') differs from the one passed to mergeDynamicTranslations ('features.config-metadata'); aligning these keys will avoid subtle issues where dynamically merged provider translations are not resolved by tmConfigMetadata.
## Individual Comments
### Comment 1
<location path="dashboard/src/composables/useProviderSources.ts" line_range="698" />
<code_context>
+ )
+ metadata["provider_group"]["metadata"]["provider"] = provider_schema["provider"]
return {
"metadata": metadata,
"config": config,
</code_context>
<issue_to_address>
**issue (bug_risk):** Missing `providerSourceSchema` in composable return while dialog expects it.
In `ProviderConfigDialog.vue` you destructure and use `providerSourceSchema` from `useProviderSources`, but that composable only exposes `configSchema`, `providerTemplates`, and `providerTypeMetadata`. As a result, `providerSourceSchema` will be `undefined` and the config UI will fail to render correctly.
Please either expose a computed `providerSourceSchema` from `useProviderSources` (e.g., derived from `configSchema` and `providerTypeMetadata`, similar to how `customSchema` is built in `openConfigDialog`) or update the dialog to use `configSchema` directly if that’s what you intended. The composable’s API and the dialog’s expectations need to be aligned.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| window.removeEventListener('astrbot-locale-changed', loadProviderTemplate) | ||
| }) | ||
|
|
||
| return { |
There was a problem hiding this comment.
issue (bug_risk): Missing providerSourceSchema in composable return while dialog expects it.
In ProviderConfigDialog.vue you destructure and use providerSourceSchema from useProviderSources, but that composable only exposes configSchema, providerTemplates, and providerTypeMetadata. As a result, providerSourceSchema will be undefined and the config UI will fail to render correctly.
Please either expose a computed providerSourceSchema from useProviderSources (e.g., derived from configSchema and providerTypeMetadata, similar to how customSchema is built in openConfigDialog) or update the dialog to use configSchema directly if that’s what you intended. The composable’s API and the dialog’s expectations need to be aligned.
There was a problem hiding this comment.
Code Review
本次 PR 为 Provider 适配器增加了动态注册 config_metadata 和 i18n_resources 的能力,并相应地更新了后端 API 和前端 UI,以支持动态表单生成和国际化。整体实现思路清晰,后端通过新的元数据字段构建了包含 i18n key 的 schema,前端则增加了相应的逻辑来合并和渲染这些动态元数据及翻译。代码改动覆盖了从数据模型、注册机制到 API 路由和前端组件的整个链路,功能实现完整。
我发现了一个可以改进的地方,主要是在前端 Vue 组件中存在直接修改 props 的反模式,这可能会影响代码的可维护性和稳定性。
| function ensureStructuredValue(key, itemMeta) { | ||
| if (!props.iterable || typeof props.iterable !== 'object') { | ||
| return undefined | ||
| } | ||
|
|
||
| if (props.iterable[key] !== undefined && props.iterable[key] !== null) { | ||
| return props.iterable[key] | ||
| } | ||
|
|
||
| if (itemMeta?.type === 'object' || itemMeta?.type === 'dict') { | ||
| props.iterable[key] = {} | ||
| return props.iterable[key] | ||
| } | ||
|
|
||
| if (itemMeta?.type === 'list' || itemMeta?.type === 'template_list') { | ||
| props.iterable[key] = [] | ||
| return props.iterable[key] | ||
| } | ||
|
|
||
| return props.iterable[key] | ||
| } |
There was a problem hiding this comment.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: dd1abfc77a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if provider.i18n_resources: | ||
| self._apply_dynamic_i18n_keys( | ||
| provider_items_to_inject, | ||
| f"provider_group.provider.{provider.type}", | ||
| ) |
There was a problem hiding this comment.
Preserve provider metadata fallback when i18n locale is absent
This rewrites dynamic provider metadata to i18n keys whenever i18n_resources is present, but it does not keep a readable fallback for locales that the plugin does not provide. In that case (for example, plugin only ships zh-CN while UI is en-US), the frontend receives key paths without corresponding translations and renders raw strings like provider_group.provider.xxx.field.hint, making provider-source forms hard to use. Keep original metadata text as fallback (or gate key-rewriting on available locale data) so partially localized providers remain usable.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2a61a1a2f5
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| for (const key of Object.keys(metadataItems)) { | ||
| if (key === 'hint') continue | ||
| result[key] = iterable[key] | ||
| } |
There was a problem hiding this comment.
Render only intended keys in AstrBotConfig forms
This loop now prioritizes all metadata keys instead of the keys actually present in iterable, which breaks callers that intentionally pass a subset object (for example basicSourceConfig/advancedSourceConfig in the provider source UI). Because provider metadata contains fields for many provider types, the form will render unrelated inputs and can push users into editing or saving irrelevant settings; previously only configured keys were shown. Restricting rendered keys to the provided iterable (or making metadata-driven expansion opt-in) avoids this regression.
Useful? React with 👍 / 👎.
本次变更为
register_provider_adapter增加了 i18n 注册路径,与现有的register_platform_adapter行为保持一致。此前,provider 适配器无法通过适配器注册 API 注册自身的
config_metadata和i18n_resources,导致 provider 侧动态 i18n 功能不完整。本 PR 填补了这一空缺,完善了后端到前端的 provider i18n 链路,并在astrbot_plugin_STEmbedding插件上进行了测试。Modifications / 改动点
astrbot/core/provider/entities.pyProviderMetaData,增加config_metadata,i18n_resources参数astrbot/core/provider/register.pyregister_provider_adapter(...),增加config_metadata,i18n_resources参数,将新的元数据字段传递到 provider 注册存储中astrbot/dashboard/routes/config.pyprovider_i18n_translations供前端运行时国际化合并使用,返回provider_type_metadata,使前端能够按当前 provider 类型合并元数据,而不是全局覆盖共享字段dashboard/src/composables/useProviderSources.tsdashboard/src/components/shared/AstrBotConfig.vuedashboard/src/components/chat/ProviderConfigDialog.vue将 provider 源表单渲染改为使用特定 provider 类型的合并 schema,保持对话框行为与主 provider 页面一致,避免渲染路径不一致
This is NOT a breaking change. / 这不是一个破坏性变更。
Screenshots or Test Results / 运行截图或测试结果
测试代码节选
Checklist / 检查清单
😊 If there are new features added in the PR, I have discussed it with the authors through issues/emails, etc.
/ 如果 PR 中有新加入的功能,已经通过 Issue / 邮件等方式和作者讨论过。
[ X ] 👀 My changes have been well-tested, and "Verification Steps" and "Screenshots" have been provided above.
/ 我的更改经过了良好的测试,并已在上方提供了“验证步骤”和“运行截图”。
有进行测试
[ X ] 🤓 I have ensured that no new dependencies are introduced, OR if new dependencies are introduced, they have been added to the appropriate locations in
requirements.txtandpyproject.toml./ 我确保没有引入新依赖库,或者引入了新依赖库的同时将其添加到
requirements.txt和pyproject.toml文件相应位置。没有引入新依赖
[ X ] 😮 My changes do not introduce malicious code.
/ 我的更改没有引入恶意代码。
没有引入恶意代码
Summary by Sourcery
Add dynamic i18n metadata and schema support for provider adapters and expose them to the dashboard so provider-specific configuration and translations can be registered and rendered at runtime.
New Features:
Enhancements: