maribakulj commited on
Commit
3c726a6
·
unverified ·
1 Parent(s): a5510c5

Revise STATUS.md for Sprint 2 updates

Browse files

Updated the STATUS.md file to reflect changes in Sprint 2, including objectives, completed tasks, and criteria for completion.

Files changed (1) hide show
  1. STATUS.md +154 -129
STATUS.md CHANGED
@@ -1,165 +1,190 @@
1
- STATUS.md — Sprint 2 : Pipeline page unique
2
- Sprint : 2 — Session A
3
- Objectif du sprint : 1 image → 1 master.json valide via Google AI
4
 
5
- Ce qui est fait (Sprint 1 ✓)
 
6
 
7
- Repo GitHub structuré, arborescence complète
8
- Schémas Pydantic : corpus_profile.py, page_master.py, annotation.py
9
- 4 profils JSON (medieval-illuminated, medieval-textual, early-modern-print, modern-handwritten)
10
- 9 templates de prompts versionnés
11
- 54 tests pytest passants (26 schemas + 28 profiles)
12
- pyproject.toml configuré
13
- 6 secrets GitHub en place :
14
- GOOGLE_AI_STUDIO_API_KEY, VERTEX_API_KEY, VERTEX_PROJECT_ID,
15
- VERTEX_LOCATION, VERTEX_SERVICE_ACCOUNT_JSON, AI_PROVIDER
16
 
 
 
 
 
 
 
 
 
 
 
17
 
18
- Contexte important pour ce sprint
19
- Providers Google AI disponibles
20
- Trois options configurées, priorité :
21
 
22
- AI_PROVIDER=vertex_api_key clé AQ.Ab... (Vertex Express, production)
23
- AI_PROVIDER=google_ai_studio clé AIza... (gratuit, développement)
24
- AI_PROVIDER=vertex_service_accountJSON credentials (institutions)
 
 
25
 
26
- Format de clé Vertex non confirmé
27
  La clé Vertex commence par AQ.Ab (format OAuth2 Vertex Express).
28
  La syntaxe SDK exacte pour ce format N'EST PAS encore validée.
29
  La Session A commence par ce test — avant tout le reste.
30
- Images test disponibles
 
31
  Pas d'images locales. On travaille avec des URLs IIIF directes.
 
32
  URL Beatus haute résolution (profil medieval-illuminated) :
33
- https://gallica.bnf.fr/iiif/ark:/12148/btv1b52505441p/f233/full/full/0/native.jpg
 
34
  URL Beatus basse résolution (même folio, qualité réduite — test confidence) :
35
- https://gallica.bnf.fr/iiif/ark:/12148/btv1b52505441p/f233/full/600,/0/native.jpg
 
36
  URL second corpus — Grandes Chroniques de France (profil medieval-textual) :
37
- https://gallica.bnf.fr/iiif/ark:/12148/btv1b84472995/f16/full/full/0/native.jpg
 
38
  Pourquoi tester deux résolutions du Beatus :
39
- Les deux images doivent produire un master.json valide.
40
- La basse résolution doit retourner un score confidence plus faible
41
- et potentiellement déclencher le statut needs_review si < flag_below (0.4).
42
- Cela valide que les seuils du profil fonctionnent correctement.
 
 
 
 
43
 
44
- Session A — Connexion Google AI + listage modèles
45
- Objectif
46
  Valider que les 3 providers fonctionnent et lister les modèles disponibles.
47
  Aucun traitement d'image. Aucun master.json. Juste la connexion.
