caarleexx commited on
Commit
d2a58f5
Β·
verified Β·
1 Parent(s): b13d2b2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +88 -108
app.py CHANGED
@@ -1,6 +1,7 @@
 
1
  # ╔════════════════════════════════════════════════════════════════════════════╗
2
- # β•‘ PIPELINE v30: AUTO-PLAN | MESMA UI v27 | COMPATÍVEL HF SPACES β•‘
3
- # β•‘ 1ΒΊ: MODELO CRIA PLANO β†’ ITERA PELO PRΓ“PRIO PLANO | SEM 'icon' β•‘
4
  # β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
5
 
6
  import os
@@ -21,9 +22,9 @@ else:
21
  model_flash = model_pro = None
22
 
23
  ARQUIVO_CONFIG = "protocolo.json"
24
- ARQUIVO_HISTORY = "history_v30.json"
25
 
26
- # ==================== 2. UTILIDADES (IDÊNTICAS AO v27) ====================
27
  def carregar_protocolo():
28
  try:
29
  with open(ARQUIVO_CONFIG, "r", encoding="utf-8") as f:
@@ -62,54 +63,77 @@ def ler_anexo(arquivo):
62
  return f"\n\n[ANEXO: {os.path.basename(arquivo.name)}]\n{f.read()}\n[FIM ANEXO]\n"
63
  except: return ""
64
 
65
- # ==================== 3. PLANEJADOR AUTO (1Βͺ AÇÃO) ====================
66
  def criar_plano_auto(full_input, history_contexto):
67
- """MODELO CRIA SEU PRΓ“PRIO PLANO dinamicamente"""
68
  if not model_pro:
69
  return None, "❌ Sem API_KEY"
70
 
71
- history_resumo = "\n".join([
72
- f"πŸ‘€: {h[0][:150]}... | πŸ€–: {h[1][:150]}..."
73
- for h in history_contexto[-3:]
74
- ][:300]) if history_contexto else ""
 
 
 
 
 
75
 
76
- prompt_planejador = f"""CONTEXTO HISTΓ“RICO:
77
- {history_resumo}
78
 
79
- INPUT ATUAL: {full_input}
80
 
81
- CRIE PLANO OTIMIZADO de 3-5 agentes:
82
 
83
- FORMATO JSON VÁLIDO:
 
84
  [
85
- {{"nome": "AnalisadorInput", "missao": "Identifique elementos principais", "modelo": "flash", "tipo_saida": "json"}},
86
- {{"nome": "ExecutorFinal", "missao": "Produza resposta final completa", "modelo": "pro", "tipo_saida": "texto"}}
87
  ]
88
-
89
- βœ… ÚLTIMO agente = saΓ­da FINAL pro usuΓ‘rio"""
90
 
91
  try:
92
- resp = model_pro.generate_content(prompt_planejador, temperature=0.2)
93
- plano_raw = resp.text.strip().replace('``````','')
 
 
 
 
 
 
 
 
 
 
 
94
  plano = json.loads(plano_raw)
95
 
96
  if isinstance(plano, list) and len(plano) >= 2:
 
97
  return plano, f"βœ… Plano: {len(plano)} agentes"
98
- return None, "❌ Plano invÑlido"
99
- except:
100
- return None, "❌ Erro plano"
 
 
 
 
 
 
 
 
101
 
102
- # ==================== 4. ENGINE EXECUÇÃO (ORIGINAL v27) ====================
103
  def executar_no(timeline, config):
104
  if not (model_flash or model_pro):
105
  return {"role": "system", "error": "Sem API"}, "(ERRO: API)", "Sem key"
106
 
107
  modelo = model_pro if config.get("modelo") == "pro" else model_flash
108
- contexto = json.dumps(timeline[-10:], ensure_ascii=False, indent=2)
109
 
110
- prompt = f"""--- TIMELINE ---
111
- {contexto}
112
- ----------------
113
  AGENTE: {config['nome']}
114
  MISSΓƒO: {config['missao']}"""
115
 
