Skip to content

Commit 5c0e44e

Browse files
committed
feat: enhance adapter update process with improved error handling and logging
- Added logging for errors during adapter stopping and starting processes to improve debuggability. - Enhanced the update_adapter function to handle adapter renaming and type validation more robustly. - Implemented checks for existing adapter names and types, returning appropriate error messages for invalid requests. - Updated the response structure to reflect the new adapter name and running status after updates.
1 parent 5e47776 commit 5c0e44e

File tree

1 file changed

+60
-29
lines changed

1 file changed

+60
-29
lines changed

kirara_ai/web/api/im/routes.py

Lines changed: 60 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@
77
from kirara_ai.im.adapter import BotProfileAdapter
88
from kirara_ai.im.im_registry import IMRegistry
99
from kirara_ai.im.manager import IMManager
10+
from kirara_ai.logger import get_logger
1011

1112
from ...auth.middleware import require_auth
1213
from .models import (IMAdapterConfig, IMAdapterConfigSchema, IMAdapterList, IMAdapterResponse, IMAdapterStatus,
1314
IMAdapterTypes)
1415

1516
im_bp = Blueprint("im", __name__)
1617

18+
logger = get_logger("Web.IM")
19+
1720
def _create_adapter(manager: IMManager, name: str, adapter: str, config: dict):
1821
registry: IMRegistry = g.container.resolve(IMRegistry)
1922
adapter_info = registry.get_all_adapters()[adapter]
@@ -123,48 +126,76 @@ async def create_adapter():
123126
@im_bp.route("/adapters/<adapter_id>", methods=["PUT"])
124127
@require_auth
125128
async def update_adapter(adapter_id: str):
126-
"""更新适配器配置"""
129+
"""更新适配器配置 (支持重命名)"""
127130
data = await request.get_json()
128-
adapter_info = IMAdapterConfig(**data)
129-
registry: IMRegistry = g.container.resolve(IMRegistry)
130-
131-
if adapter_id != adapter_info.name:
132-
return jsonify({"error": "Adapter ID mismatch"}), 400
131+
try:
132+
adapter_info = IMAdapterConfig(**data)
133+
except Exception as e:
134+
return jsonify({"error": f"Invalid request data: {e}"}), 400
133135

134136
config: GlobalConfig = g.container.resolve(GlobalConfig)
135137
manager: IMManager = g.container.resolve(IMManager)
138+
registry: IMRegistry = g.container.resolve(IMRegistry)
136139
loop = asyncio.get_event_loop()
137140

138-
# 检查适配器是否存在
141+
# 1. 检查原始适配器是否存在
139142
if not manager.has_adapter(adapter_id):
140143
return jsonify({"error": "Adapter not found"}), 404
141144

142-
# 更新配置
143-
adapter_config_class = registry.get_config_class(adapter_info.adapter)
144-
adapter_config = adapter_config_class(**adapter_info.config)
145-
manager.update_adapter_config(adapter_id, adapter_config)
145+
# 2. 如果名称改变,检查新名称是否冲突
146+
if adapter_id != adapter_info.name and manager.has_adapter(adapter_info.name):
147+
return jsonify({"error": f"Adapter name '{adapter_info.name}' already exists"}), 400
146148

147-
# 保存配置到文件
148-
ConfigLoader.save_config_with_backup(CONFIG_FILE, config)
149+
# 3. 检查适配器类型是否有效
150+
if adapter_info.adapter not in registry.get_all_adapters():
151+
return jsonify({"error": "Invalid adapter type specified"}), 400
149152

150-
# 如果适配器正在运行,需要重启
151-
is_running = manager.is_adapter_running(adapter_id)
152-
if is_running:
153-
await manager.stop_adapter(adapter_id, loop)
154-
155-
_create_adapter(manager, adapter_id, adapter_info.adapter, adapter_info.config)
156-
153+
# --- 停止旧适配器 (如果正在运行) ---
154+
if manager.is_adapter_running(adapter_id):
155+
try:
156+
await manager.stop_adapter(adapter_id, loop)
157+
except Exception as e:
158+
logger.error(f"Error stopping adapter {adapter_id}: {e}")
159+
160+
# --- 更新 IMManager ---
161+
# 从管理器中删除旧的实例
162+
manager.delete_adapter(adapter_id)
163+
164+
# 使用新名称和配置创建新的实例
165+
_create_adapter(manager, adapter_info.name, adapter_info.adapter, adapter_info.config)
166+
config.ims.append(adapter_info)
167+
168+
# --- 尝试启动新适配器 (如果启用) ---
169+
is_now_running = False
157170
if adapter_info.enable:
158-
await manager.start_adapter(adapter_id, loop)
171+
try:
172+
await manager.start_adapter(adapter_info.name, loop)
173+
is_now_running = True
174+
except Exception as e:
175+
logger.error(f"Failed to start adapter '{adapter_info.name}' after update: {e}")
159176

160-
return IMAdapterResponse(
161-
adapter=IMAdapterStatus(
162-
name=adapter_id,
163-
adapter=adapter_info.adapter,
164-
is_running=is_running,
165-
config=adapter_info.config,
166-
)
167-
).model_dump()
177+
# --- 保存配置到文件 ---
178+
# 无论是否启动成功,都保存更新后的配置
179+
ConfigLoader.save_config_with_backup(CONFIG_FILE, config)
180+
181+
# --- 准备并返回响应 ---
182+
bot_profile = None
183+
if is_now_running: # 仅在成功启动后尝试获取 profile
184+
adapter_instance = manager.get_adapter(adapter_info.name)
185+
if isinstance(adapter_instance, BotProfileAdapter):
186+
try:
187+
# 添加超时以防卡住
188+
bot_profile = await asyncio.wait_for(adapter_instance.get_bot_profile(), timeout=5.0)
189+
except Exception as e:
190+
logger.error(f"Failed to get bot profile for {adapter_info.name} after update: {e}")
191+
192+
return IMAdapterResponse(adapter=IMAdapterStatus(
193+
name=adapter_info.name, # 使用新名称
194+
adapter=adapter_info.adapter,
195+
is_running=is_now_running, # 反映当前实际运行状态
196+
config=adapter_info.config,
197+
bot_profile=bot_profile
198+
)).model_dump()
168199

169200

170201
@im_bp.route("/adapters/<adapter_id>", methods=["DELETE"])

0 commit comments

Comments
 (0)