48
- Tâches dans l'ordre
49
-
50
- Créer backend/app/services/ai/init.py (vide)
51
- Créer backend/app/services/ai/client.py
52
- → factory get_ai_client() avec les 3 options
53
- Option B (vertex_api_key) : tester les deux syntaxes possibles
54
- et documenter celle qui fonctionne dans un commentaire
55
- Créer backend/app/services/ai/models.py
56
- fonction list_available_models(client) list[dict]
57
- → filtrer sur les modèles qui supportent generateContent + vision
58
- retourner : id, display_name, supports_vision
59
- Créer backend/tests/test_ai_connection.py
60
- test_option_a_google_ai_studio() : connexion + list_models
61
- test_option_b_vertex_api_key() : connexion + list_models
62
- → test_option_c_vertex_service_account() : connexion + list_models
63
- Chaque test affiche les modèles disponibles dans les logs
64
- Lancer pytest test_ai_connection.py
65
- documenter dans DECISIONS.md la syntaxe exacte validée pour AQ.Ab
66
-
67
- Critère de done Session A
 
 
 
 
 
68
  Les 3 tests de connexion passent.
69
  On sait quelle syntaxe fonctionne pour la clé AQ.Ab.
70
  La liste des modèles disponibles est affichée pour chaque provider.
71
- Ne pas faire en Session A
72
 
73
- Aucun traitement d'image
74
- Aucun appel de prompt
75
- Aucune ingestion de corpus
 
76
 
 
77
 
78
- Session B — Ingestion + préparation image
79
- Objectif
 
80
  Ingérer une image depuis une URL IIIF et produire un dérivé web prêt pour l'IA.
81
- Tâches dans l'ordre
82
-
83
- Créer backend/app/services/ingest/init.py
84
- Créer backend/app/services/ingest/image_loader.py
85
- load_from_url(url) → image bytes + dimensions
86
- load_from_file(path) → image bytes + dimensions
87
- Pillow pour lire et redimensionner
88
- Créer backend/app/services/image/init.py
89
- Créer backend/app/services/image/processor.py
90
- make_derivative(image_bytes, max_size=1500) → JPEG bytes
91
- get_dimensions(image_bytes) → (width, height)
92
- Tester sur les 3 URLs dans l'ordre :
93
-
94
- Beatus haute résolution :
95
- https://gallica.bnf.fr/iiif/ark:/12148/btv1b52505441p/f233/full/full/0/native.jpg
96
- Beatus basse résolution :
97
- https://gallica.bnf.fr/iiif/ark:/12148/btv1b52505441p/f233/full/600,/0/native.jpg
98
- Grandes Chroniques :
99
- https://gallica.bnf.fr/iiif/ark:/12148/btv1b84472995/f16/full/full/0/native.jpg
100
- → vérifier que les 3 images se téléchargent et se redimensionnent
101
- → vérifier que les dimensions sont bien extraites pour chaque cas
102
-
103
-
104
- Ajouter tests/test_image_processing.py
105
-
106
- Critère de done Session B
107
  Les 3 URLs produisent chacune un JPEG dérivé de 1500px max.
108
  Les dimensions sont correctement extraites pour chaque image.
109
  La basse résolution Beatus produit bien une image plus petite en entrée.
110
 
111
- Session C — Premier appel IA + master.json
112
- Objectif
 
 
 
113
  1 image → 1 appel Google AI → 1 master.json valide.
114
  C'est le cœur du Sprint 2.
115
- Tâches dans l'ordre
116
-
117
- Créer backend/app/services/ai/prompt_loader.py
118
- load_and_render(template_path, context_dict) → str
119
- remplace {{profile_label}}, {{language_hints}}, {{script_type}}
120
- Créer backend/app/services/ai/pipeline.py
121
- → analyze_page(image_bytes, corpus_profile, model_id) → PageMaster
122
- → Appelle le prompt primary_v1.txt du profil
123
- Stocke ai_raw.json (brut) + master.json (validé Pydantic)
124
- Lève une erreur explicite si le JSON retourné est invalide
125
- Tester sur les 3 images dans l'ordre :
126
- a. Beatus haute résolution + profil medieval-illuminated
127
- → master.json valide, confidence attendue > 0.6
128
- b. Beatus basse résolution + profil medieval-illuminated
129
- → master.json valide, confidence attendue plus faible
130
- vérifier que editorial.status = "needs_review" si confidence < 0.4
131
- c. Grandes Chroniques + profil medieval-textual
132
- → master.json valide, extensions sans iconography
133
- valide la généricité (zéro logique Beatus dans le code)
134
- Vérifier pour chaque master.json :
135
- ai_raw.json bien séparé
136
- processing.provider = "vertex_api_key"
137
- → schema_version = "1.0"
138
- bbox toutes en format [x, y, w, h] avec w > 0 et h > 0
139
- Ajouter tests/test_pipeline.py
140
-
141
- Critère de done Session C
 
 
 
 
 
