67 lines
2.7 KiB
Python
67 lines
2.7 KiB
Python
"""角色卡字段映射:ST CharacterCard → 魂镜 Character + 世谱条目。
|
||
|
||
纯逻辑,无 IO。``system_prompt`` / ``post_history_instructions`` 导入时存入 profile,
|
||
运行时作道体增补层注入(绝不覆盖恒定层,见融合设计 §6)。
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from app.modules.imports.card_parser import CharacterCard
|
||
|
||
|
||
def card_to_profile(card: CharacterCard) -> dict:
|
||
"""ST 卡 → Character profile JSON(自由字段,保留酒馆全部信息)。"""
|
||
return {
|
||
"background": card.description,
|
||
"scenario": card.scenario,
|
||
"first_mes": card.first_mes,
|
||
"mes_example": card.mes_example,
|
||
"alternate_greetings": card.alternate_greetings,
|
||
"tags": card.tags,
|
||
# 运行时作道体增补层注入(§6 安全边界),导入先保存
|
||
"system_prompt": card.system_prompt,
|
||
"post_history_instructions": card.post_history_instructions,
|
||
"source_meta": {
|
||
"creator": card.creator,
|
||
"character_version": card.character_version,
|
||
"creator_notes": card.creator_notes,
|
||
"spec_version": card.spec_version,
|
||
},
|
||
"st_extensions": card.extensions, # 保留未知键(酒馆规范:不得删除)
|
||
}
|
||
|
||
|
||
def card_to_daoti(card: CharacterCard) -> dict:
|
||
"""ST 卡 → 道体字段。
|
||
|
||
``personality`` 作 ``personality_summary`` 初始值(已拍板);``mission`` /
|
||
``safety_guidelines`` 酒馆卡没有,导入不设,留用户 / 演化填。
|
||
"""
|
||
return {"personality_summary": card.personality or None}
|
||
|
||
|
||
def character_book_to_entries(book: dict | None) -> list[dict]:
|
||
"""ST character_book entries → 世谱条目构造参数。"""
|
||
if not book:
|
||
return []
|
||
result = []
|
||
for e in book.get("entries") or []:
|
||
enabled_raw = e.get("enabled", True)
|
||
result.append(
|
||
{
|
||
"keys": list(e.get("keys") or []),
|
||
"content": e.get("content") or "",
|
||
"secondary_keys": list(e.get("secondary_keys") or []),
|
||
"constant": bool(e.get("constant", False)),
|
||
"selective": bool(e.get("selective", False)),
|
||
"enabled": True if enabled_raw is None else bool(enabled_raw),
|
||
"case_sensitive": bool(e.get("case_sensitive", False)),
|
||
"use_regex": bool(e.get("use_regex", False)),
|
||
"position": e.get("position") or "after_char",
|
||
"insertion_order": int(e.get("insertion_order") or 100),
|
||
"priority": int(e.get("priority") or 10),
|
||
"comment": e.get("comment") or e.get("name") or "",
|
||
}
|
||
)
|
||
return result
|