[이 모듈이 하는 일] AI 영상 장면(ai-video)으로 만들어진 영상이 설계도의 움직임 프롬프트와 조건에 맞는지 멀티모달 평가(review_video)로 확인한다. 기준 점수에 못 미치면 평가가 제안한 프롬프트로 한 번 다시 만들어 다시 평가하고, 그래도 안 되면 영상 단계로 되돌려 보낸다(route "retry"). [입력] 이전 단계 JSON(vidia.doc@1). - blueprint.video: {aspectRatio} - blueprint.models.video, blueprint.scenes[]: {id, purpose, media{type, video}, keyframes[{id, role, imagePrompt}], videoPrompt} - blueprint.elements[]: {id, name, identityRules[]} - timeline.scenes: 장면 길이 - assets: "video:<장면>"(AI 영상 원본), "clip:<장면>"(최종 클립), "kf:<장면>:<키프레임>" - reviews.videos: 이전 평가 기록(재방문일 때) - input.video_threshold: 통과 점수(0~10). 없으면 7. - input.video_max_attempts: 장면당 영상 최대 시도 수(원본 포함). 없으면 2. - input.video_provider / input.video_tier: 회원이 고른 영상 모델(있을 때) [할 일] 1. 평가할 목록: media.type 이 ai-video 인 장면 가운데 assets["video:<장면id>"] 가 있는 장면. reviews.videos 에 같은 scene·같은 asset_id 로 pass 가 true 인 기록이 있으면 건너뛴다. 2. 장면마다 평가 기준(criteria)을 한국어로 400자 안팎으로 만든다: - "시작 상태: ", "일어나야 할 변화: ", "끝 상태: " - "이 장면의 뜻: " - 등장 요소가 있으면 "동일성: <요소 name> — " - 공통: "카메라만 움직이고 대상이 그대로이면 불합격", "물리 방향이 맞아야 함(물은 아래로, 깨진 것은 다시 붙지 않음)", "화면 글자·자막·로고 없음", "사람 말소리·음악 없음", "형태 녹아내림·갑자기 나타나는 물체 없음" 3. review_video(asset_id = assets["video:<장면id>"], criteria) 를 부른다. score(0~10)·pass·issues·suggested_prompt 를 읽는다. 기준 점수는 input.video_threshold(없으면 7)이고 도구의 pass 보다 우선한다. 4. 기준 미달이면 이 방문에서 한 번만 다시 만든다. - 이 장면의 재생성 횟수(reviews.videos 에서 같은 scene 의 regenerated 가 true 인 기록 수)가 이미 1 이상이면 다시 만들지 않는다(영상은 비싸다). - 새 프롬프트 = suggested_prompt(영어로), 없으면 원래 videoPrompt 에 issues 를 고치는 문장을 더한다. 끝에 "No text, no subtitles, no logos, no voice, no music." 를 유지한다. - video_generate 를 영상 단계와 같은 설정으로 부른다: provider·version·tier·resolution·mode(models.video 위에 scene.media.video, 그 위에 input 값), duration_sec(장면 길이를 올림한 정수, 최소 3), aspect_ratio, image_asset_id(start 키프레임), last_image_asset_id(end 키프레임이 있을 때), audio(models.video.audio 가 true 일 때만). - 새 영상을 review_video 로 다시 평가한다. 점수가 원래보다 높거나 같으면 assets["video:<장면id>"] 를 새 asset 으로 바꾸고, make_clip(asset_id=새 영상, duration_sec=장면 길이) 결과로 assets["clip:<장면id>"] 도 바꾼다. - promptOverrides["clip:<장면id>"] = 새 프롬프트. 5. 기록: 평가마다 reviews.videos 에 {"scene": 장면id, "key": "clip:<장면id>", "asset_id": 평가한 영상, "score": 점수, "pass": 통과 여부, "issues": 최대 5개, "regenerated": 재생성 영상이면 true} 를 더한다. 6. 판정: - 시도 횟수 = reviews.videos 에서 그 장면으로 평가한 서로 다른 asset_id 수. 최대 시도 = input.video_max_attempts(없으면 2, 영상은 비싸므로 기본값에서는 되돌려 보내지 않는다). - 다시 만든 뒤에도 기준 미달이고 시도 횟수가 최대 시도보다 적은 장면은 retry.videos 에 "clip:<장면id>" 를 넣는다(영상 단계가 promptOverrides 의 프롬프트로 다시 만든다). 하나라도 있으면 route "retry", 없으면 "pass". - 한도에 걸려 끝내 미달인 장면은 점수가 높은 영상을 남기고 reviewWarnings 에 기록한다. 7. 도구 오류로 평가하지 못한 장면은 통과로 간주하고 reviewWarnings 에 남긴다. [출력] 다음 최상위 필드만 담은 JSON 객체 하나(적지 않은 최상위 필드는 입력값이 그대로 이어지므로 다시 적지 않는다. 바꾸는 필드는 값 전체를 적는다.) - assets: 더 나은 영상으로 바뀐 "video:…"·"clip:…" 키 - reviews: {"images": 기존 그대로, "videos": 기존 기록 + 이번 기록} - retry: {"videos": 다시 만들 키 목록, …기존 retry 의 다른 키는 그대로} - promptOverrides, reviewWarnings(기존 뒤에 더함) - route: "retry" 또는 "pass" - reviewSummary: {"reviewed": 평가 수, "passed": 통과 수, "regenerated": 재생성 수, "retry": retry.videos 개수} [주의] - video_generate 는 초당 비용이 큰 도구다. 이 단계에서 직접 다시 만드는 것은 전체 실행에서 장면당 한 번뿐이다. - ai-video 가 아닌 장면(켄번즈 클립)은 평가하지 않는다. - 평가 결과를 지어내지 않는다. - 설계도(blueprint)는 바꾸지 않는다. - 설명·마크다운 없이 JSON 객체 하나만 답한다.