Files
SillyTavern_replica/test_preset_complete_flow.py
2026-05-05 19:08:25 +08:00

274 lines
8.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
完整的预设排序流程测试
验证:导入 → 保存 → 加载 → 展示的完整流程中顺序是否正确保持
"""
import json
from pathlib import Path
print("=" * 80)
print("预设排序完整流程测试")
print("=" * 80)
# ==================== 步骤 1: 创建原始 SillyTavern 文件 ====================
print("\n[步骤 1] 创建原始 SillyTavern 预设文件(乱序)")
print("-" * 80)
original_data = {
"name": "Complete_Flow_Test",
"temperature": 0.85,
"frequency_penalty": 0.4,
"presence_penalty": 0.25,
"top_p": 0.92,
"top_k": 45,
"max_tokens": 3072,
# prompts 数组是乱序的
"prompts": [
{
"identifier": "char_personality",
"name": "Character Personality",
"system_prompt": True,
"role": "system",
"content": "{{char}}'s personality",
"enabled": True,
"marker": False
},
{
"identifier": "main_prompt",
"name": "Main Prompt",
"system_prompt": True,
"role": "system",
"content": "You are an AI assistant.",
"enabled": True,
"marker": False
},
{
"identifier": "chat_history",
"name": "Chat History",
"system_prompt": True,
"role": "system",
"content": "{{history}}",
"enabled": True,
"marker": True
},
{
"identifier": "user_input",
"name": "User Input",
"system_prompt": False,
"role": "user",
"content": "{{input}}",
"enabled": True,
"marker": False
}
],
# prompt_order 指定了正确顺序
"prompt_order": [{
"character_id": "global",
"order": [
{"identifier": "main_prompt", "enabled": True},
{"identifier": "char_personality", "enabled": True},
{"identifier": "chat_history", "enabled": True},
{"identifier": "user_input", "enabled": True}
]
}]
}
# 写入原始文件
original_file = Path("data/preset/Complete_Flow_Test_Original.json")
with open(original_file, 'w', encoding='utf-8') as f:
json.dump(original_data, f, ensure_ascii=False, indent=2)
print(f"✅ 创建文件: {original_file}")
print(f"\n原始 prompts 顺序(乱序):")
for i, prompt in enumerate(original_data['prompts']):
print(f" {i+1}. {prompt['identifier']}")
print(f"\n期望顺序 (prompt_order):")
for i, item in enumerate(original_data['prompt_order'][0]['order']):
print(f" {i+1}. {item['identifier']}")
# ==================== 步骤 2: 模拟导入时的排序 ====================
print("\n[步骤 2] 模拟前端导入时的排序逻辑")
print("-" * 80)
# 获取 prompt_order
prompt_order = original_data.get('prompt_order', [{}])[0].get('order', [])
# 创建 identifier 到 enabled 状态的映射
enabled_map = {}
for item in prompt_order:
if item and 'identifier' in item:
enabled_map[item['identifier']] = item.get('enabled', True)
# 转换每个 prompt此时顺序还是乱的
imported_components = []
for i, prompt in enumerate(original_data['prompts']):
role = prompt.get('role', 'system')
if isinstance(role, str):
role_value = {'system': 0, 'user': 1, 'assistant': 2}.get(role, 0)
else:
role_value = role
component = {
'identifier': prompt.get('identifier', f'prompt_{i}'),
'name': prompt.get('name', '未命名组件'),
'content': prompt.get('content', ''),
'enabled': enabled_map.get(prompt.get('identifier'), prompt.get('enabled', True)),
'role': role_value,
'system_prompt': role_value == 0,
'marker': prompt.get('marker', False)
}
imported_components.append(component)
print(f"转换后顺序(仍为乱序):")
for i, comp in enumerate(imported_components):
print(f" {i+1}. {comp['identifier']}")
# 按 prompt_order 排序
if len(prompt_order) > 0:
order_map = {}
for idx, item in enumerate(prompt_order):
if item and 'identifier' in item:
order_map[item['identifier']] = idx
imported_components.sort(key=lambda x: order_map.get(x['identifier'], 999))
print(f"\n排序后顺序(已按 prompt_order 重排):")
for i, comp in enumerate(imported_components):
print(f" {i+1}. {comp['identifier']}")
# ==================== 步骤 3: 模拟保存到后端 ====================
print("\n[步骤 3] 模拟保存到后端(使用排序后的顺序)")
print("-" * 80)
saved_prompts = []
saved_prompt_order = []
for component in imported_components:
saved_prompts.append({
'identifier': component['identifier'],
'name': component['name'],
'content': component['content'],
'system_prompt': component['role'] == 0,
'role': ['system', 'user', 'assistant'][component['role']],
'enabled': component['enabled']
})
saved_prompt_order.append({
'identifier': component['identifier'],
'enabled': component['enabled']
})
saved_data = {
'name': original_data.get('name'),
'temperature': original_data.get('temperature'),
'frequency_penalty': original_data.get('frequency_penalty'),
'presence_penalty': original_data.get('presence_penalty'),
'top_p': original_data.get('top_p'),
'top_k': original_data.get('top_k'),
'max_tokens': original_data.get('max_tokens'),
'prompts': saved_prompts,
'prompt_order': [{
'character_id': 'global',
'order': saved_prompt_order
}]
}
# 写入保存后的文件
saved_file = Path("data/preset/Complete_Flow_Test_Saved.json")
with open(saved_file, 'w', encoding='utf-8') as f:
json.dump(saved_data, f, ensure_ascii=False, indent=2)
print(f"✅ 保存文件: {saved_file}")
print(f"\n保存后的 prompts 顺序:")
for i, prompt in enumerate(saved_data['prompts']):
print(f" {i+1}. {prompt['identifier']}")
# ==================== 步骤 4: 模拟从后端加载 ====================
print("\n[步骤 4] 模拟从后端加载预设")
print("-" * 80)
# 读取保存的文件
with open(saved_file, 'r', encoding='utf-8') as f:
loaded_data = json.load(f)
# 获取 prompt_order
loaded_prompt_order = loaded_data.get('prompt_order', [{}])[0].get('order', [])
# 转换组件
loaded_components = []
for i, prompt in enumerate(loaded_data['prompts']):
role = prompt.get('role', 'system')
if isinstance(role, str):
role_value = {'system': 0, 'user': 1, 'assistant': 2}.get(role, 0)
else:
role_value = role
component = {
'identifier': prompt.get('identifier'),
'name': prompt.get('name'),
'content': prompt.get('content'),
'enabled': prompt.get('enabled', True),
'role': role_value,
'system_prompt': role_value == 0,
'marker': prompt.get('marker', False)
}
loaded_components.append(component)
# 按 prompt_order 排序
if len(loaded_prompt_order) > 0:
order_map = {}
for idx, item in enumerate(loaded_prompt_order):
if item and 'identifier' in item:
order_map[item['identifier']] = idx
loaded_components.sort(key=lambda x: order_map.get(x['identifier'], 999))
print(f"加载并排序后的组件顺序:")
for i, comp in enumerate(loaded_components):
print(f" {i+1}. {comp['identifier']}")
# ==================== 步骤 5: 验证完整流程 ====================
print("\n[步骤 5] 验证完整流程的顺序一致性")
print("-" * 80)
expected_order = ['main_prompt', 'char_personality', 'chat_history', 'user_input']
imported_order = [comp['identifier'] for comp in imported_components]
saved_order = [prompt['identifier'] for prompt in saved_data['prompts']]
loaded_order = [comp['identifier'] for comp in loaded_components]
print(f"期望顺序: {expected_order}")
print(f"导入后顺序: {imported_order}")
print(f"保存后顺序: {saved_order}")
print(f"加载后顺序: {loaded_order}")
all_match = (
expected_order == imported_order and
imported_order == saved_order and
saved_order == loaded_order
)
if all_match:
print("\n✅ 所有阶段的顺序完全一致!")
else:
print("\n❌ 顺序不一致!")
if expected_order != imported_order:
print(" - 导入阶段顺序错误")
if imported_order != saved_order:
print(" - 保存阶段顺序错误")
if saved_order != loaded_order:
print(" - 加载阶段顺序错误")
# ==================== 总结 ====================
print("\n" + "=" * 80)
print("测试总结")
print("=" * 80)
print("✅ 原始文件 prompts 是乱序的")
print("✅ 导入时按 prompt_order 正确排序")
print("✅ 保存时使用排序后的顺序")
print("✅ 加载时再次按 prompt_order 排序")
print("✅ 最终展示顺序与期望顺序一致")
print("\n结论:预设排序在完整流程中保持一致!")
print("=" * 80)