Compare commits

..

2 Commits

Author SHA1 Message Date
Soulter
7f6aeffd03 feat(i18n): update session management translations and improve provider configuration handling
- Updated English and Chinese translations for session management, including "Unified Message Origin" and "Follow Config".
- Enhanced provider configuration options to include "Follow Config" as a selectable item.
- Removed unused clear buttons and refactored provider configuration saving logic to handle updates and deletions more efficiently.
2025-11-27 13:23:00 +08:00
Soulter
c51de491a5 refactor: umo custom rules 2025-11-27 13:06:51 +08:00
7 changed files with 40 additions and 61 deletions

View File

@@ -1,7 +1,7 @@
import asyncio
import traceback
from astrbot.core import astrbot_config, logger, sp
from astrbot.core import logger, sp
from astrbot.core.astrbot_config_mgr import AstrBotConfigManager
from astrbot.core.db import BaseDatabase
@@ -24,7 +24,6 @@ class ProviderManager:
db_helper: BaseDatabase,
persona_mgr: PersonaManager,
):
self.reload_lock = asyncio.Lock()
self.persona_mgr = persona_mgr
self.acm = acm
config = acm.confs["default"]
@@ -227,7 +226,6 @@ class ProviderManager:
async def load_provider(self, provider_config: dict):
if not provider_config["enable"]:
logger.info(f"Provider {provider_config['id']} is disabled, skipping")
return
if provider_config.get("provider_type", "") == "agent_runner":
return
@@ -436,46 +434,40 @@ class ProviderManager:
)
async def reload(self, provider_config: dict):
async with self.reload_lock:
await self.terminate_provider(provider_config["id"])
if provider_config["enable"]:
await self.load_provider(provider_config)
await self.terminate_provider(provider_config["id"])
if provider_config["enable"]:
await self.load_provider(provider_config)
# 和配置文件保持同步
self.providers_config = astrbot_config["provider"]
config_ids = [provider["id"] for provider in self.providers_config]
logger.info(f"providers in user's config: {config_ids}")
for key in list(self.inst_map.keys()):
if key not in config_ids:
await self.terminate_provider(key)
# 和配置文件保持同步
config_ids = [provider["id"] for provider in self.providers_config]
logger.debug(f"providers in user's config: {config_ids}")
for key in list(self.inst_map.keys()):
if key not in config_ids:
await self.terminate_provider(key)
if len(self.provider_insts) == 0:
self.curr_provider_inst = None
elif self.curr_provider_inst is None and len(self.provider_insts) > 0:
self.curr_provider_inst = self.provider_insts[0]
logger.info(
f"自动选择 {self.curr_provider_inst.meta().id} 作为当前提供商适配器。",
)
if len(self.provider_insts) == 0:
self.curr_provider_inst = None
elif self.curr_provider_inst is None and len(self.provider_insts) > 0:
self.curr_provider_inst = self.provider_insts[0]
logger.info(
f"自动选择 {self.curr_provider_inst.meta().id} 作为当前提供商适配器。",
)
if len(self.stt_provider_insts) == 0:
self.curr_stt_provider_inst = None
elif (
self.curr_stt_provider_inst is None and len(self.stt_provider_insts) > 0
):
self.curr_stt_provider_inst = self.stt_provider_insts[0]
logger.info(
f"自动选择 {self.curr_stt_provider_inst.meta().id} 作为当前语音转文本提供商适配器。",
)
if len(self.stt_provider_insts) == 0:
self.curr_stt_provider_inst = None
elif self.curr_stt_provider_inst is None and len(self.stt_provider_insts) > 0:
self.curr_stt_provider_inst = self.stt_provider_insts[0]
logger.info(
f"自动选择 {self.curr_stt_provider_inst.meta().id} 作为当前语音转文本提供商适配器。",
)
if len(self.tts_provider_insts) == 0:
self.curr_tts_provider_inst = None
elif (
self.curr_tts_provider_inst is None and len(self.tts_provider_insts) > 0
):
self.curr_tts_provider_inst = self.tts_provider_insts[0]
logger.info(
f"自动选择 {self.curr_tts_provider_inst.meta().id} 作为当前文本转语音提供商适配器。",
)
if len(self.tts_provider_insts) == 0:
self.curr_tts_provider_inst = None
elif self.curr_tts_provider_inst is None and len(self.tts_provider_insts) > 0:
self.curr_tts_provider_inst = self.tts_provider_insts[0]
logger.info(
f"自动选择 {self.curr_tts_provider_inst.meta().id} 作为当前文本转语音提供商适配器。",
)
def get_insts(self):
return self.provider_insts

