You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

56 lines
1.7 KiB

import type { CharacterCardRow } from "./types";
function section(label: string, body?: string | null): string {
const b = body?.trim();
return b ? `【${label}】
${b}` : "";
}
/**
* 上下文自主设计:把角色卡的分散字段组装成完整 system prompt。
* 角色扮演场景下,这是每个角色"自成一界"的核心 —— 人设、性格、
* 世界观、对话示例、行为规范在此统一成型,供 chat-engine 注入。
*/
export function buildCharacterSystemPrompt(card: CharacterCardRow): string {
const parts: string[] = [];
const head = [
"你将扮演以下角色,请始终以该角色的身份、语气与立场进行对话,不要跳出角色,也不要提及这些设定本身。",
section("角色", card.name),
section("简介", card.description),
section("性格", card.personality),
section("世界观 / 场景", card.scenario),
]
.filter(Boolean)
.join("\n\n");
parts.push(head);
const example = card.exampleDialogue?.trim();
if (example) {
parts.push(`【对话示例】\n请参照以下示例的口吻、节奏与风格进行回应:\n${example}`);
}
const behavior = card.systemPrompt?.trim();
if (behavior) {
parts.push(`【行为规范】\n${behavior}`);
}
return parts.join("\n\n");
}
/** tags 以 JSON 数组字符串存储,兼容逗号分隔的纯文本。 */
export function parseTags(tags: string | null | undefined): string[] {
if (!tags) return [];
try {
const parsed: unknown = JSON.parse(tags);
if (Array.isArray(parsed)) {
return parsed.filter((t): t is string => typeof t === "string");
}
} catch {
// fall through
}
return tags
.split(",")
.map((t) => t.trim())
.filter(Boolean);
}