"""T6.2 创作工具箱注册表(`TOOLBOX`)单测。 校验:15 条齐全(legacy 3 + 新 8 + 竞品快赢 4);legacy 携 legacy_route 且 spec=None; 新工具携 spec + output_schema(与 spec.output_schema 一致);ingest 工具的 table 在白名单内; `get_tool` 解析。 """ from __future__ import annotations from ww_skills import TOOLBOX, get_tool _LEGACY_KEYS = {"worldbuilding", "character", "outline"} _NEW_KEYS = { "brainstorm", "book-title", "blurb", "name", "golden-finger", "glossary", "opening", "fine-outline", # 竞品快赢(Scope B):续写/扩写/降AI率 preview-only;拆书 F1 可落库 rules。 "continue", "expand", "de-ai", "teardown", } _INGEST_KEYS = {"golden-finger", "glossary", "fine-outline", "teardown"} def test_toolbox_has_all_tools() -> None: # Arrange / Act keys = set(TOOLBOX.keys()) # Assert:legacy 3 + 新 8 + 竞品快赢 4 = 15。 assert keys == _LEGACY_KEYS | _NEW_KEYS assert len(TOOLBOX) == 15 def test_legacy_tools_have_route_and_no_spec() -> None: for key in _LEGACY_KEYS: tool = TOOLBOX[key] assert tool.spec is None, key assert tool.output_schema is None, key assert tool.legacy_route is not None, key assert "{id}" in tool.legacy_route, key def test_new_tools_carry_spec_and_matching_schema() -> None: for key in _NEW_KEYS: tool = TOOLBOX[key] assert tool.spec is not None, key assert tool.output_schema is not None, key # 描述符的 output_schema 必须与其 spec 的 output_schema 一致(同一真类)。 assert tool.output_schema is tool.spec.output_schema, key assert tool.legacy_route is None, key # 每个新工具的 key 与 spec.name 一致(路由稳定)。 assert tool.key == tool.spec.name, key def test_ingest_tools_declare_known_table() -> None: for key, tool in TOOLBOX.items(): if key in _INGEST_KEYS: assert tool.ingest is not None, key else: assert tool.ingest is None, key assert TOOLBOX["golden-finger"].ingest is not None assert TOOLBOX["golden-finger"].ingest.table == "world_entities" assert TOOLBOX["glossary"].ingest is not None assert TOOLBOX["glossary"].ingest.table == "world_entities" assert TOOLBOX["fine-outline"].ingest is not None assert TOOLBOX["fine-outline"].ingest.table == "outline" # F1:拆书结论落库为项目 rules。 assert TOOLBOX["teardown"].ingest is not None assert TOOLBOX["teardown"].ingest.table == "rules" def test_chapter_tools_have_chapter_no_field() -> None: for key in ("opening", "fine-outline"): field_names = {f.name for f in TOOLBOX[key].input_fields} assert "chapter_no" in field_names, key def test_every_tool_has_brief_field_where_applicable() -> None: # 新工具均带 brief textarea(声明驱动表单的统一入口)。 for key in _NEW_KEYS: field_names = {f.name for f in TOOLBOX[key].input_fields} assert "brief" in field_names, key def test_get_tool_resolves_known_and_unknown() -> None: assert get_tool("brainstorm") is TOOLBOX["brainstorm"] assert get_tool("worldbuilding") is TOOLBOX["worldbuilding"] assert get_tool("does-not-exist") is None