65 lines
2.3 KiB
Python
65 lines
2.3 KiB
Python
"""Pydantic schemas for the Higgsfield Shorts wrapper.
|
|
|
|
VideoSpec mirrors the Remotion data contract (remotion/src/data/mumum.ts) 1:1.
|
|
The LLM (spec_builder) fills VideoSpec; Higgsfield consumes higgsfield_prompt;
|
|
Remotion consumes the rest (hook / selling_point / brand_lines / end_card).
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from typing import Literal, Optional
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
# ---------- Inbound: interview answers (no complex analysis) ----------
|
|
class GenerateRequest(BaseModel):
|
|
kind: Literal["place", "product", "message"]
|
|
biz_name: str = Field(..., description="업체명·상품명·메시지 제목")
|
|
addr: Optional[str] = Field(None, description="주소 또는 판매 사이트 URL")
|
|
price: Optional[str] = Field(None, description="가격 정보")
|
|
selling: str = Field(..., description="주인/마케터가 생각하는 강력한 한방 셀링포인트")
|
|
|
|
|
|
# ---------- VideoSpec sub-objects (mirror mumum.ts) ----------
|
|
class Hook(BaseModel):
|
|
eyebrow: str
|
|
title: str
|
|
|
|
|
|
class SellingPoint(BaseModel):
|
|
items: list[str] = Field(..., description="3개 독립 배지 카피")
|
|
|
|
|
|
class EndCard(BaseModel):
|
|
brand: str
|
|
location: str
|
|
disclosure: str = "실제 사진 기반, AI 카메라 효과를 적용한 영상입니다."
|
|
|
|
|
|
class VideoSpec(BaseModel):
|
|
# 에너지 프로파일 → Remotion 리듬/트랜지션 기본값 결정
|
|
profile: Literal["Still Cinema", "Rhythm Reveal", "Maximum Viral"]
|
|
# Higgsfield marketing_studio_video 프롬프트 (유형별 톤)
|
|
higgsfield_prompt: str
|
|
hook: Hook
|
|
selling_point: SellingPoint
|
|
brand_lines: list[str] = Field(..., description="감성 카피 2줄")
|
|
end_card: EndCard
|
|
caption: str = Field(..., description="업로드용 캡션+해시태그")
|
|
|
|
|
|
# ---------- Outbound: 자막 스크립트 4블록 ----------
|
|
class ScriptResult(BaseModel):
|
|
intro: str = Field(..., description="인트로 (후킹)")
|
|
selling: str = Field(..., description="셀링포인트")
|
|
story: str = Field(..., description="감성 스토리")
|
|
cta: str = Field(..., description="CTA")
|
|
|
|
|
|
# ---------- Outbound: final result ----------
|
|
class GenerateResult(BaseModel):
|
|
video_url: str
|
|
caption: str
|
|
profile: str
|
|
cost_credits: float = 0.0
|
|
job_id: Optional[str] = None
|