@@ -117,19 +141,19 @@ MISSÃO: {config['missao']}"""
117
  try:
118
  inicio = time.time()
119
  resp = modelo.generate_content(prompt)
120
- out = resp.text
121
 
122
  tempo = time.time() - inicio
123
- content = json.loads(out.strip().replace('``````','')) if config['tipo_saida']=='json' else out
124
 
125
- log += f" (OK - {tempo:.2f}s)"
126
  return {"role": "assistant", "agent": config['nome'], "content": content}, log, out
127
- except Exception as e:
128
- return {"role": "system", "error": str(e)}, f" (ERRO: {e})", str(e)
 
129
 
130
- # ==================== 5. ORQUESTRADOR v30 (PLANO AUTO) ====================
131
  def orquestrador(texto, arquivo, history, json_config):
132
- # 1. Input Check (IDÊNTICO v27)
133
  anexo = ler_anexo(arquivo)
134
  full_input = f"{texto}\n{anexo}".strip()
135
 
@@ -137,47 +161,39 @@ def orquestrador(texto, arquivo, history, json_config):
137
  yield history, {}, "Sem input."
138
  return
139
 
140
- # 2. Setup (IDÊNTICO v27)
141
  history = history + [[texto + (" πŸ“Ž" if arquivo else ""), None]]
142
  timeline = [{"role": "user", "content": full_input}]
143
- logs = f"πŸš€ AUTO-PLAN v30: {datetime.now().strftime('%H:%M:%S')}\n"
144
 
145
- history[-1][1] = "🎯 Criando plano dinÒmico..."
146
  yield history, timeline, logs
147
 
148
- # 3. 1Βͺ AÇÃO: CRIA PLANO
149
  plano, log_plano = criar_plano_auto(full_input, history)
150
- if not plano:
151
- history[-1][1] = log_plano
152
- yield history, timeline, logs
153
- return
154
-
155
- logs += f"{log_plano}\n"
156
- timeline.append({"role": "system", "plano_auto": plano})
157
 
158
- history[-1][1] = f"βœ… Plano criado: {len(plano)} agentes"
159
  yield history, timeline, logs
160
 
161
- # 4. ITERA PELO PLANO (IDÊNTICO v27)
162
- final_response = ""
163
  for i, cfg in enumerate(plano):
164
- history[-1][1] = f"βš™οΈ [{i+1}/{len(plano)}] {cfg['nome']}..."
165
  yield history, timeline, logs
166
 
167
  res, log_add, raw = executar_no(timeline, cfg)
168
  timeline.append(res)
169
- logs += log_add + "\n"
170
 
171
- if cfg['tipo_saida'] == 'texto':
172
- final_response = res['content']
173
- history[-1][1] = final_response[:800] + "..." if len(final_response) > 800 else final_response
174
  yield history, timeline, logs
175
 
176
- logs += "βœ… AUTO-PLAN concluΓ­do."
177
  salvar_history(history)
 
178
  yield history, timeline, logs
179
 
180
- # ==================== 6. UI LIMPA v27 (SEM 'icon') ====================
181
  def ui_clean():
182
  css = """
183
  footer {display: none !important;}
