-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
225 lines (198 loc) · 10.1 KB
/
Copy pathapp.py
File metadata and controls
225 lines (198 loc) · 10.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# app.py — Gradio UI pour Sigma-LLM (Llama-3 ready, Codespaces friendly)
import os, sys, importlib.util, traceback, json, pathlib
import gradio as gr
# ───────────────────────────────────────────────────────────────
# Import robuste de SigmaLLM (à la racine ou par chemin explicite)
# ───────────────────────────────────────────────────────────────
def import_sigma_llm():
try:
from sigma_llm_complete import SigmaLLM
return SigmaLLM
except Exception:
here = os.path.dirname(os.path.abspath(__file__))
candidate = os.path.join(here, "sigma_llm_complete.py")
if not os.path.exists(candidate):
raise ImportError("sigma_llm_complete.py introuvable à la racine du repo")
spec = importlib.util.spec_from_file_location("sigma_llm_complete", candidate)
if spec is None or spec.loader is None:
raise ImportError("Impossible de créer un ModuleSpec pour sigma_llm_complete.py")
mod = importlib.util.module_from_spec(spec)
sys.modules["sigma_llm_complete"] = mod
spec.loader.exec_module(mod)
if not hasattr(mod, "SigmaLLM"):
raise ImportError("SigmaLLM non trouvé dans sigma_llm_complete.py")
return mod.SigmaLLM
SigmaLLM = import_sigma_llm()
# ───────────────────────────────────────────────────────────────
# Préférence modèle + chaîne de fallbacks
# ───────────────────────────────────────────────────────────────
PREFERRED = os.getenv("SIGMA_LLM_MODEL", "meta-llama/Meta-Llama-3-8B-Instruct")
FALLBACKS = [
"TinyLlama/TinyLlama-1.1B-Chat-v1.0",
"microsoft/Phi-3-mini-4k-instruct",
"meta-llama/Meta-Llama-3-8B-Instruct",
]
# Dossiers utiles (pour affichage & reset mémoire)
CFG = os.getenv("SIGMA_CONFIGS_DIR", "configs")
ST = os.getenv("SIGMA_STATE_DIR", "state")
RP = os.getenv("SIGMA_REPORTS_DIR", "reports")
OUT = os.getenv("SIGMA_OUTPUTS_DIR", "outputs")
for d in (CFG, ST, RP, OUT):
os.makedirs(d, exist_ok=True)
LATEST_OUT = os.path.join(OUT, "latest_output.txt")
# ───────────────────────────────────────────────────────────────
# Fabrique/Reload d’agent avec fallback
# ───────────────────────────────────────────────────────────────
_agent = None
_active_model = None
def make_agent(model_name: str):
"""Instancie SigmaLLM avec fallback en cascade si besoin."""
global _agent, _active_model
tried = [model_name] + [m for m in FALLBACKS if m != model_name]
last_err = None
for m in tried:
try:
print(f"[SigmaLLM] Loading model: {m}", flush=True)
_agent = SigmaLLM(model_name=m)
_active_model = m
return _agent
except Exception as e:
last_err = e
print(f"[SigmaLLM] Failed loading {m}: {e}", flush=True)
raise RuntimeError(f"Impossible de charger un modèle. Dernière erreur: {last_err}")
def get_agent():
global _agent
if _agent is None:
_agent = make_agent(PREFERRED)
return _agent
# ───────────────────────────────────────────────────────────────
# Utilitaires mémoire
# ───────────────────────────────────────────────────────────────
def reset_memory():
"""Efface la mémoire conversationnelle & fichiers rapides, puis recrée l'agent."""
for p in [
os.path.join(ST, "conversation.json"),
os.path.join(ST, "episodes.jsonl"),
os.path.join(ST, "semantic_index.jsonl"),
]:
try:
if os.path.exists(p):
os.remove(p)
except Exception:
pass
try:
if os.path.exists(LATEST_OUT):
os.remove(LATEST_OUT)
except Exception:
pass
make_agent(_active_model or PREFERRED)
# ───────────────────────────────────────────────────────────────
# Fonction de chat (branchée sur SigmaLLM.generate)
# ───────────────────────────────────────────────────────────────
def chat_fn(message, history, temperature, top_p):
"""
Gradio ChatInterface:
- message: str
- history: list[(user, assistant)]
- temperature/top_p: sliders (additional_inputs)
"""
agent = get_agent()
# pilote direct des curseurs de l’agent
try:
agent.temp = float(temperature)
agent.top_p = float(top_p)
except Exception:
pass
try:
reply = agent.generate(message, max_new_tokens=200)
if isinstance(reply, str) and "AI:" in reply:
reply = reply.split("AI:")[-1].strip()
# garde: sauvegarder aussi pour debug rapide
try:
with open(LATEST_OUT, "w", encoding="utf-8") as f:
f.write(reply or "")
except Exception:
pass
return reply or "(réponse vide)"
except Exception as e:
tb = traceback.format_exc(limit=4)
print(f"[chat_fn] ERROR: {e}\n{tb}", flush=True)
return f"⚠️ Erreur: {e}\n```\n{tb}\n```"
# ───────────────────────────────────────────────────────────────
# Callbacks UI: changer le modèle, reset mémoire, infos système
# ───────────────────────────────────────────────────────────────
AVAILABLE = [
"meta-llama/Meta-Llama-3-8B-Instruct",
"TinyLlama/TinyLlama-1.1B-Chat-v1.0",
"microsoft/Phi-3-mini-4k-instruct",
"meta-llama/Meta-Llama-3-8B-Instruct",
]
def on_change_model(new_model):
try:
make_agent(new_model)
return f"✅ Modèle chargé: {new_model}"
except Exception as e:
return f"❌ Échec chargement {new_model}: {e}"
def on_reset_memory():
try:
reset_memory()
return "🧹 Mémoire réinitialisée."
except Exception as e:
return f"❌ Reset échoué: {e}"
def info_text():
here = os.getcwd()
info = {
"active_model": _active_model or PREFERRED,
"cwd": here,
"outputs": str(pathlib.Path(OUT).resolve()),
"reports": str(pathlib.Path(RP).resolve()),
"state": str(pathlib.Path(ST).resolve()),
}
return "```\n" + json.dumps(info, indent=2, ensure_ascii=False) + "\n```"
# ───────────────────────────────────────────────────────────────
# Gradio UI
# ───────────────────────────────────────────────────────────────
with gr.Blocks(title="Sigma-LLM Reflexive Agent") as demo:
gr.Markdown("## 🧠 Sigma-LLM — S(t) / O(t) / Δcoh — Interface interactive")
with gr.Row():
model_dd = gr.Dropdown(
choices=AVAILABLE,
value=PREFERRED if PREFERRED in AVAILABLE else AVAILABLE[0],
label="Modèle",
interactive=True,
)
temp = gr.Slider(minimum=0.60, maximum=1.30, value=0.95, step=0.01, label="temperature")
topp = gr.Slider(minimum=0.70, maximum=0.99, value=0.95, step=0.01, label="top_p")
btn_reload = gr.Button("🔄 Recharger modèle")
btn_reset = gr.Button("🧹 Reset mémoire")
# zone d’état
status_msg = gr.Markdown()
status = gr.Markdown(value=info_text())
def _reload(m):
msg = on_change_model(m)
return msg, info_text()
btn_reload.click(_reload, inputs=model_dd, outputs=[status_msg, status])
btn_reset.click(lambda: (on_reset_memory(), info_text()), outputs=[status_msg, status])
gr.Markdown("### 💬 Chat")
chat = gr.ChatInterface(
fn=chat_fn,
additional_inputs=[temp, topp], # ✅ sliders réellement reliés à chat_fn
chatbot=gr.Chatbot(height=460, avatar_images=(None, None)),
textbox=gr.Textbox(placeholder="Tape ton message…", autofocus=True),
title="Sigma-LLM",
description="Agent réflexif (Llama-3 ready). Les sorties sont archivées dans outputs/ et reports/.",
theme="soft",
cache_examples=False,
)
# ───────────────────────────────────────────────────────────────
# Lancement serveur (Codespaces/localhost)
# ───────────────────────────────────────────────────────────────
if __name__ == "__main__":
# Pré-initialise pour feedback immédiat dans l’UI
try:
make_agent(PREFERRED)
except Exception as e:
print(f"[boot] warning: preferred model not available ({e}) — UI démarre avec fallback à la première requête.")
port = int(os.getenv("PORT", "7860"))
print(f"[SigmaLLM] Gradio démarre sur 0.0.0.0:{port}", flush=True)
demo.launch(server_name="0.0.0.0", server_port=port, show_error=True)