@@ -1,3 +1,21 @@
|
||||
/**
|
||||
* 自定义世界角色资产工坊的“默认描述文本种子”主源。
|
||||
*
|
||||
* 这份脚本只负责一件事:
|
||||
* - 从当前角色对象已有字段里挑出最合适的文本,
|
||||
* 作为资产工坊输入框的初始默认值
|
||||
*
|
||||
* 它不负责:
|
||||
* - 直接调用 LLM 重新编译默认描述
|
||||
* - 直接生成图像模型 prompt
|
||||
* - 直接生成动作模型 prompt
|
||||
*
|
||||
* 当前真实调用状态:
|
||||
* - CustomWorldRoleAssetStudioModal 的初始默认值主链,来自本文件
|
||||
* - 也就是说,资产工坊页面打开时看到的“形象描述 / 动作描述”
|
||||
* 当前优先取这里的本地字段映射,而不是后端
|
||||
* /api/assets/character-prompts/generate 接口
|
||||
*/
|
||||
export type PromptDefaultRole = {
|
||||
name: string;
|
||||
title: string;
|
||||
@@ -19,10 +37,18 @@ export type CustomWorldRolePromptBundle = {
|
||||
scenePromptText: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* 对角色字段做轻量清洗,确保作为输入框默认值时不会带多余空白。
|
||||
*/
|
||||
function cleanSeedText(value: string | undefined, maxLength: number) {
|
||||
return (value ?? '').replace(/\s+/gu, ' ').trim().slice(0, maxLength);
|
||||
}
|
||||
|
||||
/**
|
||||
* 按优先级选择第一条可用文本。
|
||||
*
|
||||
* 这里是非常轻量的本地回退逻辑,不做任何“重新创作”或 prompt 扩写。
|
||||
*/
|
||||
function pickFirstDescription(
|
||||
values: Array<string | undefined>,
|
||||
maxLength: number,
|
||||
@@ -37,6 +63,18 @@ function pickFirstDescription(
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 资产工坊默认文本映射规则。
|
||||
*
|
||||
* 规则分层:
|
||||
* - visualPromptText: 优先使用角色 visualDescription,其次 description
|
||||
* - animationPromptText: 优先使用 actionDescription,其次 combatStyle
|
||||
* - scenePromptText: 优先使用 sceneVisualDescription,其次 backstory
|
||||
*
|
||||
* 注意:
|
||||
* - 返回值只是“输入框默认文案”
|
||||
* - 正式图像 / 动作模型 prompt 还会在后端继续编译
|
||||
*/
|
||||
export function buildDefaultRolePromptBundle(
|
||||
role: PromptDefaultRole,
|
||||
): CustomWorldRolePromptBundle {
|
||||
|
||||
@@ -30,6 +30,11 @@ import {
|
||||
getFunctionById,
|
||||
getFunctionPromptDescription,
|
||||
} from '../data/stateFunctions';
|
||||
import type { StoryGenerationContext } from '../services/aiTypes';
|
||||
import { buildCustomWorldReferenceText } from '../services/customWorld';
|
||||
import { sanitizePromptNarrativeText } from '../services/narrativeLanguage';
|
||||
import { describeGoalStackForPrompt } from '../services/storyEngine/goalDirector';
|
||||
import { buildStoryPromptHistory } from '../services/storyHistory';
|
||||
import {
|
||||
Character,
|
||||
CharacterGender,
|
||||
@@ -40,11 +45,6 @@ import {
|
||||
StoryOption,
|
||||
WorldType,
|
||||
} from '../types';
|
||||
import type { StoryGenerationContext } from '../services/aiTypes';
|
||||
import { buildCustomWorldReferenceText } from '../services/customWorld';
|
||||
import { sanitizePromptNarrativeText } from '../services/narrativeLanguage';
|
||||
import { describeGoalStackForPrompt } from '../services/storyEngine/goalDirector';
|
||||
import { buildStoryPromptHistory } from '../services/storyHistory';
|
||||
|
||||
export const SYSTEM_PROMPT = `你是角色扮演 RPG 的剧情推进者,只能返回 JSON 对象,不能输出解释、markdown 或代码块。
|
||||
输出格式必须严格符合:
|
||||
@@ -1817,8 +1817,11 @@ export function buildStrictNpcChatDialoguePrompt(
|
||||
'不要让对方在聊天里推进交易、招募、切磋、战斗、送礼、求助、离开、继续前进、切换场景等其他 function。',
|
||||
'不要替玩家做选择,不要用建议句、命令句或诱导句把聊天写成别的行为入口。',
|
||||
'低揭示阶段时,宁可留钩子、先谈眼前局势,也不要把完整来历和目标一次说完。',
|
||||
context.isFirstMeaningfulContact
|
||||
? '如果这是第一次真正接触,对方第一次开口必须先用一句自然招呼或开场判断起手,不能写成“某人看着你,像是在等你把话接下去”这类第三人称占位旁白。'
|
||||
: null,
|
||||
'如果当前情景是初见或刚打完一轮冲突,优先写短句、观察句和试探句,不要写成正式自我介绍。',
|
||||
].join('\n\n');
|
||||
].filter(Boolean).join('\n\n');
|
||||
}
|
||||
|
||||
export function buildNpcRecruitDialoguePrompt(
|
||||
|
||||
Reference in New Issue
Block a user