1
Some checks failed
CI / verify (push) Has been cancelled

This commit is contained in:
2026-04-20 15:45:14 +08:00
parent 8a7bd90458
commit 1c72066bab
73 changed files with 7814 additions and 1018 deletions

View File

@@ -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 {

View File

@@ -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(