feat(web): 角色群像按定位配比生成(role_mix 缩减版)

- 契约: CharacterGenerateRequest 加 role_mix{定位:数量},model_validator 归一
  count=各值之和(每项≥1、总和≤12),缺省退回单一 role+count
- @llm: build_character_gen_context/run_character_gen 加 role_mix 参并注入配比块
  (确定性、无时间戳,守 assemble 纯函数);router 穿参
- character-gen.md 加"按配比严格分配 role"纪律 + regen prompt_hashes 金标准
- 前端: sanitizeRoleMix/roleMixTotal + buildCharacterGenerateRequest 第4参 +
  useCharacterGen 穿参 + RoleMixEditor + CharacterGenerator 单一/配比双模
This commit is contained in:
Yaojia Wang
2026-07-06 17:24:16 +02:00
parent 72b3c81146
commit 7babb4854b
16 changed files with 428 additions and 50 deletions

View File

@@ -21,6 +21,8 @@ export interface CharacterGenInput {
brief: string;
count: number;
role?: string | null;
// 群像按定位配比(⑦);在场时后端把 count 定为各值之和,忽略 count/role。
roleMix?: Readonly<Record<string, number>> | null;
}
export interface UseCharacterGen {
@@ -50,7 +52,7 @@ export function useCharacterGen(): UseCharacterGen {
const toast = useToast();
const generate = useCallback<UseCharacterGen["generate"]>(
async ({ projectId, brief, count, role }) => {
async ({ projectId, brief, count, role, roleMix }) => {
setGenStatus("generating");
setCards([]);
setConflicts(null);
@@ -60,7 +62,7 @@ export function useCharacterGen(): UseCharacterGen {
"/projects/{project_id}/characters/generate",
{
params: { path: { project_id: projectId } },
body: buildCharacterGenerateRequest(brief, count, role),
body: buildCharacterGenerateRequest(brief, count, role, roleMix),
},
);
if (error || !data) {