142
  3 master.json valides produits (Beatus HR + Beatus BR + Grandes Chroniques).
143
  La basse résolution déclenche bien un score de confidence plus faible.
144
  Les Grandes Chroniques ne contiennent pas de bloc iconography dans extensions.
145
  pytest 100% sur tous les fichiers de test.
146
  ai_raw.json et master.json bien séparés dans data/ pour chaque page.
147
 
148
- Critère de fin du Sprint 2
149
-
150
- 3 providers connectés et testés
151
- Syntaxe AQ.Ab documentée dans DECISIONS.md
152
- Pipeline page unique fonctionnel
153
- 3 master.json valides (Beatus HR + Beatus BR + Grandes Chroniques)
154
- La basse résolution produit un confidence plus faible que la haute résolution
155
- Règle de généricité respectée (zéro logique hardcodée Beatus)
156
- pytest 100%
157
-
158
-
159
- Ne pas faire dans ce sprint
160
-
161
- Aucune API FastAPI
162
- Aucune interface web
163
- Aucun ALTO / METS / IIIF
164
- Aucun traitement en lot
165
- Passes dérivées (traduction, commentaire) : Sprint 3
 
 
1
+ # STATUS.md — Sprint 2 : Pipeline page unique
 
 
2
 
3
+ ## Sprint : 2 Session A
4
+ ## Objectif du sprint : 1 image → 1 master.json valide via Google AI
5
 
6
+ ---
 
 
 
 
 
 
 
 
7
 
8
+ ## Ce qui est fait (Sprint 1 ✓)
9
+ - [x] Repo GitHub structuré, arborescence complète
10
+ - [x] Schémas Pydantic : corpus_profile.py, page_master.py, annotation.py
11
+ - [x] 4 profils JSON (medieval-illuminated, medieval-textual, early-modern-print, modern-handwritten)
12
+ - [x] 9 templates de prompts versionnés
13
+ - [x] 54 tests pytest passants (26 schemas + 28 profiles)
14
+ - [x] pyproject.toml configuré
15
+ - [x] 6 secrets GitHub en place :
16
+ GOOGLE_AI_STUDIO_API_KEY, VERTEX_API_KEY, VERTEX_PROJECT_ID,
17
+ VERTEX_LOCATION, VERTEX_SERVICE_ACCOUNT_JSON, AI_PROVIDER
18
 
19
+ ---
20
+
21
+ ## Contexte important pour ce sprint
22
 
23
+ ### Providers Google AI disponibles
24
+ Trois options configurées, priorité :
25
+ - AI_PROVIDER=vertex_api_keyclé AQ.Ab... (Vertex Express, production)
26
+ - AI_PROVIDER=google_ai_studio → clé AIza... (gratuit, développement)
27
+ - AI_PROVIDER=vertex_service_account → JSON credentials (institutions)
28
 
29
+ ### Format de clé Vertex non confirmé
30
  La clé Vertex commence par AQ.Ab (format OAuth2 Vertex Express).
31
  La syntaxe SDK exacte pour ce format N'EST PAS encore validée.
32
  La Session A commence par ce test — avant tout le reste.
33
+
34
+ ### Images test disponibles
35
  Pas d'images locales. On travaille avec des URLs IIIF directes.
36
+
37
  URL Beatus haute résolution (profil medieval-illuminated) :