View File

@@ -69,7 +69,7 @@ const sidebarItem: menu[] = [
},
{
title: 'core.navigation.sessionManagement',
icon: 'mdi-pencil-ruler',
icon: 'mdi-account-group',
to: '/session-management'
},
{

View File

@@ -4,8 +4,7 @@
<v-card flat>
<v-card-title class="d-flex align-center py-3 px-4">
<span class="text-h4">{{ tm('customRules.title') }}</span>
<v-btn icon="mdi-information-outline" size="small" variant="text" href="https://astrbot.app/use/custom-rules.html" target="_blank"></v-btn>
<v-chip size="small" class="ml-1">{{ totalItems }} {{ tm('customRules.rulesCount') }}</v-chip>
<v-chip size="small" class="ml-2">{{ totalItems }} {{ tm('customRules.rulesCount') }}</v-chip>
<v-row class="me-4 ms-4" dense>
<v-text-field v-model="searchQuery" prepend-inner-icon="mdi-magnify" :label="tm('search.placeholder')"
hide-details clearable variant="solo-filled" flat class="me-4" density="compact"></v-text-field>
@@ -29,8 +28,8 @@
<v-card-text class="pa-0">
<v-data-table-server :headers="headers" :items="filteredRulesList" :loading="loading"
:items-length="totalItems" v-model:items-per-page="itemsPerPage" v-model:page="currentPage"
@update:options="onTableOptionsUpdate" class="elevation-0" style="font-size: 12px;" v-model="selectedItems"
show-select item-value="umo" return-object>
@update:options="onTableOptionsUpdate" class="elevation-0" style="font-size: 12px;"
v-model="selectedItems" show-select item-value="umo" return-object>
<!-- UMO 信息 -->
<template v-slot:item.umo_info="{ item }">
@@ -41,8 +40,7 @@
</v-chip>
<span class="text-truncate" style="max-width: 300px;">{{ item.umo }}</span>
<div class="d-flex align-center" v-if="item.rules?.session_service_config?.custom_name || true">
<span class="ml-2" style="color: gray; font-size: 10px;"
v-if="item.rules?.session_service_config?.custom_name">
<span class="ml-2" style="color: gray; font-size: 10px;" v-if="item.rules?.session_service_config?.custom_name">
({{ item.rules?.session_service_config?.custom_name }})
</span>
<v-btn icon size="x-small" variant="text" class="ml-1" @click.stop="openQuickEditName(item)">
@@ -259,7 +257,7 @@
<v-spacer></v-spacer>
<v-btn variant="text" @click="deleteDialog = false">{{ tm('buttons.cancel') }}</v-btn>
<v-btn color="error" variant="tonal" @click="deleteAllRules" :loading="deleting">{{ tm('buttons.delete')
}}</v-btn>
}}</v-btn>
</v-card-actions>
</v-card>
</v-dialog>

View File

@@ -41,6 +41,7 @@ class ProcessLLMRequest:
if default_persona:
persona_id = default_persona["name"]
persona = next(
builtins.filter(
lambda persona: persona["name"] == persona_id,

View File

@@ -14,7 +14,7 @@ from astrbot.core.utils.session_waiter import (
)
class Main(Star):
class Waiter(Star):
"""会话控制"""
def __init__(self, context: Context):

View File

@@ -21,17 +21,7 @@ async def core_lifecycle_td(tmp_path_factory):
log_broker = LogBroker()
core_lifecycle = AstrBotCoreLifecycle(log_broker, db)
await core_lifecycle.initialize()
try:
yield core_lifecycle
finally:
# 优先停止核心生命周期以释放资源(包括关闭 MCP 等后台任务)
try:
_stop_res = core_lifecycle.stop()
if asyncio.iscoroutine(_stop_res):
await _stop_res
except Exception:
# 停止过程中如有异常,不影响后续清理
pass
return core_lifecycle
@pytest.fixture(scope="module")

View File

@@ -39,7 +39,6 @@ def plugin_manager_pm(tmp_path):
message_history_manager = MagicMock()
persona_manager = MagicMock()
astrbot_config_mgr = MagicMock()
knowledge_base_manager = MagicMock()
star_context = Context(
event_queue,
@@ -51,7 +50,6 @@ def plugin_manager_pm(tmp_path):
message_history_manager,
persona_manager,
astrbot_config_mgr,
knowledge_base_manager=knowledge_base_manager,
)
# Create the PluginManager instance