This commit is contained in:
2026-01-27 17:40:37 +01:00
parent 82947a7bd6
commit adc2cd572a
55 changed files with 4145 additions and 101 deletions

View File

@@ -0,0 +1,63 @@
import json
from app.core.ai import ai_client
from app.models.shot import Shot
from app.models.scene import Scene
class FlowGeneratorService:
async def generate_flow_json(self, shot: Shot, scene: Scene) -> dict:
prompt = f"""
You are a Virtual Cinematographer creating production instructions for Google Veo (Generative Video AI).
Generate a JSON configuration payload for the following shot.
CONTEXT:
Scene Heading: {scene.slugline}
Scene Description: {scene.raw_content}
SHOT DETAILS:
Description: {shot.description}
Additional Notes: {shot.llm_context_cache}
The JSON output should strictly follow this schema:
{{
"prompt": "Detailed visual description of the video to be generated...",
"negative_prompt": "things to avoid...",
"camera_movement": "string (e.g. pan left, zoom in, static)",
"aspect_ratio": "16:9",
"duration_seconds": 5
}}
Enhance the 'prompt' field to be highly descriptive, visual, and suitable for a text-to-video model.
Include lighting, style, and composition details based on the context.
"""
json_str = await ai_client.generate_json(prompt)
try:
return json.loads(json_str)
except json.JSONDecodeError:
raise ValueError("Failed to generate valid JSON from AI response")
async def refine_flow_json(self, current_json: dict, user_feedback: str) -> dict:
prompt = f"""
You are an AI Video Assistant.
Update the following Google Veo JSON configuration based on the user's feedback.
CURRENT JSON:
{json.dumps(current_json, indent=2)}
USER FEEDBACK:
"{user_feedback}"
Return ONLY the updated JSON object. Do not wrap in markdown code blocks.
"""
json_str = await ai_client.generate_json(prompt)
try:
return json.loads(json_str)
except json.JSONDecodeError:
raise ValueError("Failed to refine JSON")
flow_generator = FlowGeneratorService()

View File

@@ -0,0 +1,57 @@
import json
from app.core.ai import ai_client
from app.schemas.script import ScriptAnalysisResponse
class ScriptParserService:
async def parse_script(self, text_content: str) -> ScriptAnalysisResponse:
prompt = f"""
You are an expert Assistant Director and Script Supervisor.
Analyze the following screenplay text and break it down into Scenes and Shots.
For each Scene, identify:
- Scene Number (if present, or incrementing)
- Heading (INT./EXT. LOCATION - DAY/NIGHT)
- Brief Description of what happens
For each Scene, break the action down into a list of Shots (Camera setups).
For each Shot, provide:
- Shot Number (e.g. 1, 1A, etc)
- Description of the action in the shot
- Visual Notes (Camera angles, movement if implied)
- Dialogue (if any covers this shot)
Output MUST be a valid JSON object matching this structure:
{{
"scenes": [
{{
"scene_number": "1",
"heading": "INT. OFFICE - DAY",
"description": "John sits at his desk.",
"shots": [
{{
"shot_number": "1A",
"description": "Wide shot of John at desk.",
"visual_notes": "Static",
"dialogue": null
}}
]
}}
]
}}
SCRIPT TEXT:
{text_content}
"""
json_str = await ai_client.generate_json(prompt)
# Parse JSON and validate with Pydantic
try:
data = json.loads(json_str)
return ScriptAnalysisResponse(**data)
except json.JSONDecodeError:
# Fallback or retry logic could go here
raise ValueError("Failed to parse LLM response as JSON")
parser_service = ScriptParserService()