feat(config): add plugin system configuration options and localization support

This commit is contained in:
LTbinglingfeng
2026-06-13 05:32:16 +08:00
Unverified
parent 6bca83f70a
commit b75d4084aa
7 changed files with 109 additions and 4 deletions
@@ -658,6 +658,13 @@ export function VisualConfigEditor({
disabled={disabled}
onChange={(loggingToFile) => onChange({ loggingToFile })}
/>
<ToggleRow
title={t('config_management.visual.sections.system.plugins_enabled')}
description={t('config_management.visual.sections.system.plugins_enabled_desc')}
checked={values.pluginsEnabled}
disabled={disabled}
onChange={(pluginsEnabled) => onChange({ pluginsEnabled })}
/>
</SectionGrid>
<SectionGrid>
@@ -813,6 +820,17 @@ export function VisualConfigEditor({
disabled={disabled}
/>
</SectionGrid>
<SectionGrid>
<ToggleRow
title={t('config_management.visual.sections.headers.codex_identity_confuse')}
description={t(
'config_management.visual.sections.headers.codex_identity_confuse_desc'
)}
checked={values.codexIdentityConfuse}
disabled={disabled}
onChange={(codexIdentityConfuse) => onChange({ codexIdentityConfuse })}
/>
</SectionGrid>
</SectionStack>
</SectionSubsection>
@@ -931,6 +949,16 @@ export function VisualConfigEditor({
}
/>
</FieldShell>
<Input
label={t('config_management.visual.sections.network.gpt_image_2_base_model')}
placeholder="gpt-5.4-mini"
value={values.gptImage2BaseModel}
onChange={(e) => onChange({ gptImage2BaseModel: e.target.value })}
disabled={disabled}
hint={t(
'config_management.visual.sections.network.gpt_image_2_base_model_hint'
)}
/>
<Input
label={t('config_management.visual.sections.network.session_affinity_ttl')}
placeholder="1h"
+47
View File
@@ -729,9 +729,11 @@ function getNextDirtyFields(
'errorLogsMaxFiles',
'usageStatisticsEnabled',
'redisUsageQueueRetentionSeconds',
'pluginsEnabled',
'passthroughHeaders',
'disableCooling',
'disableImageGeneration',
'gptImage2BaseModel',
'authAutoRefreshWorkers',
'enableGeminiCliEndpoint',
'antigravitySignatureCacheEnabled',
@@ -745,6 +747,7 @@ function getNextDirtyFields(
'claudeHeaderStabilizeDeviceProfile',
'codexHeaderUserAgent',
'codexHeaderBetaFeatures',
'codexIdentityConfuse',
'host',
'port',
'tlsEnable',
@@ -912,6 +915,8 @@ export function useVisualConfig() {
const routing = asRecord(parsed.routing);
const payload = asRecord(parsed.payload);
const streaming = asRecord(parsed.streaming);
const plugins = asRecord(parsed.plugins);
const codex = asRecord(parsed.codex);
const claudeHeaderDefaults = asRecord(parsed['claude-header-defaults']);
const codexHeaderDefaults = asRecord(parsed['codex-header-defaults']);
@@ -939,6 +944,7 @@ export function useVisualConfig() {
authDir: typeof parsed['auth-dir'] === 'string' ? parsed['auth-dir'] : '',
apiKeysText: resolveApiKeysText(parsed),
pluginsEnabled: Boolean(plugins?.enabled),
debug: Boolean(parsed.debug),
commercialMode: Boolean(parsed['commercial-mode']),
@@ -958,6 +964,10 @@ export function useVisualConfig() {
maxRetryInterval: String(parsed['max-retry-interval'] ?? ''),
disableCooling: Boolean(parsed['disable-cooling']),
disableImageGeneration: parseDisableImageGenerationMode(parsed['disable-image-generation']),
gptImage2BaseModel:
typeof parsed['gpt-image-2-base-model'] === 'string'
? parsed['gpt-image-2-base-model']
: '',
authAutoRefreshWorkers: String(parsed['auth-auto-refresh-workers'] ?? ''),
wsAuth: Boolean(parsed['ws-auth']),
enableGeminiCliEndpoint: Boolean(parsed['enable-gemini-cli-endpoint']),
@@ -994,6 +1004,7 @@ export function useVisualConfig() {
typeof codexHeaderDefaults?.['beta-features'] === 'string'
? codexHeaderDefaults['beta-features']
: '',
codexIdentityConfuse: Boolean(codex?.['identity-confuse']),
quotaSwitchProject: Boolean(quotaExceeded?.['switch-project'] ?? true),
quotaSwitchPreviewModel: Boolean(quotaExceeded?.['switch-preview-model'] ?? true),
@@ -1100,6 +1111,16 @@ export function useVisualConfig() {
}
deleteLegacyApiKeysProvider(doc);
if (
docHas(doc, ['plugins']) ||
values.pluginsEnabled ||
shouldWriteManagedField(doc, ['plugins', 'enabled'], dirtyFields, 'pluginsEnabled')
) {
ensureMapInDoc(doc, ['plugins']);
setBooleanInDoc(doc, ['plugins', 'enabled'], values.pluginsEnabled);
deleteIfMapEmpty(doc, ['plugins']);
}
setBooleanInDoc(doc, ['debug'], values.debug);
setBooleanInDoc(doc, ['commercial-mode'], values.commercialMode);
@@ -1125,6 +1146,17 @@ export function useVisualConfig() {
['disable-image-generation'],
values.disableImageGeneration
);
if (
values.gptImage2BaseModel.trim() ||
shouldWriteManagedField(
doc,
['gpt-image-2-base-model'],
dirtyFields,
'gptImage2BaseModel'
)
) {
setStringInDoc(doc, ['gpt-image-2-base-model'], values.gptImage2BaseModel);
}
setIntFromStringInDoc(doc, ['auth-auto-refresh-workers'], values.authAutoRefreshWorkers);
setBooleanInDoc(doc, ['ws-auth'], values.wsAuth);
setBooleanInDoc(doc, ['enable-gemini-cli-endpoint'], values.enableGeminiCliEndpoint);
@@ -1195,6 +1227,21 @@ export function useVisualConfig() {
deleteIfMapEmpty(doc, ['codex-header-defaults']);
}
if (
docHas(doc, ['codex']) ||
values.codexIdentityConfuse ||
shouldWriteManagedField(
doc,
['codex', 'identity-confuse'],
dirtyFields,
'codexIdentityConfuse'
)
) {
ensureMapInDoc(doc, ['codex']);
setBooleanInDoc(doc, ['codex', 'identity-confuse'], values.codexIdentityConfuse);
deleteIfMapEmpty(doc, ['codex']);
}
if (
docHas(doc, ['quota-exceeded']) ||
!values.quotaSwitchProject ||
+7 -1
View File
@@ -918,6 +918,8 @@
"commercial_mode_desc": "Disable high-overhead middleware to support high concurrency",
"logging_to_file": "Log to File",
"logging_to_file_desc": "Save logs to files",
"plugins_enabled": "Enable Plugin System",
"plugins_enabled_desc": "Enable standard dynamic-library plugin loading; individual plugin instances are still managed on the Plugins page",
"logs_max_size": "Log File Size Limit (MB)",
"error_logs_max_files": "Retained Error Log Files",
"usage_statistics_enabled": "Enable In-memory Usage Statistics",
@@ -942,7 +944,9 @@
"timeout": "Timeout",
"stabilize_device": "Stabilize Device Profile",
"stabilize_device_desc": "Pin OS/Arch and stabilize the software fingerprint per credential/API key",
"beta_features": "Beta Features"
"beta_features": "Beta Features",
"codex_identity_confuse": "Codex Identity Confuse",
"codex_identity_confuse_desc": "When fill-first routing or session affinity is used, remap Codex prompt_cache_key and installation identity for the selected auth"
},
"network": {
"title": "Network Configuration",
@@ -959,6 +963,8 @@
"disable_image_generation_false": "false (enabled)",
"disable_image_generation_true": "true (disabled everywhere)",
"disable_image_generation_chat": "chat (disable chat injection only)",
"gpt_image_2_base_model": "GPT Image 2 Base Model",
"gpt_image_2_base_model_hint": "Mainline model used when proxying gpt-image-2 image requests; backend uses its default when empty or invalid",
"routing_strategy": "Routing Strategy",
"routing_strategy_hint": "Select credential selection strategy",
"strategy_round_robin": "Round Robin",
+7 -1
View File
@@ -905,6 +905,8 @@
"commercial_mode_desc": "Отключить тяжёлое промежуточное ПО для поддержки высокой нагрузки",
"logging_to_file": "Журналировать в файл",
"logging_to_file_desc": "Сохранять журналы в файлы",
"plugins_enabled": "Включить систему плагинов",
"plugins_enabled_desc": "Включает загрузку стандартных dynamic-library плагинов; отдельные экземпляры управляются на странице плагинов",
"logs_max_size": "Максимальный размер файла журнала (МБ)",
"error_logs_max_files": "Файлов журнала ошибок",
"usage_statistics_enabled": "Включить статистику использования в памяти",
@@ -929,7 +931,9 @@
"timeout": "Timeout",
"stabilize_device": "Стабилизировать профиль устройства",
"stabilize_device_desc": "Фиксировать OS/Arch и стабилизировать программный отпечаток для учётных данных/API-ключа",
"beta_features": "Beta Features"
"beta_features": "Beta Features",
"codex_identity_confuse": "Codex identity-confuse",
"codex_identity_confuse_desc": "При fill-first routing или session affinity переопределяет Codex prompt_cache_key и installation identity под выбранную auth-запись"
},
"network": {
"title": "Сетевые настройки",
@@ -946,6 +950,8 @@
"disable_image_generation_false": "false (включено)",
"disable_image_generation_true": "true (отключено везде)",
"disable_image_generation_chat": "chat (только отключить chat-инъекцию)",
"gpt_image_2_base_model": "Базовая модель GPT Image 2",
"gpt_image_2_base_model_hint": "Основная модель для проксирования gpt-image-2 image-запросов; если пусто или неверно, backend использует значение по умолчанию",
"routing_strategy": "Стратегия маршрутизации",
"routing_strategy_hint": "Выберите стратегию подбора учётных данных",
"strategy_round_robin": "По кругу",
+7 -1
View File
@@ -918,6 +918,8 @@
"commercial_mode_desc": "禁用高开销中间件以支持高并发",
"logging_to_file": "写入日志文件",
"logging_to_file_desc": "将日志保存到文件",
"plugins_enabled": "启用插件系统",
"plugins_enabled_desc": "启用标准动态库插件加载;具体插件实例仍在插件管理页启停",
"logs_max_size": "日志文件大小限制 (MB)",
"error_logs_max_files": "错误日志保留文件数",
"usage_statistics_enabled": "启用内存用量统计",
@@ -942,7 +944,9 @@
"timeout": "Timeout",
"stabilize_device": "稳定设备指纹",
"stabilize_device_desc": "固定 OS/Arch,并按凭据/API Key 稳定软件指纹",
"beta_features": "Beta Features"
"beta_features": "Beta Features",
"codex_identity_confuse": "Codex 身份混淆",
"codex_identity_confuse_desc": "在 fill-first 或会话粘性路由下,按所选认证重映射 Codex prompt_cache_key 与安装身份"
},
"network": {
"title": "网络配置",
@@ -959,6 +963,8 @@
"disable_image_generation_false": "false(启用)",
"disable_image_generation_true": "true(全部禁用)",
"disable_image_generation_chat": "chat(仅禁用聊天注入)",
"gpt_image_2_base_model": "GPT Image 2 基础模型",
"gpt_image_2_base_model_hint": "代理 gpt-image-2 图片请求时使用的主线模型;留空或非法时后端使用默认值",
"routing_strategy": "路由策略",
"routing_strategy_hint": "选择凭据选择策略",
"strategy_round_robin": "轮询 (Round Robin)",
+7 -1
View File
@@ -944,6 +944,8 @@
"commercial_mode_desc": "停用高開銷中介軟體以支援高並行",
"logging_to_file": "寫入記錄檔",
"logging_to_file_desc": "將記錄儲存到檔案",
"plugins_enabled": "啟用插件系統",
"plugins_enabled_desc": "啟用標準動態庫插件載入;具體插件實例仍在插件管理頁啟停",
"logs_max_size": "記錄檔大小限制(MB",
"error_logs_max_files": "錯誤記錄保留檔案數",
"usage_statistics_enabled": "啟用記憶體用量統計",
@@ -968,7 +970,9 @@
"timeout": "Timeout",
"stabilize_device": "穩定設備指紋",
"stabilize_device_desc": "固定 OS/Arch,並按憑證/API Key 穩定軟體指紋",
"beta_features": "Beta Features"
"beta_features": "Beta Features",
"codex_identity_confuse": "Codex 身分混淆",
"codex_identity_confuse_desc": "在 fill-first 或會話黏性路由下,按所選驗證重映射 Codex prompt_cache_key 與安裝身分"
},
"network": {
"title": "網路設定",
@@ -985,6 +989,8 @@
"disable_image_generation_false": "false(啟用)",
"disable_image_generation_true": "true(全部停用)",
"disable_image_generation_chat": "chat(僅停用聊天注入)",
"gpt_image_2_base_model": "GPT Image 2 基礎模型",
"gpt_image_2_base_model_hint": "代理 gpt-image-2 圖片請求時使用的主線模型;留空或非法時後端使用預設值",
"routing_strategy": "路由策略",
"routing_strategy_hint": "選擇憑證選擇策略",
"strategy_round_robin": "輪詢(Round Robin",
+6
View File
@@ -80,6 +80,7 @@ export type VisualConfigValues = {
rmPanelRepo: string;
authDir: string;
apiKeysText: string;
pluginsEnabled: boolean;
debug: boolean;
commercialMode: boolean;
loggingToFile: boolean;
@@ -95,6 +96,7 @@ export type VisualConfigValues = {
maxRetryInterval: string;
disableCooling: boolean;
disableImageGeneration: DisableImageGenerationMode;
gptImage2BaseModel: string;
authAutoRefreshWorkers: string;
quotaSwitchProject: boolean;
quotaSwitchPreviewModel: boolean;
@@ -115,6 +117,7 @@ export type VisualConfigValues = {
claudeHeaderStabilizeDeviceProfile: boolean;
codexHeaderUserAgent: string;
codexHeaderBetaFeatures: string;
codexIdentityConfuse: boolean;
payloadDefaultRules: PayloadRule[];
payloadDefaultRawRules: PayloadRule[];
payloadOverrideRules: PayloadRule[];
@@ -141,6 +144,7 @@ export const DEFAULT_VISUAL_VALUES: VisualConfigValues = {
rmPanelRepo: '',
authDir: '',
apiKeysText: '',
pluginsEnabled: false,
debug: false,
commercialMode: false,
loggingToFile: false,
@@ -156,6 +160,7 @@ export const DEFAULT_VISUAL_VALUES: VisualConfigValues = {
maxRetryInterval: '',
disableCooling: false,
disableImageGeneration: 'false',
gptImage2BaseModel: '',
authAutoRefreshWorkers: '',
quotaSwitchProject: true,
quotaSwitchPreviewModel: true,
@@ -176,6 +181,7 @@ export const DEFAULT_VISUAL_VALUES: VisualConfigValues = {
claudeHeaderStabilizeDeviceProfile: false,
codexHeaderUserAgent: '',
codexHeaderBetaFeatures: '',
codexIdentityConfuse: false,
payloadDefaultRules: [],
payloadDefaultRawRules: [],
payloadOverrideRules: [],