@@ -185,77 +201,41 @@ def ui_clean():
185
  """
186
 
187
  config_init = carregar_protocolo()
188
- history_init = carregar_history()
189
 
190
- with gr.Blocks(title="PIPELINE v30 - AUTO-PLAN", css=css, theme=gr.themes.Soft()) as app:
191
  with gr.Tabs():
192
- # === ABA 1: CHAT (EXATA v27) ===
193
  with gr.Tab("πŸ’¬ Pipeline"):
194
- chatbot = gr.Chatbot(
195
- value=history_init,
196
- label="",
197
- show_label=False,
198
- height=600,
199
- show_copy_button=True,
200
- render_markdown=True
201
- )
202
 
203
  with gr.Row():
204
  with gr.Column(scale=10):
205
- txt_in = gr.Textbox(
206
- show_label=False,
207
- placeholder="Digite input... Modelo criarΓ‘ plano automaticamente!",
208
- lines=1,
209
- max_lines=5,
210
- container=False
211
- )
212
  with gr.Column(scale=1, min_width=50):
213
- file_in = gr.UploadButton(
214
- "πŸ“Ž",
215
- file_types=[".txt", ".md", ".csv", ".json", ".py", ".yaml"],
216
- size="sm"
217
- )
218
- with gr.Column(scale=1, min_width=80):
219
  btn_send = gr.Button("Enviar", variant="primary", size="sm")
220
 
221
- file_status = gr.Markdown("", visible=True)
222
- file_in.upload(lambda x: f"πŸ“Ž Anexo: {os.path.basename(x.name)}", file_in, file_status)
223
 
224
- # === ABA 2: DEPURAÇÃO (EXATA v27) ===
225
  with gr.Tab("πŸ•΅οΈ DepuraΓ§Γ£o"):
226
  with gr.Row():
227
- out_dna = gr.JSON(label="DNA (Timeline)")
228
- out_logs = gr.Textbox(label="Logs do Sistema", lines=20)
229
 
230
- # === ABA 3: CONFIG (EXATA v27) ===
231
  with gr.Tab("βš™οΈ Config"):
232
- with gr.Row():
233
- btn_save = gr.Button("Salvar Config")
234
- lbl_save = gr.Label(show_label=False)
235
-
236
- code_json = gr.Code(
237
- value=config_init,
238
- language="json",
239
- label="protocolo.json (placeholder - usa auto-plan)"
240
- )
241
- btn_save.click(salvar_protocolo, code_json, lbl_save)
242
 
243
- # === TRIGGERS (EXATOS v27) ===
244
  triggers = [btn_send.click, txt_in.submit]
245
  for trig in triggers:
246
- trig(
247
- orquestrador,
248
- inputs=[txt_in, file_in, chatbot, code_json],
249
- outputs=[chatbot, out_dna, out_logs]
250
- ).then(
251
- lambda: (None, ""),
252
- outputs=[txt_in, file_status]
253
  )
254
 
255
  return app
256
 
257
  if __name__ == "__main__":
258
- print("πŸš€ PIPELINE v30 - AUTO-PLAN (HF Spaces compatΓ­vel)")
259
- print("πŸ’‘ Sem 'icon' | History persistente | Mesmo UI v27")
260
  app = ui_clean()
261
- app.launch(server_name="0.0.0.0", server_port=7860, share=False)
 
1
+
2
  # ╔════════════════════════════════════════════════════════════════════════════╗
3
+ # β•‘ PIPELINE v31: AUTO-PLAN ROBUSTO | DEBUG + FALLBACK | HF SPACES OK β•‘
4
+ # β•‘ 1ΒΊ: PLANEJADOR com ERROR HANDLING β†’ ITERA PLANO β†’ SAÍDA β•‘
5
  # β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
6
 
7
  import os
 
22
  model_flash = model_pro = None
23
 
24
  ARQUIVO_CONFIG = "protocolo.json"
25
+ ARQUIVO_HISTORY = "history_v31.json"
26
 
27
+ # ==================== 2. UTILIDADES (ROBUSTAS) ====================
28
  def carregar_protocolo():
29
  try:
30
  with open(ARQUIVO_CONFIG, "r", encoding="utf-8") as f:
 
63
  return f"\n\n[ANEXO: {os.path.basename(arquivo.name)}]\n{f.read()}\n[FIM ANEXO]\n"
64
  except: return ""
65
 
66
+ # ==================== 3. PLANEJADOR AUTO ROBUSTO (v31) ====================
67
  def criar_plano_auto(full_input, history_contexto):
68
+ """PLANEJADOR com FALLBACK + DEBUG DETALHADO"""
69
  if not model_pro:
70
  return None, "❌ Sem API_KEY"
71
 
72
+ # PLANO DE FALLBACK (se erro)
73
+ plano_fallback = [
74
+ {"nome": "Analisador", "missao": "Analise o input principal e identifique elementos chave", "modelo": "flash", "tipo_saida": "json"},
75
+ {"nome": "RespostaFinal", "missao": "Baseado na anΓ‘lise anterior, produza resposta completa e clara", "modelo": "pro", "tipo_saida": "texto"}
76
+ ]
77
+
78
+ history_resumo = ""
79
+ if history_contexto:
80
+ history_resumo = "\n".join([f"πŸ‘€: {h[0][:100]}..." for h in history_contexto[-2:]])[:200]
81
 
82
+ # PROMPT SIMPLIFICADO + ROBUSTO
83
+ prompt_planejador = f"""INPUT: {full_input[:500]}
84
 
