140 lines
4.9 KiB
Python
140 lines
4.9 KiB
Python
|
|
#!/usr/bin/env python3
|
||
|
|
# -*- coding: utf-8 -*-
|
||
|
|
"""
|
||
|
|
patch_prompts_c1_c4.py — Mises à jour des prompts sources (C3 + C4)
|
||
|
|
===================================================================
|
||
|
|
Insère dans les prompts SOURCES les règles hors-catalogue accumulées
|
||
|
|
depuis C1 (le catalogue, lui, se propage tout seul via
|
||
|
|
prompt_injection_v2.py — ne jamais l'éditer à la main) :
|
||
|
|
|
||
|
|
1. prompt_the_narrator_v4.md
|
||
|
|
- Notes du présentateur (C3) : ligne facultative « Notes : »
|
||
|
|
par slide à la formalisation.
|
||
|
|
- Images du projet (C4) : référencer les fichiers listés par
|
||
|
|
/lire dans les slides visuelles.
|
||
|
|
2. prompt_the_free_designer.md
|
||
|
|
- Nouveau bloc « image » (C4) dans le vocabulaire freeform.
|
||
|
|
3. prompt_the_encoder_v2.md (fallback agent — mode express
|
||
|
|
uniquement ; en mode schema le prompt est embarqué dans
|
||
|
|
encoder_schema.py)
|
||
|
|
- Transcription du champ notes.
|
||
|
|
|
||
|
|
Ancres = titres de section Markdown (stables). Refuse de patcher deux
|
||
|
|
fois. Sauvegardes .bak-prompts.
|
||
|
|
|
||
|
|
Usage (dossier du pipeline, single-line) :
|
||
|
|
python3 patch_prompts_c1_c4.py
|
||
|
|
|
||
|
|
APRÈS ce patch, la séquence complète de propagation est :
|
||
|
|
python3 prompt_injection_v2.py && python3 build_gallery.py
|
||
|
|
puis recoller dans Mistral Studio :
|
||
|
|
- Agent Narrator ← prompt_the_narrator_v4.md (source)
|
||
|
|
- Agent Designer ← prompt_the_designer_injected_v3.md
|
||
|
|
- Agent Encoder ← prompt_the_encoder_injected_v2.md
|
||
|
|
- Agent Free Designer ← prompt_the_free_designer.md (source)
|
||
|
|
"""
|
||
|
|
|
||
|
|
import shutil
|
||
|
|
import sys
|
||
|
|
from pathlib import Path
|
||
|
|
|
||
|
|
JOBS = [
|
||
|
|
{
|
||
|
|
"file": "prompt_the_narrator_v4.md",
|
||
|
|
"marker": "## IMAGES DU PROJET",
|
||
|
|
"anchor": "## RÈGLES ABSOLUES",
|
||
|
|
"block": """## NOTES DU PRÉSENTATEUR (formalisation)
|
||
|
|
|
||
|
|
À la formalisation, tu peux ajouter sous chaque slide une ligne
|
||
|
|
facultative :
|
||
|
|
|
||
|
|
Notes : [2-3 phrases de narration orale pour le présentateur — le ton
|
||
|
|
parlé, les transitions, l'exemple à raconter. Pas une répétition du
|
||
|
|
contenu affiché.]
|
||
|
|
|
||
|
|
Ces notes seront placées dans la zone commentaires de PowerPoint,
|
||
|
|
invisibles à l'audience. N'en mets que là où elles apportent quelque
|
||
|
|
chose.
|
||
|
|
|
||
|
|
## IMAGES DU PROJET
|
||
|
|
|
||
|
|
Quand la commande /lire t'a fourni une liste « IMAGES DISPONIBLES DANS
|
||
|
|
assets/ », tu peux construire des slides visuelles autour de ces
|
||
|
|
fichiers : ouverture de chapitre sur une image forte, slide
|
||
|
|
image + points clés. Référence toujours le nom de fichier EXACT tel
|
||
|
|
que listé. Ne référence JAMAIS une image absente de la liste.
|
||
|
|
|
||
|
|
""",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"file": "prompt_the_free_designer.md",
|
||
|
|
"marker": "- type: image",
|
||
|
|
"anchor": "## FORMAT DE SORTIE",
|
||
|
|
"block": """### Bloc image (nouveau)
|
||
|
|
|
||
|
|
- type: image # image du dossier assets/ du projet
|
||
|
|
image: photo.png # nom de fichier EXACT (liste fournie en contexte)
|
||
|
|
fit: cover # cover (remplit, recadrage centré) | contain
|
||
|
|
# x/y/w/h : grille habituelle. Jamais de déformation.
|
||
|
|
# Ne référence JAMAIS un fichier absent de la liste fournie.
|
||
|
|
|
||
|
|
""",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"file": "prompt_the_encoder_v2.md",
|
||
|
|
"marker": "champ `notes`",
|
||
|
|
"anchor": "## GESTION DE LA LONGUEUR",
|
||
|
|
"block": """### Notes du présentateur
|
||
|
|
|
||
|
|
Si une slide du plan contient une ligne « Notes : ... », transcris son
|
||
|
|
contenu dans un champ `notes` de la slide YAML (chaîne simple). Les
|
||
|
|
lignes de justification du Designer (commençant par →) ne sont NI du
|
||
|
|
contenu NI des notes : ignore-les.
|
||
|
|
|
||
|
|
""",
|
||
|
|
},
|
||
|
|
]
|
||
|
|
|
||
|
|
|
||
|
|
def fail(msg):
|
||
|
|
print(" ! %s" % msg)
|
||
|
|
sys.exit(1)
|
||
|
|
|
||
|
|
|
||
|
|
def main():
|
||
|
|
patched = 0
|
||
|
|
for job in JOBS:
|
||
|
|
path = Path(job["file"])
|
||
|
|
if not path.exists():
|
||
|
|
print(" ~ %s introuvable — sauté." % path)
|
||
|
|
continue
|
||
|
|
content = path.read_text(encoding="utf-8")
|
||
|
|
if job["marker"] in content:
|
||
|
|
print(" = %s : déjà à jour." % path)
|
||
|
|
continue
|
||
|
|
n = content.count(job["anchor"])
|
||
|
|
if n != 1:
|
||
|
|
fail("%s : ancre %r trouvée %d fois — insertion manuelle "
|
||
|
|
"requise (bloc dans ce script)." % (path, job["anchor"],
|
||
|
|
n))
|
||
|
|
shutil.copy2(path, str(path) + ".bak-prompts")
|
||
|
|
content = content.replace(job["anchor"],
|
||
|
|
job["block"] + job["anchor"])
|
||
|
|
path.write_text(content, encoding="utf-8")
|
||
|
|
print(" + %s : bloc inséré avant %r." % (path, job["anchor"]))
|
||
|
|
patched += 1
|
||
|
|
if patched == 0:
|
||
|
|
print("\n Rien à faire.")
|
||
|
|
return
|
||
|
|
print("\n Propager : python3 prompt_injection_v2.py && "
|
||
|
|
"python3 build_gallery.py")
|
||
|
|
print(" Puis recoller dans Mistral Studio :")
|
||
|
|
print(" Narrator ← prompt_the_narrator_v4.md (source)")
|
||
|
|
print(" Designer ← prompt_the_designer_injected_v3.md")
|
||
|
|
print(" Encoder ← prompt_the_encoder_injected_v2.md")
|
||
|
|
print(" Free Designer ← prompt_the_free_designer.md (source)")
|
||
|
|
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
main()
|