expAge commited on
Commit
abf6044
·
1 Parent(s): 118bc82

ux: bouton 'Soumettre' post-hoc sous Lancer (Enrich/Audit/Signalement)

Browse files

Apres une analyse, sous le bouton 'Lancer …' (primary violet) apparait
un bouton 'Soumettre a JDM (post-hoc)' en variant=stop (rouge), visible
des qu'un fichier .enrich/.audit/.err a ete produit (je_file.change()).

Logique de grise :
- Au build : interactive selon que JDM_DROPS_API_KEY est dans l'env.
- Quand jarvis_drops_key change (bandeau), un wire transverse rafraichit
les 3 boutons (cle UI override env -> bouton actif).
- Quand un fichier est produit : visible=True + interactive recalcule.

Au clic, appelle submit_to_jdm via le nouvel helper
jarvis.submit_existing_file() qui :
- override temporairement JDM_DROPS_API_KEY avec drops_key UI si fournie
- appelle submit_to_jdm(path, model_name=…)
- append le verdict (OK/echec) au chatbot existant

Permet de soumettre meme si on n'avait pas coche la case 'Soumettre
directement' au lancement. 163 verts.

Files changed (2) hide show
  1. app.py +115 -0
  2. jarvis.py +64 -0
app.py CHANGED
@@ -1617,6 +1617,17 @@ with gr.Blocks(theme=THEME, title="JDMAgent Demo", head=_HEAD_JS, css=_CHATBOT_C
1617
  "🌱 Lancer l'enrichissement",
1618
  variant="primary",
1619
  )
 
 
 
 
 
 
 
 
 
 
 
1620
  with gr.Column(scale=2):