85
+ CRIE PLANO JSON de 2-4 agentes:
86
 
87
+ {{"nome": "Nome", "missao": "MissΓ£o curta", "modelo": "flash", "tipo_saida": "texto"}}
88
 
89
+ APENAS JSON VÁLIDO:
90
+ ```
91
  [
92
+ {{"nome": "Analisador", "missao": "Analise input", "modelo": "flash", "tipo_saida": "json"}},
93
+ {{"nome": "Final", "missao": "Resposta final", "modelo": "pro", "tipo_saida": "texto"}}
94
  ]
95
+ ```"""
 
96
 
97
  try:
98
+ resp = model_pro.generate_content(prompt_planejador, temperature=0.1)
99
+ plano_raw = resp.text.strip()
100
+
101
+ # DEBUG: Mostra raw response
102
+ print(f"DEBUG PLANO RAW: {plano_raw[:300]}...")
103
+
104
+ # Limpa markdown agressivamente
105
+ plano_raw = re.sub(r'``````|```
106
+ plano_raw = re.sub(r'^.*?\[', '[', plano_raw)
107
+ plano_raw = re.sub(r'\].*?$', ']', plano_raw)
108
+
109
+ print(f"DEBUG PLANO CLEAN: {plano_raw[:300]}...")
110
+
111
  plano = json.loads(plano_raw)
112
 
113
  if isinstance(plano, list) and len(plano) >= 2:
114
+ print(f"βœ… PLANO VÁLIDO: {len(plano)} agentes")
115
  return plano, f"βœ… Plano: {len(plano)} agentes"
116
+
117
+ print(f"❌ PLANO INVÁLIDO: {type(plano)}")
118
+ return plano_fallback, "⚠️ Plano corrigido (fallback)"
119
+
120
+ except json.JSONDecodeError as e:
121
+ print(f"❌ JSON ERROR: {str(e)[:100]}")
122
+ print(f"RAW FALHOU: {plano_raw[:200]}")
123
+ return plano_fallback, f"⚠️ Fallback ativo (JSON: {str(e)[:50]})"
124
+ except Exception as e:
125
+ print(f"❌ GERAL ERROR: {str(e)}")
126
+ return plano_fallback, f"⚠️ Fallback (erro: {str(e)[:30]})"
127
 
128
+ # ==================== 4. ENGINE EXECUÇÃO (ROBUSTO) ====================
129
  def executar_no(timeline, config):
130
  if not (model_flash or model_pro):
131
  return {"role": "system", "error": "Sem API"}, "(ERRO: API)", "Sem key"
132
 
133
  modelo = model_pro if config.get("modelo") == "pro" else model_flash
134
+ contexto = json.dumps(timeline[-8:], ensure_ascii=False, indent=2)
135
 
136
+ prompt = f"""TIMELINE: {contexto}
 
 
137
  AGENTE: {config['nome']}
