"""The render prompt of a window: six sections, as the prompt-writing guide (guide(), data/short_guide.md) describes, in case/win/prompt.txt. Who writes it: - by default the client (the agent driving this MCP): write_prompts returns one brief per window - the facts of the window, the rules below, the guide and example paths, its pictures and contact sheet - and set_prompt stores the text the client wrote; - with REMAKE_LLM_MODEL set, the server, through an OpenAI-compatible chat API with images (REMAKE_LLM_BASE_URL / REMAKE_LLM_API_KEY, else OPENAI_BASE_URL / OPENAI_API_KEY), from the same brief. Either way the prompt is stored with `fp`, the fingerprint of what it was written from (plan, window, ref paints, cast), and stamp.json (render span + case.json), so submit refuses a prompt that no longer matches its paints. case/win/ also holds the window's cut: cond.mp4 (draft canvas), audio.m4a, sheet.jpg (contact sheet every 0.5 s) and cut.json, the span it was cut from; a cut that no longer matches its window is wiped or re-cut before any prompt is written for it, and the final-canvas cond720.mp4 goes with it. """ import base64 import hashlib import io import json import os import re import shutil import subprocess import time from concurrent.futures import ThreadPoolExecutor from pathlib import Path from openai import OpenAI from PIL import Image from .common import ARM, FPS, STOP, contact, jr, kind, log, spent from .kit import size from .paint import MAX_USD SECTIONS = ["subject_definitions:", "summary:", "retention_analysis:", "detailed_description:", "overall_soundscape:", "non_diegetic_music:"] DATA = Path(__file__).resolve().parent / "data" EXAMPLE, EDIT_EXAMPLE = DATA / "example_prompt.txt", DATA / "example_edit_prompt.txt" LLM = os.environ.get("REMAKE_LLM_MODEL") # REMAKE_LLM_MODEL=codex-pool: the server writes them with one helper `codex exec` per window (paint.py's pool # helper: own CODEX_HOME, no MCP, read-only), from the same brief and pictures; free on the codex login PPOOL = LLM == "codex-pool" # the helper writes typographic punctuation the lint flags, and the agent cannot see the text to fix it (on one run two # windows were written twice for it); folded on store TO_ASCII = str.maketrans({"—": "-", "–": "-", "‑": "-", "−": "-", "‘": "'", "’": "'", "“": '"', "”": '"', "…": "...", "×": "x", " ": " ", "→": "->"}) PROMPT_MODEL = os.environ.get("REMAKE_PROMPT_MODEL", "gpt-6.1-terra") PROMPT_EFFORT = os.environ.get("REMAKE_PROMPT_EFFORT", "high") # codex_exec.sh put the guide and examples at the end of AGENTS.md: re-read after every compaction, never resent IN_AGENTS = os.environ.get("REMAKE_GUIDE_IN_AGENTS") == "1" GUIDE_AT = "at the end of AGENTS.md" if IN_AGENTS else "at the top of the session's first write_prompts result" # codex code mode keeps ~10K tokens (~40K chars) of one exec result and drops the middle: briefs past this many # characters wait for the next call BRIEF_CHARS = int(os.environ.get("REMAKE_BRIEF_CHARS", "32000")) def guide(): """The prompt-writing guide shipped in data/: a short summary of the six-section format.""" return DATA / "short_guide.md" RULES = ( "Rules: describe the TARGET video in present tense, never edit instructions; every is bound to " "the picture(s) that show it and its descriptor must exclude every similar person in frame; " "retention_analysis: