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:
51
apps/api/tests/test_generation_schema.py
Normal file
51
apps/api/tests/test_generation_schema.py
Normal file
@@ -0,0 +1,51 @@
|
||||
"""CharacterGenerateRequest.role_mix 校验单测(⑦ 群像按定位配比)。
|
||||
|
||||
纯 pydantic 校验,无 DB/网关。契约:role_mix 在场时 count 取各值之和,
|
||||
每项数量须 ≥ 1、总和须 ≤ MAX_GENERATE_COUNT。
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
from pydantic import ValidationError
|
||||
from ww_api.schemas.generation import MAX_GENERATE_COUNT, CharacterGenerateRequest
|
||||
|
||||
|
||||
def test_role_mix_absent_keeps_explicit_count() -> None:
|
||||
req = CharacterGenerateRequest(brief="剑修", count=3)
|
||||
assert req.role_mix is None
|
||||
assert req.count == 3
|
||||
|
||||
|
||||
def test_role_mix_sets_count_to_sum() -> None:
|
||||
req = CharacterGenerateRequest(brief="群像", role_mix={"主角": 1, "对手": 2, "配角": 3})
|
||||
assert req.count == 6
|
||||
|
||||
|
||||
def test_role_mix_overrides_provided_count() -> None:
|
||||
# role_mix 在场时 count 取各值之和,忽略客户端显式传入的 count
|
||||
req = CharacterGenerateRequest(brief="群像", count=1, role_mix={"主角": 2, "对手": 2})
|
||||
assert req.count == 4
|
||||
|
||||
|
||||
def test_role_mix_total_at_max_allowed() -> None:
|
||||
req = CharacterGenerateRequest(brief="群像", role_mix={"主角": MAX_GENERATE_COUNT})
|
||||
assert req.count == MAX_GENERATE_COUNT
|
||||
|
||||
|
||||
def test_role_mix_sum_over_max_rejected() -> None:
|
||||
with pytest.raises(ValidationError):
|
||||
# 6 + 7 = 13 > 12
|
||||
CharacterGenerateRequest(brief="群像", role_mix={"主角": 6, "对手": 7})
|
||||
|
||||
|
||||
def test_role_mix_empty_dict_rejected() -> None:
|
||||
with pytest.raises(ValidationError):
|
||||
CharacterGenerateRequest(brief="群像", role_mix={})
|
||||
|
||||
|
||||
def test_role_mix_nonpositive_value_rejected() -> None:
|
||||
with pytest.raises(ValidationError):
|
||||
CharacterGenerateRequest(brief="群像", role_mix={"主角": 0})
|
||||
with pytest.raises(ValidationError):
|
||||
CharacterGenerateRequest(brief="群像", role_mix={"主角": -1})
|
||||
Reference in New Issue
Block a user