feat: T6.1 创作工具箱通用生成器框架地基 — 脑洞生成器 + run_generator
- schemas: Idea/IdeaListResult(脑洞生成器结构化产出,纯预览不入库) - specs: brainstorm_spec(light 档,reads=[projects] writes=[]) - orchestrator: build_brief_context(brief_only 策略)+ 通用 run_generator (据 spec.output_schema 校验 parsed,不绑定具体类型,任一声明式生成器共用) - 新增 13 测;两包 ruff/format/mypy 干净、252 passed 无回归 P1 第一波(@llm):证实「加生成器=加一份声明」。@backend T6.2/T6.3 待续。
This commit is contained in:
@@ -21,11 +21,13 @@ from .collect import (
|
||||
extract_style,
|
||||
)
|
||||
from .generation_node import (
|
||||
build_brief_context,
|
||||
build_character_gen_context,
|
||||
build_precheck_context,
|
||||
build_worldbuilder_context,
|
||||
precheck_generated_cards,
|
||||
run_character_gen,
|
||||
run_generator,
|
||||
run_worldbuilder,
|
||||
)
|
||||
from .graph import (
|
||||
@@ -102,6 +104,7 @@ __all__ = [
|
||||
"GatewayStream",
|
||||
"ReviewRecorder",
|
||||
"SseEvent",
|
||||
"build_brief_context",
|
||||
"build_character_gen_context",
|
||||
"build_outline_request",
|
||||
"build_precheck_context",
|
||||
@@ -128,6 +131,7 @@ __all__ = [
|
||||
"pace_event",
|
||||
"precheck_generated_cards",
|
||||
"run_character_gen",
|
||||
"run_generator",
|
||||
"run_outline",
|
||||
"run_review",
|
||||
"run_style_extraction",
|
||||
|
||||
@@ -28,6 +28,7 @@ from collections.abc import Sequence
|
||||
from typing import Protocol
|
||||
|
||||
import structlog
|
||||
from pydantic import BaseModel
|
||||
from ww_agents import (
|
||||
AgentSpec,
|
||||
CharacterCard,
|
||||
@@ -73,6 +74,49 @@ def _build_request(
|
||||
)
|
||||
|
||||
|
||||
# ---- 通用生成器执行器(T6 · 创作工具箱通用框架)----
|
||||
|
||||
|
||||
def build_brief_context(*, brief: str, project_context: str) -> str:
|
||||
"""通用「brief_only」上下文:作品设定 + 作者一句话需求(确定性,无时间戳)。
|
||||
|
||||
覆盖最简生成器(脑洞/书名…):仅需作品设定 + 一句话方向。需求为空时给降级占位,
|
||||
交由 system_prompt 的「按题材自由发散」纪律处理。
|
||||
"""
|
||||
brief_block = brief.strip() or "(作者未填具体方向,按题材自由发散)"
|
||||
return f"## 作品设定\n{project_context or '(暂无设定)'}\n\n## 创作需求\n{brief_block}"
|
||||
|
||||
|
||||
async def run_generator(
|
||||
spec: AgentSpec,
|
||||
*,
|
||||
context: str,
|
||||
gateway: GatewayRun,
|
||||
user_id: uuid.UUID,
|
||||
project_id: uuid.UUID,
|
||||
) -> BaseModel:
|
||||
"""通用生成器执行器(T6):构请求 → `gateway.run` → 按 `spec.output_schema` 校验 parsed。
|
||||
|
||||
任一声明式生成器共用此路径(不绑定具体产物类型,据 spec 的 output_schema 校验)。
|
||||
**只读、不写库**(纯预览,不变量 #3);独立生成——网关失败直接上抛(端点处理),不静默吞。
|
||||
"""
|
||||
expected = spec.output_schema
|
||||
if expected is None:
|
||||
raise ValueError(f"generator spec {spec.name!r} has no output_schema")
|
||||
req = _build_request(spec, context=context, user_id=user_id, project_id=project_id)
|
||||
resp = await gateway.run(req)
|
||||
parsed = resp.parsed
|
||||
if not isinstance(parsed, expected):
|
||||
log.error(
|
||||
"generator_node_missing_parsed",
|
||||
spec=spec.name,
|
||||
project_id=str(project_id),
|
||||
parsed_type=type(parsed).__name__,
|
||||
)
|
||||
raise ValueError(f"gateway returned no parsed {expected.__name__} for {spec.name} request")
|
||||
return parsed
|
||||
|
||||
|
||||
# ---- worldbuilder ----
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user