- src: phase_z2 composition/mapper/pipeline/placement_planner/retry, ai_fallback(prompts/schema/validate), mdx_text_atoms 신규 - Front: PipelineTracePanel 신규, FramePanel/SlideCanvas/Home/designAgentApi 등 갱신 + 테스트 4종 추가 - templates/phase_z2: catalog(component_expansion_registry, node_slot_mapping 신규), frames, families, slide_base 갱신 - tests/matching: phase2~26 매칭 실험 스크립트·리포트·온톨로지 전체 (미커밋 진행분) - tests: b4_v4 evidence, task5~28.5 시리즈, regression(imp95 baseline) 등 신규 테스트 대량 추가 - docs/reference: MDX 구조 인벤토리, MDX→Frame 구조 계약 문서 - scripts: mdx 계약/parity/coverage/viewport 체크, gitea comment, run sync 유틸 - .gitignore: tmp*.json, chromedriver, .orchestrator, *.pkl, Front_test* 등 임시/스냅샷 제외 미완성 작업의 보존용 스냅샷 커밋 (2026-07-02) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
106 lines
4.0 KiB
Python
106 lines
4.0 KiB
Python
"""IMP-33 u3 — AI fallback prompt builder (fallback path only).
|
|
|
|
System+user prompt for the Anthropic client (u4). MDX is READ-ONLY
|
|
(`feedback_ai_isolation_contract`); output is constrained to the u2
|
|
schema; frame_id swap is forbidden (V4 rank-1 protected,
|
|
`feedback_phase_z_spacing_direction`). Inputs per Stage 2 plan: V4
|
|
result (route=ai_adaptation_required, cardinality), frame_contract,
|
|
frame_visual HTML, figma_to_html_agent partial JSON, Internal Region,
|
|
MDX text.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from typing import Any
|
|
|
|
from src.phase_z2_ai_fallback.schema import FORBIDDEN_KINDS, ProposalKind
|
|
|
|
V4_ROUTE_AI_ADAPTATION = "ai_adaptation_required"
|
|
|
|
_ALLOWED_KINDS = ", ".join(sorted(k.value for k in ProposalKind))
|
|
_FORBIDDEN_KINDS = ", ".join(sorted(FORBIDDEN_KINDS))
|
|
|
|
SYSTEM_PROMPT = (
|
|
"You are an IMP-33 AI fallback adapter for Phase Z slide composition.\n"
|
|
"STRICT RULES:\n"
|
|
" 1. MDX text in the user payload is READ-ONLY. Do NOT rewrite, "
|
|
"compress, or paraphrase MDX.\n"
|
|
" 2. Output MUST be a single JSON object conforming to AiFallbackProposal.\n"
|
|
f" 3. proposal_kind MUST be one of: {_ALLOWED_KINDS}.\n"
|
|
f" 4. Do NOT propose any of: {_FORBIDDEN_KINDS}.\n"
|
|
" 5. Do NOT change frame_id — V4 rank-1 frame is locked.\n"
|
|
" 6. Preferred Task-12 output is proposal_kind='design_adaptation_plan': "
|
|
"plan frame/layout/repeat changes only; do NOT output final text slots.\n"
|
|
" 7. Do NOT create titles, labels, summaries, body text, or slot content. "
|
|
"The code layer will place MDX verbatim text.\n"
|
|
" 8. Keep declared frame slots (text/table/image/details) accounted for.\n"
|
|
" 9. Respect Internal Region containment; place content units within "
|
|
"the declared region only."
|
|
)
|
|
|
|
|
|
def build_ai_fallback_prompt(
|
|
*,
|
|
v4_result: dict[str, Any],
|
|
frame_contract: dict[str, Any],
|
|
frame_visual_html: str,
|
|
figma_partial_json: dict[str, Any],
|
|
internal_region: dict[str, Any],
|
|
mdx_text: str,
|
|
) -> dict[str, str]:
|
|
"""Build system+user prompt strings for the fallback AI adapter.
|
|
|
|
Raises:
|
|
ValueError: when ``v4_result.route`` is not
|
|
``ai_adaptation_required`` — the fallback prompt MUST NOT be
|
|
built outside this route (normal-path AI call count must
|
|
remain 0; PZ-1).
|
|
"""
|
|
route = v4_result.get("route") or v4_result.get("imp05_route_hint")
|
|
if route != V4_ROUTE_AI_ADAPTATION:
|
|
raise ValueError(
|
|
f"build_ai_fallback_prompt: v4_result.route={route!r} is not "
|
|
f"{V4_ROUTE_AI_ADAPTATION!r}; fallback prompt MUST NOT be built "
|
|
"outside the AI adaptation route."
|
|
)
|
|
user_payload = {
|
|
"v4": {
|
|
"route": route,
|
|
"cardinality": v4_result.get("cardinality")
|
|
or v4_result.get("cardinality_signature"),
|
|
"label": v4_result.get("label"),
|
|
"frame_id": v4_result.get("frame_id"),
|
|
"rank": v4_result.get("rank"),
|
|
},
|
|
"frame_contract": frame_contract,
|
|
"frame_visual_html": frame_visual_html,
|
|
"figma_partial_json": figma_partial_json,
|
|
"internal_region": internal_region,
|
|
"mdx_text_READ_ONLY": mdx_text,
|
|
"task12_output_contract": {
|
|
"preferred_proposal_kind": ProposalKind.DESIGN_ADAPTATION_PLAN.value,
|
|
"allowed_operation_examples": [
|
|
"increase_repeat_count",
|
|
"split_group_across_repeat_blocks",
|
|
"rebalance_zone_ratio",
|
|
"compact_spacing",
|
|
"use_repeatable_frame",
|
|
],
|
|
"forbidden_content_fields": [
|
|
"text",
|
|
"title",
|
|
"label",
|
|
"body",
|
|
"slots",
|
|
"mdx_text",
|
|
"summary",
|
|
"raw_html",
|
|
"raw_css",
|
|
],
|
|
},
|
|
}
|
|
return {
|
|
"system": SYSTEM_PROMPT,
|
|
"user": json.dumps(user_payload, ensure_ascii=False),
|
|
}
|