38
+ https://gallica.bnf.fr/iiif/ark:/12148/btv1b52505441p/f233/full/full/0/native.jpg
39
+
40
  URL Beatus basse résolution (même folio, qualité réduite — test confidence) :
41
+ https://gallica.bnf.fr/iiif/ark:/12148/btv1b52505441p/f233/full/600,/0/native.jpg
42
+
43
  URL second corpus — Grandes Chroniques de France (profil medieval-textual) :
44
+ https://gallica.bnf.fr/iiif/ark:/12148/btv1b84472995/f16/full/full/0/native.jpg
45
+
46
  Pourquoi tester deux résolutions du Beatus :
47
+ Les deux images doivent produire un master.json valide.
48
+ La basse résolution doit retourner un score confidence plus faible
49
+ et potentiellement déclencher le statut needs_review si < flag_below (0.4).
50
+ Cela valide que les seuils du profil fonctionnent correctement.
51
+
52
+ ---
53
+
54
+ ## Session A — Connexion Google AI + listage modèles
55
 
56
+ ### Objectif
 
57
  Valider que les 3 providers fonctionnent et lister les modèles disponibles.
58
  Aucun traitement d'image. Aucun master.json. Juste la connexion.
59
+
60
+ ### Tâches dans l'ordre
61
+
62
+ 1. Créer backend/app/services/ai/__init__.py (vide)
63
+
64
+ 2. Créer backend/app/services/ai/client.py
65
+ factory get_ai_client() avec les 3 options
66
+ Option B (vertex_api_key) : tester les deux syntaxes possibles
67
+ et documenter celle qui fonctionne dans un commentaire
68
+
69
+ 3. Créer backend/app/services/ai/models.py
70
+ fonction list_available_models(client) → list[dict]
71
+ filtrer sur les modèles qui supportent generateContent + vision
72
+ retourner : id, display_name, supports_vision
73
+
74
+ 4. Créer backend/tests/test_ai_connection.py
75
+ test_option_a_google_ai_studio() : connexion + list_models
76
+ test_option_b_vertex_api_key() : connexion + list_models
77
+ → test_option_c_vertex_service_account() : connexion + list_models
78
+ Chaque test affiche les modèles disponibles dans les logs
79
+
80
+ 5. Lancer pytest test_ai_connection.py
81
+ → documenter dans DECISIONS.md la syntaxe exacte validée pour AQ.Ab
82
+
83
+ ### Critère de done Session A
84
  Les 3 tests de connexion passent.
85
  On sait quelle syntaxe fonctionne pour la clé AQ.Ab.
86
  La liste des modèles disponibles est affichée pour chaque provider.
 
87
 
88
+ ### Ne pas faire en Session A
89
+ - Aucun traitement d'image
90
+ - Aucun appel de prompt
91
+ - Aucune ingestion de corpus
92
 
93
+ ---
94
 
95
+ ## Session B — Ingestion + préparation image
96
+
97
+ ### Objectif
98
  Ingérer une image depuis une URL IIIF et produire un dérivé web prêt pour l'IA.
99
+
100
+ ### Tâches dans l'ordre
101
+
102
+ 1. Créer backend/app/services/ingest/__init__.py
103
+ 2. Créer backend/app/services/ingest/image_loader.py
104
+ load_from_url(url) → image bytes + dimensions
105
+ load_from_file(path) image bytes + dimensions
106
+ Pillow pour lire et redimensionner
107
+ 3. Créer backend/app/services/image/__init__.py
108
+ 4. Créer backend/app/services/image/processor.py
109
+ make_derivative(image_bytes, max_size=1500) → JPEG bytes
110
+ get_dimensions(image_bytes) (width, height)
111
+ 5. Tester sur les 3 URLs dans l'ordre :
112
+ - Beatus haute résolution :
113
+ https://gallica.bnf.fr/iiif/ark:/12148/btv1b52505441p/f233/full/full/0/native.jpg
114
+ - Beatus basse résolution :
115
+ https://gallica.bnf.fr/iiif/ark:/12148/btv1b52505441p/f233/full/600,/0/native.jpg
116
+ - Grandes Chroniques :
117
+ https://gallica.bnf.fr/iiif/ark:/12148/btv1b84472995/f16/full/full/0/native.jpg
118
+ → vérifier que les 3 images se téléchargent et se redimensionnent
119
+ → vérifier que les dimensions sont bien extraites pour chaque cas
120
+ 6. Ajouter tests/test_image_processing.py
121
+
122
+ ### Critère de done Session B
 
 
123
  Les 3 URLs produisent chacune un JPEG dérivé de 1500px max.
