fix:修复智能引入角色/组织的生成逻辑,同时添加数据校验
This commit is contained in:
+49
-15
@@ -909,7 +909,8 @@ async def _continue_outline(
|
||||
stage_instruction = stage_instructions.get(request.plot_stage, "")
|
||||
|
||||
# 🎭 【方案A】先角色后大纲:在生成大纲前预测并创建角色
|
||||
if request.enable_auto_characters:
|
||||
# 🔧 判断:如果confirmed_organizations存在,说明已经是组织确认阶段,跳过角色处理
|
||||
if request.enable_auto_characters and not request.confirmed_organizations:
|
||||
# 检查是否有用户确认的角色列表
|
||||
if request.confirmed_characters:
|
||||
# 直接使用用户确认的角色列表创建角色
|
||||
@@ -920,8 +921,18 @@ async def _continue_outline(
|
||||
|
||||
auto_char_service = get_auto_character_service(user_ai_service)
|
||||
|
||||
# 🔧 去重检查:获取现有角色名称列表,避免重复创建
|
||||
existing_character_names = {char.name for char in characters}
|
||||
actually_created_count = 0
|
||||
|
||||
for char_data in request.confirmed_characters:
|
||||
try:
|
||||
# 检查角色是否已存在
|
||||
char_name = char_data.get("name") or char_data.get("character_name")
|
||||
if char_name in existing_character_names:
|
||||
logger.warning(f"⚠️ 角色 '{char_name}' 已存在,跳过创建")
|
||||
continue
|
||||
|
||||
# 生成角色详细信息
|
||||
character_data = await auto_char_service._generate_character_details(
|
||||
spec=char_data,
|
||||
@@ -951,6 +962,8 @@ async def _continue_outline(
|
||||
)
|
||||
|
||||
characters.append(character)
|
||||
existing_character_names.add(character.name) # 更新已存在的角色名称集合
|
||||
actually_created_count += 1
|
||||
logger.info(f"✅ 创建确认的角色: {character.name}")
|
||||
|
||||
except Exception as e:
|
||||
@@ -958,7 +971,11 @@ async def _continue_outline(
|
||||
continue
|
||||
|
||||
# 提交角色到数据库
|
||||
await db.commit()
|
||||
if actually_created_count > 0:
|
||||
await db.commit()
|
||||
logger.info(f"✅ 【确认模式】实际创建了 {actually_created_count} 个新角色(跳过了 {len(request.confirmed_characters) - actually_created_count} 个已存在的角色)")
|
||||
else:
|
||||
logger.info(f"ℹ️ 【确认模式】所有角色均已存在,无需创建")
|
||||
|
||||
# 更新角色信息(供后续大纲生成使用)
|
||||
characters_info = "\n".join([
|
||||
@@ -967,8 +984,6 @@ async def _continue_outline(
|
||||
for char in characters
|
||||
])
|
||||
|
||||
logger.info(f"✅ 【确认模式】成功创建 {len(request.confirmed_characters)} 个用户确认的角色")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"⚠️ 【确认模式】创建确认角色失败: {e}", exc_info=True)
|
||||
else:
|
||||
@@ -2058,8 +2073,10 @@ async def continue_outline_generator(
|
||||
# 🎭 【方案A】先角色后大纲:在生成大纲前预测并创建角色
|
||||
enable_auto_characters = data.get("enable_auto_characters", True)
|
||||
confirmed_characters = data.get("confirmed_characters")
|
||||
confirmed_organizations = data.get("confirmed_organizations")
|
||||
|
||||
if enable_auto_characters:
|
||||
# 🔧 判断:如果confirmed_organizations存在,说明已经是组织确认阶段,跳过角色处理
|
||||
if enable_auto_characters and not confirmed_organizations:
|
||||
# 检查是否有用户确认的角色列表
|
||||
if confirmed_characters:
|
||||
# 直接使用用户确认的角色列表创建角色
|
||||
@@ -2075,9 +2092,18 @@ async def continue_outline_generator(
|
||||
|
||||
auto_char_service = get_auto_character_service(user_ai_service)
|
||||
|
||||
created_count = 0
|
||||
# 🔧 去重检查:获取现有角色名称列表,避免重复创建
|
||||
existing_character_names = {char.name for char in characters}
|
||||
actually_created_count = 0
|
||||
|
||||
for char_data in confirmed_characters:
|
||||
try:
|
||||
# 检查角色是否已存在
|
||||
char_name = char_data.get("name") or char_data.get("character_name")
|
||||
if char_name in existing_character_names:
|
||||
logger.warning(f"⚠️ 角色 '{char_name}' 已存在,跳过创建")
|
||||
continue
|
||||
|
||||
# 生成角色详细信息
|
||||
character_data = await auto_char_service._generate_character_details(
|
||||
spec=char_data,
|
||||
@@ -2107,7 +2133,8 @@ async def continue_outline_generator(
|
||||
)
|
||||
|
||||
characters.append(character)
|
||||
created_count += 1
|
||||
existing_character_names.add(character.name) # 更新已存在的角色名称集合
|
||||
actually_created_count += 1
|
||||
logger.info(f"✅ 创建确认的角色: {character.name}")
|
||||
|
||||
except Exception as e:
|
||||
@@ -2115,13 +2142,19 @@ async def continue_outline_generator(
|
||||
continue
|
||||
|
||||
# 提交角色到数据库
|
||||
await db.commit()
|
||||
|
||||
yield await SSEResponse.send_progress(
|
||||
f"✅ 【确认模式】成功创建 {created_count} 个角色",
|
||||
28
|
||||
)
|
||||
logger.info(f"✅ 【确认模式】成功创建 {created_count} 个用户确认的角色")
|
||||
if actually_created_count > 0:
|
||||
await db.commit()
|
||||
yield await SSEResponse.send_progress(
|
||||
f"✅ 【确认模式】实际创建了 {actually_created_count} 个新角色(跳过 {len(confirmed_characters) - actually_created_count} 个已存在)",
|
||||
28
|
||||
)
|
||||
logger.info(f"✅ 【确认模式】实际创建了 {actually_created_count} 个新角色(跳过了 {len(confirmed_characters) - actually_created_count} 个已存在的角色)")
|
||||
else:
|
||||
yield await SSEResponse.send_progress(
|
||||
f"ℹ️ 【确认模式】所有角色均已存在,无需创建",
|
||||
28
|
||||
)
|
||||
logger.info(f"ℹ️ 【确认模式】所有角色均已存在,无需创建")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"⚠️ 【确认模式】创建确认角色失败: {e}", exc_info=True)
|
||||
@@ -2261,7 +2294,8 @@ async def continue_outline_generator(
|
||||
|
||||
# 🏛️ 【组织引入】在生成大纲前预测并创建组织
|
||||
enable_auto_organizations = data.get("enable_auto_organizations", True)
|
||||
confirmed_organizations = data.get("confirmed_organizations")
|
||||
# confirmed_organizations在上面已经获取了,这里注释掉避免重复
|
||||
# confirmed_organizations = data.get("confirmed_organizations")
|
||||
|
||||
if enable_auto_organizations:
|
||||
from app.models.relationship import Organization
|
||||
|
||||
@@ -354,26 +354,14 @@ class AutoCharacterService:
|
||||
mcp_references="" # 暂时不使用MCP增强
|
||||
)
|
||||
|
||||
# 调用AI生成(使用统一的JSON调用方法)
|
||||
# 调用AI生成(禁用MCP,避免累积超时导致卡死)
|
||||
try:
|
||||
if enable_mcp and user_id:
|
||||
result = await self.ai_service.generate_text_with_mcp(
|
||||
prompt=prompt,
|
||||
user_id=user_id,
|
||||
db_session=db,
|
||||
enable_mcp=True,
|
||||
max_tool_rounds=2
|
||||
)
|
||||
content = result.get("content", "")
|
||||
# 使用统一的JSON清洗方法
|
||||
cleaned = self.ai_service._clean_json_response(content)
|
||||
character_data = json.loads(cleaned)
|
||||
else:
|
||||
# 非MCP调用:使用带自动重试的JSON调用
|
||||
character_data = await self.ai_service.call_with_json_retry(
|
||||
prompt=prompt,
|
||||
max_retries=3
|
||||
)
|
||||
# 🔧 优化:角色详情生成不使用MCP,只在分析阶段使用MCP
|
||||
# 这样可以减少大量的外部工具调用,避免超时和卡死
|
||||
character_data = await self.ai_service.call_with_json_retry(
|
||||
prompt=prompt,
|
||||
max_retries=2 # 减少重试次数以加快速度
|
||||
)
|
||||
|
||||
char_name = character_data.get('name', '未知')
|
||||
logger.info(f" ✅ 角色详情生成成功: {char_name}")
|
||||
|
||||
Reference in New Issue
Block a user