1621
  je_chat = gr.Chatbot(
1622
  type="messages",
@@ -1683,6 +1694,30 @@ with gr.Blocks(theme=THEME, title="JDMAgent Demo", head=_HEAD_JS, css=_CHATBOT_C
1683
  outputs=[je_chat, je_file, je_preview],
1684
  )
1685
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1686
  with gr.Tab("🔍 Audit", id="jarvis-audit"):
1687
  gr.Markdown(
1688
  "Audit sémantique : détecte les CONTAMINATIONS du "
@@ -1713,6 +1748,13 @@ with gr.Blocks(theme=THEME, title="JDMAgent Demo", head=_HEAD_JS, css=_CHATBOT_C
1713
  "🔍 Lancer l'audit",
1714
  variant="primary",
1715
  )
 
 
 
 
 
 
 
1716
  with gr.Column(scale=2):
1717
  ja_chat = gr.Chatbot(
1718
  type="messages",
@@ -1769,6 +1811,28 @@ with gr.Blocks(theme=THEME, title="JDMAgent Demo", head=_HEAD_JS, css=_CHATBOT_C
1769
  outputs=[ja_chat, ja_file, ja_preview],
1770
  )
1771
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1772
  with gr.Tab("🕳️ Détection de trous", id="jarvis-gaps"):
1773
  gr.Markdown(
1774
  "Identifie les trous de couverture (MISSING / "
@@ -1985,6 +2049,13 @@ with gr.Blocks(theme=THEME, title="JDMAgent Demo", head=_HEAD_JS, css=_CHATBOT_C
1985
  "⚠️ Scanner et signaler",
1986
  variant="primary",
1987
  )
 
 
 
 
 
 
 
1988
  with gr.Column(scale=2):
1989
  js_chat = gr.Chatbot(
1990
  type="messages",
@@ -2041,6 +2112,28 @@ with gr.Blocks(theme=THEME, title="JDMAgent Demo", head=_HEAD_JS, css=_CHATBOT_C
2041
  outputs=[js_chat, js_file, js_preview],
2042
  )
2043
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2044
  with gr.Tab("📊 Stats", id="jarvis-stats"):
2045
  gr.Markdown(
2046
  "Statistiques de couverture JDM. Deux modes "
@@ -2145,6 +2238,28 @@ with gr.Blocks(theme=THEME, title="JDMAgent Demo", head=_HEAD_JS, css=_CHATBOT_C
2145
  outputs=[jst_term, jst_relation, jarvis_tabs],
2146
  )
2147
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2148
  # ----- Tab 6: Aide / Installation (Phase 13.7) -----
2149
  with gr.Tab("🛠️ Aide / Installation"):
2150
  gr.Markdown(AIDE_MD)
 
1617
  "🌱 Lancer l'enrichissement",
1618
  variant="primary",
1619
  )
1620
+ # Bouton de soumission post-hoc — apparaît une
1621
+ # fois qu'un fichier .enrich a été produit.
1622
+ # Variant 'stop' (rouge) pour le distinguer du
1623
+ # primary 'Lancer'. Grisé si pas de clé Drops.
1624
+ from jarvis import has_drops_key as _has_dk
1625
+ je_submit = gr.Button(
1626
+ "📤 Soumettre à JDM (post-hoc)",
1627
+ variant="stop",
1628
+ visible=False,
1629
+ interactive=_has_dk(),
1630
+ )
1631
  with gr.Column(scale=2):
1632
  je_chat = gr.Chatbot(
1633
  type="messages",
 
1694
  outputs=[je_chat, je_file, je_preview],
1695
  )
1696
 
1697
+ # Quand un fichier est produit (je_file devient visible),
1698
+ # on rend visible le bouton « Soumettre » post-hoc.
1699
+ def _show_submit_btn(file_path, drops_key):
1700
+ if not file_path:
1701
+ return gr.update(visible=False)
1702
+ from jarvis import has_drops_key as _hk
1703
+ return gr.update(visible=True, interactive=_hk(drops_key))
1704
+
1705
+ je_file.change(
1706
+ _show_submit_btn,
1707
+ inputs=[je_file, jarvis_drops_key],
1708
+ outputs=[je_submit],
1709
+ )
1710
+
1711
+ def _submit_enrich(file_path, drops_key, model, chat):
1712
+ from jarvis import submit_existing_file
1713
+ return submit_existing_file(file_path, drops_key, model, chat)
1714
+
1715
+ je_submit.click(
1716
+ _submit_enrich,
1717
+ inputs=[je_file, jarvis_drops_key, jarvis_model, je_chat],
1718
+ outputs=[je_chat],
1719
+ )
1720
+
1721
  with gr.Tab("🔍 Audit", id="jarvis-audit"):
1722
  gr.Markdown(
1723
  "Audit sémantique : détecte les CONTAMINATIONS du "
 
1748
  "🔍 Lancer l'audit",
1749
  variant="primary",
1750
  )
1751
+ from jarvis import has_drops_key as _hk_a
1752
+ ja_submit = gr.Button(
1753
+ "📤 Soumettre à JDM (post-hoc)",
1754
+ variant="stop",
1755
+ visible=False,
1756
+ interactive=_hk_a(),
1757
+ )
1758
  with gr.Column(scale=2):
1759
  ja_chat = gr.Chatbot(
1760
  type="messages",
 
1811
  outputs=[ja_chat, ja_file, ja_preview],
1812
  )
1813
 
1814
+ def _show_audit_submit(file_path, drops_key):
1815
+ if not file_path:
1816
+ return gr.update(visible=False)
1817
+ from jarvis import has_drops_key as _hk
1818
+ return gr.update(visible=True, interactive=_hk(drops_key))
1819
+
1820
+ ja_file.change(
1821
+ _show_audit_submit,
1822
+ inputs=[ja_file, jarvis_drops_key],
1823
+ outputs=[ja_submit],
1824
+ )
1825
+
1826
+ def _submit_audit(file_path, drops_key, model, chat):
1827
+ from jarvis import submit_existing_file
1828
+ return submit_existing_file(file_path, drops_key, model, chat)
1829
+
1830
+ ja_submit.click(
1831
+ _submit_audit,
1832
+ inputs=[ja_file, jarvis_drops_key, jarvis_model, ja_chat],
1833
+ outputs=[ja_chat],
1834
+ )
1835
+
1836
  with gr.Tab("🕳️ Détection de trous", id="jarvis-gaps"):
1837
  gr.Markdown(
1838
  "Identifie les trous de couverture (MISSING / "
 
2049
  "⚠️ Scanner et signaler",
2050
  variant="primary",
2051
  )
2052
+ from jarvis import has_drops_key as _hk_s
2053
+ js_submit = gr.Button(
2054
+ "📤 Soumettre à JDM (post-hoc)",
2055
+ variant="stop",
2056
+ visible=False,
2057
+ interactive=_hk_s(),
2058
+ )
2059
  with gr.Column(scale=2):
2060
  js_chat = gr.Chatbot(
2061
  type="messages",
 
2112
  outputs=[js_chat, js_file, js_preview],
2113
  )
2114
 
2115
+ def _show_signal_submit(file_path, drops_key):
2116
+ if not file_path:
2117
+ return gr.update(visible=False)
2118
+ from jarvis import has_drops_key as _hk
2119
+ return gr.update(visible=True, interactive=_hk(drops_key))
2120
+
2121
+ js_file.change(
2122
+ _show_signal_submit,
2123
+ inputs=[js_file, jarvis_drops_key],
2124
+ outputs=[js_submit],
2125
+ )
2126
+
2127
+ def _submit_signal(file_path, drops_key, model, chat):
2128
+ from jarvis import submit_existing_file
2129
+ return submit_existing_file(file_path, drops_key, model, chat)
2130
+
2131
+ js_submit.click(
2132
+ _submit_signal,
2133
+ inputs=[js_file, jarvis_drops_key, jarvis_model, js_chat],
2134
+ outputs=[js_chat],
2135
+ )
2136
+
2137
  with gr.Tab("📊 Stats", id="jarvis-stats"):
2138
  gr.Markdown(
2139
  "Statistiques de couverture JDM. Deux modes "
 
2238
  outputs=[jst_term, jst_relation, jarvis_tabs],
2239
  )
2240
 
2241
+ # ---- Câblage transverse : quand la clé LLMDrops change dans
2242
+ # le bandeau, on rafraîchit l'état interactive des 3 boutons
2243
+ # « Soumettre » post-hoc (s'ils sont déjà visibles). Si le
2244
+ # bouton n'est pas encore visible (pas de fichier produit),
2245
+ # on garde son visible=False.
2246
+ def _refresh_submit_buttons(drops_key):
2247
+ from jarvis import has_drops_key as _hk
2248
+ ok = _hk(drops_key)
2249
+ # Le `interactive` se met à jour même quand visible=False ;
2250
+ # quand le bouton deviendra visible, l'état est cohérent.
2251
+ return (
2252
+ gr.update(interactive=ok),
2253
+ gr.update(interactive=ok),
2254
+ gr.update(interactive=ok),
2255
+ )
2256
+
2257
+ jarvis_drops_key.change(
2258
+ _refresh_submit_buttons,
2259
+ inputs=[jarvis_drops_key],
2260
+ outputs=[je_submit, ja_submit, js_submit],
2261
+ )
2262
+
2263
  # ----- Tab 6: Aide / Installation (Phase 13.7) -----
2264
  with gr.Tab("🛠️ Aide / Installation"):
2265
  gr.Markdown(AIDE_MD)
jarvis.py CHANGED
@@ -413,6 +413,70 @@ def _read_file_preview(path: Optional[str], max_chars: int = 6000) -> str:
413
  return text
414
 
415
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
416
  def run_jarvis_flow(
417
  prompt: str,
418
  *,
 
413
  return text
414
 
415
 
416
+ def submit_existing_file(
417
+ file_path: Optional[str],
418
+ drops_key: str,
419
+ model_name: str,
420
+ current_chat: Optional[list[dict]] = None,
421
+ ) -> list[dict]:
422
+ """Soumet un fichier .enrich/.audit/.err déjà produit au LLMDrops JDM.
423
+
424
+ À utiliser pour le bouton « 📤 Soumettre » post-hoc des sous-onglets
425
+ Jarvis. Si une clé est fournie côté UI (`drops_key`), elle override
426
+ temporairement `JDM_DROPS_API_KEY` le temps de l'appel.
427
+
428
+ Renvoie la liste de messages mise à jour pour le `gr.Chatbot` (append
429
+ d'un message assistant avec le verdict).
430
+ """
431
+ import os
432
+ from jdm_agent.enrich.uploader import submit_to_jdm
433
+
434
+ chat = list(current_chat) if current_chat else []
435
+
436
+ if not file_path:
437
+ chat.append({
438
+ "role": "assistant",
439
+ "content": "⚠️ Aucun fichier produit à soumettre."
440
+ })
441
+ return chat
442
+
443
+ saved = os.environ.get("JDM_DROPS_API_KEY")
444
+ if drops_key and drops_key.strip():
445
+ os.environ["JDM_DROPS_API_KEY"] = drops_key.strip()
446
+ try:
447
+ result = submit_to_jdm(file_path, model_name=(model_name or "").strip() or None)
448
+ finally:
449
+ if drops_key and drops_key.strip():
450
+ if saved is None:
451
+ os.environ.pop("JDM_DROPS_API_KEY", None)
452
+ else:
453
+ os.environ["JDM_DROPS_API_KEY"] = saved
454
+
455
+ if result.get("ok"):
456
+ chat.append({
457
+ "role": "assistant",
458
+ "content": (
459
+ f"✅ Fichier soumis à JDM (status {result.get('status_code')}) — "
460
+ f"uploadé sous le nom `{result.get('uploaded_as')}`.\n\n"
461
+ f"Réponse serveur : `{result.get('response')}`"
462
+ )
463
+ })
464
+ else:
465
+ chat.append({
466
+ "role": "assistant",
467
+ "content": f"❌ Échec de soumission : {result.get('error', 'inconnu')}"
468
+ })
469
+ return chat
470
+
471
+
472
+ def has_drops_key(ui_key: str = "") -> bool:
473
+ """True si une clé LLMDrops est disponible (UI override OU env)."""
474
+ import os
475
+ if ui_key and ui_key.strip():
476
+ return True
477
+ return bool(os.environ.get("JDM_DROPS_API_KEY", "").strip())
478
+
479
+
480
  def run_jarvis_flow(
481
  prompt: str,
482
  *,