124
  Les dimensions sont correctement extraites pour chaque image.
125
  La basse résolution Beatus produit bien une image plus petite en entrée.
126
 
127
+ ---
128
+
129
+ ## Session C — Premier appel IA + master.json
130
+
131
+ ### Objectif
132
  1 image → 1 appel Google AI → 1 master.json valide.
133
  C'est le cœur du Sprint 2.
134
+
135
+ ### Tâches dans l'ordre
136
+
137
+ 1. Créer backend/app/services/ai/prompt_loader.py
138
+ load_and_render(template_path, context_dict) → str
139
+ remplace {{profile_label}}, {{language_hints}}, {{script_type}}
140
+
141
+ 2. Créer backend/app/services/ai/pipeline.py
142
+ analyze_page(image_bytes, corpus_profile, model_id) PageMaster
143
+ Appelle le prompt primary_v1.txt du profil
144
+ Stocke ai_raw.json (brut) + master.json (validé Pydantic)
145
+ Lève une erreur explicite si le JSON retourné est invalide
146
+
147
+ 3. Tester sur les 3 images dans l'ordre :
148
+ a. Beatus haute résolution + profil medieval-illuminated
149
+ master.json valide, confidence attendue > 0.6
150
+ b. Beatus basse résolution + profil medieval-illuminated
151
+ → master.json valide, confidence attendue plus faible
152
+ vérifier que editorial.status = "needs_review" si confidence < 0.4
153
+ c. Grandes Chroniques + profil medieval-textual
154
+ master.json valide, extensions sans iconography
155
+ valide la généricité (zéro logique Beatus dans le code)
156
+
157
+ 4. Vérifier pour chaque master.json :
158
+ ai_raw.json bien séparé
159
+ → processing.provider = "vertex_api_key"
160
+ schema_version = "1.0"
161
+ → bbox toutes en format [x, y, w, h] avec w > 0 et h > 0
162
+
163
+ 5. Ajouter tests/test_pipeline.py
164
+
165
+ ### Critère de done Session C
166
  3 master.json valides produits (Beatus HR + Beatus BR + Grandes Chroniques).
167
  La basse résolution déclenche bien un score de confidence plus faible.
168
  Les Grandes Chroniques ne contiennent pas de bloc iconography dans extensions.
169
  pytest 100% sur tous les fichiers de test.
170
  ai_raw.json et master.json bien séparés dans data/ pour chaque page.
171
 
172
+ ---
173
+
174
+ ## Critère de fin du Sprint 2
175
+ - [ ] 3 providers connectés et testés
176
+ - [ ] Syntaxe AQ.Ab documentée dans DECISIONS.md
177
+ - [ ] Pipeline page unique fonctionnel
178
+ - [ ] 3 master.json valides (Beatus HR + Beatus BR + Grandes Chroniques)
179
+ - [ ] La basse résolution produit un confidence plus faible que la haute résolution
180
+ - [ ] Règle de généricité respectée (zéro logique hardcodée Beatus)
181
+ - [ ] pytest 100%
182
+
183
+ ---
184
+
185
+ ## Ne pas faire dans ce sprint
186
+ - Aucune API FastAPI
187
+ - Aucune interface web
188
+ - Aucun ALTO / METS / IIIF
189
+ - Aucun traitement en lot
190
+ - Passes dérivées (traduction, commentaire) : Sprint 3