Files
writer-work-flow/packages/agents/tests/test_toolbox_schemas.py
Yaojia Wang f43ccd293f feat(toolbox): T6 创作工具箱通用生成器框架 — 8 新生成器 + 声明驱动落地页 + P2 收尾
通用执行路径驱动全部生成器("加生成器=加一份声明"):
- @llm: ww_agents +7 输出 schema + 7 spec(book-title/blurb/name/golden-finger/
  glossary/opening/fine-outline,只声明 tier)+ build_outline_chapter_context
- @backend: ww_skills GeneratorTool 描述符 + TOOLBOX(11) + get_tool;3 通用端点
  GET /skills/toolbox · POST .../skills/{tool_key}/generate(预览不写库,仅记账) ·
  POST .../ingest(复用 continuity 409 + partition_writes 白名单);纯 context 派发
- @frontend: 工具箱落地页 RSC + 声明驱动 GeneratorRunner + lib/toolbox 纯函数
  + LeftNav「工具箱」+ ⌘K nav-toolbox/action-gen-*;legacy 3 跳现页
- @qa: tests/test_t6_toolbox_e2e.py 5 用例真 pg + mock 网关零 token,无端点 bug
- P2 收尾: 限流→decisions.md 记延后(单用户原型);noopener/Committable 早已修

守不变量 #2(只声明 tier)/#3(预览不写库,入库经验收 gate)/#9(缓存前缀)。无 DB 迁移。
门禁绿: 后端 ruff/format/mypy 195/alembic 无漂移/pytest 583;前端 lint/tsc/vitest 279/build。
spec 回写 PRODUCT_SPEC §7 + ARCHITECTURE §7.2 端点表。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 20:37:55 +02:00

88 lines
2.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""T6 创作工具箱 · 7 个生成器输出 schema 的解析/默认值契约测试。
校验 list 字段 default_factory=list默认空、可解析 mock 产出)。不联网、无 DB。
"""
from __future__ import annotations
from ww_agents import (
BlurbResult,
DetailedOutlineResult,
GlossaryResult,
GoldenFingerResult,
NameListResult,
OpeningResult,
TitleListResult,
)
def test_title_list_result_parses_and_defaults_empty() -> None:
assert TitleListResult().titles == []
parsed = TitleListResult.model_validate(
{"titles": [{"title": "吞噬星空", "rationale": "升级流爽点抓人"}]}
)
assert parsed.titles[0].title == "吞噬星空"
def test_blurb_result_parses_and_defaults_empty() -> None:
assert BlurbResult().variants == []
parsed = BlurbResult.model_validate(
{"variants": [{"text": "废柴逆袭...", "angle": "金手指反差"}]}
)
assert parsed.variants[0].angle == "金手指反差"
def test_name_list_result_parses_and_note_optional() -> None:
assert NameListResult().names == []
parsed = NameListResult.model_validate({"names": [{"name": "玄阴宗", "kind": "势力"}]})
assert parsed.names[0].note is None
def test_golden_finger_result_parses_and_defaults_empty() -> None:
assert GoldenFingerResult().systems == []
parsed = GoldenFingerResult.model_validate(
{
"systems": [
{
"name": "吞噬瞳",
"mechanism": "吞噬血脉获能",
"growth": "逐级进阶",
"limits": "吞噬反噬记忆",
}
]
}
)
assert parsed.systems[0].limits == "吞噬反噬记忆"
def test_glossary_result_parses_and_rules_default_empty() -> None:
assert GlossaryResult().terms == []
parsed = GlossaryResult.model_validate(
{"terms": [{"name": "炼气期", "type": "境界", "definition": "修真初阶"}]}
)
assert parsed.terms[0].rules == []
def test_opening_result_parses_and_defaults_empty() -> None:
assert OpeningResult().variants == []
parsed = OpeningResult.model_validate({"variants": [{"text": "雷光劈下..."}]})
assert parsed.variants[0].text == "雷光劈下..."
def test_detailed_outline_result_parses_and_defaults_empty() -> None:
assert DetailedOutlineResult().scenes == []
parsed = DetailedOutlineResult.model_validate(
{
"scenes": [
{
"idx": 0,
"beat": "主角觉醒",
"purpose": "立金手指",
"conflict": "被族人欺压",
"hook": "神秘老者出现",
}
]
}
)
assert parsed.scenes[0].idx == 0