138
  MISSΓƒO: {config['missao']}"""
139
 
 
141
  try:
142
  inicio = time.time()
143
  resp = modelo.generate_content(prompt)
144
+ out = resp.text.strip()
145
 
146
  tempo = time.time() - inicio
147
+ content = json.loads(re.sub(r'```json|```
148
 
149
+ log += f" βœ“ {tempo:.1f}s"
150
  return {"role": "assistant", "agent": config['nome'], "content": content}, log, out
151
+ except:
152
+ log += " βœ— erro"
153
+ return {"role": "system", "error": "Falha execuΓ§Γ£o"}, log, "Erro agente"
154
 
155
+ # ==================== 5. ORQUESTRADOR v31 ====================
156
  def orquestrador(texto, arquivo, history, json_config):
 
157
  anexo = ler_anexo(arquivo)
158
  full_input = f"{texto}\n{anexo}".strip()
159
 
 
161
  yield history, {}, "Sem input."
162
  return
163
 
 
164
  history = history + [[texto + (" πŸ“Ž" if arquivo else ""), None]]
165
  timeline = [{"role": "user", "content": full_input}]
166
+ logs = f"πŸš€ v31 DEBUG: {datetime.now().strftime('%H:%M:%S')}\n"
167
 
168
+ history[-1] = "πŸ” Criando plano..."[1]
169
  yield history, timeline, logs
170
 
171
+ # PLANEJADOR ROBUSTO
172
  plano, log_plano = criar_plano_auto(full_input, history)
173
+ logs += f"PLANO: {log_plano}\n"
174
+ timeline.append({"role": "system", "plano": plano})
 
 
 
 
 
175
 
176
+ history[-1] = f"βœ… {log_plano}"[1]
177
  yield history, timeline, logs
178
 
179
+ # EXECUTA PLANO
 
180
  for i, cfg in enumerate(plano):
181
+ history[-1] = f"[{i+1}/{len(plano)}] {cfg['nome']}..."[1]
182
  yield history, timeline, logs
183
 
184
  res, log_add, raw = executar_no(timeline, cfg)
185
  timeline.append(res)
186
+ logs += f" {log_add}\n"
187
 
188
+ if cfg.get('tipo_saida') == 'texto' and 'content' in res:
189
+ history[-1] = str(res['content'])[:900][1]
 
190
  yield history, timeline, logs
191
 
 
192
  salvar_history(history)
193
+ logs += "βœ… v31 OK"
194
  yield history, timeline, logs
195
 
196
+ # ==================== 6. UI v27 EXATA (HF SPACES OK) ====================
197
  def ui_clean():
198
  css = """
199
  footer {display: none !important;}
 
201
  """
202
 
203
  config_init = carregar_protocolo()
 
204
 
205
+ with gr.Blocks(title="PIPELINE v31 - AUTO-PLAN ROBUSTO", css=css, theme=gr.themes.Soft()) as app:
206
  with gr.Tabs():
 
207
  with gr.Tab("πŸ’¬ Pipeline"):
208
+ chatbot = gr.Chatbot(height=600, show_copy_button=True, render_markdown=True)
 
 
 
 
 
 
 
209
 
210
  with gr.Row():
211
  with gr.Column(scale=10):
212
+ txt_in = gr.Textbox(placeholder="Teste agora... sem erros!", lines=1, container=False)
 
 
 
 
 
 
213
  with gr.Column(scale=1, min_width=50):
214
+ file_in = gr.UploadButton("πŸ“Ž", file_types=[".txt"], size="sm")
215
+ with gr.Column(scale=1):
 
 
 
 
216
  btn_send = gr.Button("Enviar", variant="primary", size="sm")
217
 
218
+ file_status = gr.Markdown("")
219
+ file_in.upload(lambda x: f"πŸ“Ž {os.path.basename(x.name)}", file_in, file_status)
220
 
 
221
  with gr.Tab("πŸ•΅οΈ DepuraΓ§Γ£o"):
222
  with gr.Row():
223
+ out_dna = gr.JSON(label="Timeline")
224
+ out_logs = gr.Textbox(label="Logs DEBUG", lines=20)
225
 
 
226
  with gr.Tab("βš™οΈ Config"):
227
+ code_json = gr.Code(value=config_init, language="json", label="NΓ£o usado (auto-plan)")
228
+ gr.Button("Salvar", variant="secondary")
 
 
 
 
 
 
 
 
229
 
 
230
  triggers = [btn_send.click, txt_in.submit]
231
  for trig in triggers:
232
+ trig(orquestrador, [txt_in, file_in, chatbot, code_json], [chatbot, out_dna, out_logs]).then(
233
+ lambda: (None, ""), [txt_in, file_status]
 
 
 
 
 
234
  )
235
 
236
  return app
237
 
238
  if __name__ == "__main__":
239
+ print("πŸš€ v31 ROBUSTO - SEM ERROS PLANO!")
 
240
  app = ui_clean()
241
+ app.launch(server_name="0.0.0.0", server_port=7860)